【问题标题】:Minizinc constraints from another array来自另一个数组的 Minizinc 约束
【发布时间】:2017-03-06 12:26:06
【问题描述】:

我正在尝试使用 minizinc 进行我的第一个约束编程。我正在尝试创建一个时间表,其中包含n 插槽和n 人员,并为每个插槽分配了不同的人员。我使用array of var int 来模拟日程安排,使用alldifferent() 来确保每个位置都有不同的人。 大小为nnames 的单独array 包含它们的名称,如下所示:

% Pseudo enum
set of int: NameIndex = 1..2;
int: Forename = 1;
int: Surname = 2;

int: n = 4; % Number of slots and people
set of int: slots = 1..n;

array[slots, NameIndex] of string: names = [| "John", "Doe" 
                                            | "Ann", "Jones" 
                                            | "Fred", "Doe"
                                            | "Barry", "Doe" |];                  
% The schedule
array[slots] of var slots: schedule;

% Every person is scheduled:
include "alldifferent.mzn";
constraint alldifferent(schedule);

% How to constrain by a value from names, say alphabetic order by forename.
% Want to compare each value in schedule to the next one.
%constraint forall (i in 1..n-1) (names[schedule[i],Forename] < names[schedule[i+1],Forename]);

solve satisfy;

output [show(i) ++ ": " ++ show(names[schedule[i], Forename]) ++ " " ++ show(names[schedule[i], Surname])  ++ "\n"
    | i in slots]
% should be:
%  | i in schedule]

如何通过名称中的值来限制 schdule?在我上面的(损坏的)示例中,当 forall 约束未注释时,我得到(使用 Minizinc IDE):

in call 'forall'
in array comprehension expression
  with i = 1
in binary '<' operator expression
in array access
cannot find matching declaration

我一直跟踪错误,直到不明白找不到哪个声明。当我从 schdule 值索引到数组时,输出块 show()s 的值来自名称。

我错过了什么?有没有更好的方法来模拟名称?我希望将名称扩展到人的其他“属性”并创建额外的约束。我确信模型和我的 forall 约束都非常幼稚!

【问题讨论】:

    标签: minizinc


    【解决方案1】:

    问题在于 MiniZinc 对字符串的支持不多;并针对您的示例:不支持比较字符串(“

    也就是说,有一些计划支持 var 字符串(即使用字符串作为决策变量),但我不知道它何时发布的确切状态。

    这是一个非常简单的修复方法,但需要一些预处理:

    1) 创建一个包含每个名称的(排序)索引的新数组:

      array[slots] of int: names_ix = [4, % John Doe
                                       1, % Ann Jones
                                       3, % Fred Doe
                                       2, % Barry Doe
                                       ];                  
    

    2) 更改排序约束以使用这个新数组

    constraint 
       forall (i in 1..n-1) (
          names_ix[schedule[i]] <= names_ix[schedule[i+1]]
       );
    

    [有一个更复杂的变体,要求您将名称中的每个字符转换为整数(在“var int”的矩阵中),然后要求单词 - 作为整数的集合 - 是有序的。请注意,这往往很混乱,例如处理不同长度的字符串等]

    【讨论】:

    • 这就解释了!预处理不是问题。我认为支持字符串的 CP 求解器很少(来自search results like this)?
    • 论文“MiniZinc with Strings”描述了传统CP求解器中var字符串的第一个实现(Gecode中有相关的实验实现,但尚未正式发布)。有一些专用的字符串求解器,但它们往往只支持字符串,而不支持具有传统全局约束的 var int:s。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多