首页 > 解决方案 > 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]

感谢您在我的道路上帮助我!

标签: constraintspreferenceminizinctimetable

解决方案


您可能不理解的重要部分是 MiniZinc 是一种声明性语言。您不告诉它如何解决问题,而只是指定问题并让语言完成其余的工作。

MiniZinc 模型是根据以下内容指定的

  • 变量:需要做出的决定/你想知道的事情
  • 参数:你已经知道的东西
  • 约束:在任何或所有变量和参数之间强制执行的规则。

在您的模型中,您没有指定任何变量,仅指定参数和约束。据说它是不一致的,因为你给它一个pref包含trueand的数组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), ";"  ];

那么就不需要任何约束来确保学生有一个确切的偏好。


推荐阅读