【问题标题】:How to iterate through 2d array in constraint in minizinc correctly?如何在 minizinc 中正确迭代约束中的二维数组?
【发布时间】:2021-10-02 14:29:20
【问题描述】:

我想解决图表着色的问题。当一个图形应该用最少数量的颜色着色时,问题就是没有相邻顶点被着色为相同的颜色。 这是我的带有玩具图的代码。

int: N_Vertices=4;
int: N_Edges=3;
array[1..N_Edges, 1..2] of int: Adjacency;
Adjacency = [| 0, 1
             | 1, 2
             | 1, 3|];
array [1..N_Vertices] of var int: coloring;

constraint forall(e in 1..N_Edges)(coloring[Adjacency[e, 1]] != coloring[Adjacency[e, 2]]);
constraint forall(c in coloring)(c >= 0);

solve minimize (max(coloring));

但它给了

 WARNING: undefined result becomes false in Boolean context
  (array access out of bounds)
Playground:11:
  in call 'forall'
  in array comprehension expression
    with e = 1
  in binary '!=' operator expression
  in array access

  WARNING: model inconsistency detected
Playground:11:
  in call 'forall'
  in array comprehension expression
    with e = 1
  in binary '!=' operator expression
  in array access
=====UNSATISFIABLE=====

我想我在第一个约束中对 Adjacency 迭代做错了。应该怎么做呢?

【问题讨论】:

    标签: arrays constraint-programming minizinc


    【解决方案1】:

    问题在于Adjacency:这些值以 0 为基数,但 coloring 以 1 为基数 (array[1..N_Vertices])。 MiniZinc 默认使用 base 1 索引。

    最简单的方法是将 Adjacency 中的索引改为以 1 为底:

    Adjacency = [| 1, 2
                 | 2, 3
                 | 2, 4|];
    

    那么解决办法是:

    coloring = array1d(1..4, [1, 0, 1, 1]);
    ----------
    ==========
    

    如果您想在Adjacency 中保留基数为0 的索引,则必须通过将1..N_Edges 替换为0..N_Edges-1 来进行一些其他调整:

    int: N_Vertices=4;
    int: N_Edges=3;
    array[0..N_Edges-1, 1..2] of int: Adjacency;        
    
    Adjacency = array2d(0..N_Edges-1,1..2,[| 0, 1
                 | 1, 2
                 | 1, 3|]);
    
    array[0..N_Vertices-1] of var int: coloring;
    constraint forall(e in 0..N_Edges-1)(coloring[Adjacency[e, 1]] != coloring[Adjacency[e, 2]]);
    constraint forall(c in coloring)(c >= 0);
    

    答案:

    coloring = array1d(1..4, [1, 0, 1, 1]);
    

    另外,我建议您给coloring 一个适当的域而不是var int,例如:

    array[0..N_Vertices-1] of 0..4: coloring; % recommended
    % ....
    % Then this is not needed:
    % constraint forall(c in coloring)(c >= 0);
    

    【讨论】:

    • 为什么 MiniZinc 默认有base 0 索引?是因为给 0 赋予特殊语义(例如“没有这样的值”或“缺少段”)通常是实用的吗?这是有道理的,因为没有NULL。甚至全局约束也以这种方式使用 0,被命名为“foo_except_0”。
    • @DavidTonhofer MiniZinc 默认具有基本的1 索引(但我猜你的意思是)。您可能对foo_except_0 有意见,但这更多的是关于数组中的值,而不是索引。我宁愿认为base 1索引默认是来自其他系统(例如Comet,OPL,AMPL?,Prolog的nth / 3?)的历史原因,倾向于使用索引base 1。(我个人认为在base中工作更自然1 建模问题时的索引,但这是另一回事。)
    • 谢谢,这行得通!看来你有这方面的经验,你能再回答几个问题吗?如何指定int_search 的顺序?例如,在图着色问题中按度数节点减少的顺序进行?
    • @Nourless 这说来话长。这可能会有所帮助:minizinc.org/doc-2.5.5/en/mzn_search.html?highlight=annotation
    • @DavidTonhofer Julia 和基于 1 的索引:是的,这在我的书中对 Julia 来说是一个加分项。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 2018-10-17
    相关资源
    最近更新 更多