【问题标题】:How to improve the performance of my graph coloring model in MiniZinc?如何在 MiniZinc 中提高我的图形着色模型的性能?
【发布时间】:2020-06-21 18:37:45
【问题描述】:

我已经创建了一个模型来解决 MiniZinc 中的图形着色问题:

include "globals.mzn";

int: n_nodes;               % Number of nodes
int: n_edges;               % Number of edges
int: domain_ub;             % Number of colors
array[int] of int: edges;   % All edges of graph as a 1D array
array[1..n_edges, 1..2] of int: edges2d = array2d(1..n_edges, 1..2, edges);

array[1..n_nodes] of var 1..domain_ub: colors;

constraint forall (i in 1..n_edges) (colors[edges2d[i,1]] != colors[edges2d[i,2]]);

solve :: int_search(colors, dom_w_deg, indomain_random)
    satisfy;

为了解决大问题(大约 400-500 个节点),我从颜色数量的上限开始,并解决连续的满意度问题,将数字减一直到它变得无法满足或超时。这种方法给了我不错的结果。

为了改进我的结果,我在上面的模型中添加了对称破坏约束:

constraint colors[1] = 1;
constraint forall (i in 2..n_nodes) ( colors[i] in 1..max(colors[1..i-1])+1 );

然而,这降低了我在速度和质量方面的结果。

为什么我的模型在添加额外约束后表现不佳?我应该如何添加对称破坏约束?

【问题讨论】:

  • 您可以测试不同的搜索策略,哪种方法效果更好(indomain_random 在对称性破坏方面可能不太好)。另外,颜色的上限是多少(domain_ub)?如果是平面图,4色就够了。
  • @hakank 这不是平面图。我用不同的搜索策略进行了测试,尽管input_orderindomain_min 的结果稍好一些,但仍然无法与我没有添加额外约束时相比。
  • @hakank 我正在使用minizinc Python 包来运行模型。对于domain_ub,我从图形的最大度数开始运行一个循环,然后将其递减,直到达到不可满足或超时。
  • 好的,那么如果您可以添加一个(小)数据集来显示此行为,那将会有所帮助。
  • @hakank 不幸的是,我在大型数据集上遇到了这个问题。我正在尝试在一个小数据集中重新创建问题,但到目前为止没有运气。

标签: optimization constraint-programming minizinc


【解决方案1】:

对于值完全对称的情况下的对称性破坏,我建议使用seq_precede_chain 约束,它破坏了这种对称性。正如@hakank 所评论的,在与对称破坏一起使用时使用indomain_random 可能不是一个好主意,indomain_min 是一个更安全的选择。

对于一般的图形着色,运行团查找算法可能有助于提高性能,并在找到的每个团上发布all_different 约束。在为每个实例生成 minizinc 程序时必须这样做。如需比较,请参阅Gecode graph coloring example which uses pre-computed cliques

【讨论】:

  • 我第一次尝试对称约束时使用了seq_precede_chain(colors)。然而,这并没有太大帮助。根据我的观察,获得解决方案的最快方法是仅添加主要约束并指定搜索策略。我还将研究派系查找算法。谢谢你的例子!
  • 使用对称破坏,对称破坏约束可能无法与所使用的搜索策略一起很好地工作,但始终值得尝试。
  • 我现在意识到我正在寻找的是一种在搜索过程中动态添加对称约束的方法。例如,如果搜索使用first-fail 策略,那么当求解器选择要查看的第二个变量时,它应该被动态限制为只有两个值,如this video 中所述。有没有办法在 MiniZinc 中做到这一点?
【解决方案2】:

我知道这是一个老问题,但我正在解决同样的问题,我想写下我发现的关于这个主题的内容,也许它对将来的某人有用。

要改进模型,解决方案是像您一样使用对称破坏约束,但在 Minizinc 中有一个名为 value_precede 的全局约束,可以在这种情况下使用。

% A new color J is only allowed to appear after colors 0..J-1 have been seen before (in any order)
constraint forall(j in 1..n-1)(value_precede(j, j+1, map));

更改搜索启发式结果并没有太大改善,我尝试了不同的配置,使用dom_w_degindomain_min 获得了最佳结果(与我的数据文件相比)。

另一种改进结果的方法是接受任何小于域中颜色数量的足够好的解决方案。 但这种模型并不总是导致获得最优结果。

include "globals.mzn";

int: n; % Number of nodes
int: e; % Number of edges
int: maxcolors = 17; % Domain of colors

array[1..e,1..2] of int: E; % 2d array, rows = edges, 2 cols = nodes per edge
array[0..n-1] of var 0..maxccolors: c;   % Color of node n

constraint forall(i in 1..e)(c[E[i,1]] != c[E[i,2]] ); % Two linked nodes have diff color
constraint c[0] == 0; % Break Symmetry, force fist color == 0

% Big symmetry breaker. A new color J is only allowed to appear after colors
% 0..J-1 have been seen before (in any order)
constraint forall(i in 0..n-2)( value_precede(i,i+1, c)  );

% Ideally solve would minimize(max(c)), but that's too slow, so we accept any good
% enough solution that's less equal our heuristic "maxcolors"
constraint max(c) <= maxcolors;
solve :: int_search(c, dom_w_deg, indomain_min, complete) satisfy;

output [ show(max(c)+1), "\n", show(c)]

可以在这里找到清晰完整的解释: https://maxpowerwastaken.gitlab.io/model-idiot/posts/graph_coloring_and_minizinc/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    相关资源
    最近更新 更多