constraints - Minizinc 对数组和布尔值的基本理解
问题描述
看完教程后,我以为我掌握了概念,我开始创建自己的模型,但很快就遇到了问题。最好尽快陷入困境以意识到你实际上知道的很少,imo。
在这个例子中,我只想得到一个输出,其中班级由需要他们的学生组成,即true
,由我的数组表示(不是每个学生都能每天参加)。
模型的编写方式可能存在各种不良情况......
不用说,我得到了错误WARNING: model inconsistency detected
enum Students = { Mark, Bart, Mary, Anne, Sue };
enum Classes = { Mon, Tue, Wed};
array[Students, Classes] of bool: pref =
[| true, true, false,
| false, true, true,
| true, false, true,
| true, false, false,
| false, false, true |];
constraint forall (i in Students, j in Classes)(pref[i,j]=true);
solve satisfy;
output [ " \(pref[Students,Classes]);\n" ]
奖金会限制它,所以每个Student
只出现一次......
完美的结果将类似于满足学生偏好并且他们在 1 个班级的所有组合的列表。
[Mark, Anne | Bart | Mary, Sue]
感谢您在我的道路上帮助我!
解决方案
您可能不理解的重要部分是 MiniZinc 是一种声明性语言。您不告诉它如何解决问题,而只是指定问题并让语言完成其余的工作。
MiniZinc 模型是根据以下内容指定的
- 变量:需要做出的决定/你想知道的事情
- 参数:你已经知道的东西
- 约束:在任何或所有变量和参数之间强制执行的规则。
在您的模型中,您没有指定任何变量,仅指定参数和约束。据说它是不一致的,因为你给它一个pref
包含true
and的数组false
,但是你的约束强制数组中的每个元素都必须是true
。
可能您打算制作pref
一组变量,并且意味着您的约束应该强制每个学生都有一个偏好:
enum Students = { Mark, Bart, Mary, Anne, Sue };
enum Classes = { Mon, Tue, Wed};
array[Students, Classes] of var bool: pref;
constraint forall (i in Students)(
count(j in Classes) (pref[i, j]) = 1
);
solve satisfy;
output [ "pref = ", show2d(pref), ";" ];
如果您只希望每个学生至少有一个偏好,您可以使用exists
:
enum Students = { Mark, Bart, Mary, Anne, Sue };
enum Classes = { Mon, Tue, Wed};
array[Students, Classes] of var bool: pref;
constraint forall (i in Students)(
exists(j in Classes) (pref[i, j])
);
solve satisfy;
output [ "pref = ", show2d(pref), ";" ];
这会起作用,但是如果您知道,就像第一个解决方案中的情况一样,学生只做出一个偏好,那么最好将其作为变量类型的一部分强制执行:
enum Students = { Mark, Bart, Mary, Anne, Sue };
enum Classes = { Mon, Tue, Wed};
array[Students] of var Classes: pref;
solve satisfy;
output [ "pref = ", show(pref), ";" ];
那么就不需要任何约束来确保学生有一个确切的偏好。