我对Choco和CP完全不熟悉,但我正在制作一个小模型来解决Steiner树问题,而Choco一直强迫第一个节点无论图形是什么(并且它不正确,我检查过)。
我有一个IntVar的数组es
,如果边缘在解决方案中,则== 1,否则为== 0。设置顶点的数组vs
也是如此。
我使用数组activeEdgeW
能够有一个标量约束,其中coeffs是可变的。
然后我只有通道约束,树约束和sum == w约束。并尽量减少w。相当简单,但出于某种原因,vs[0] == true
始终为任何图表。
我的模型很简单,我真的不知道它来自哪里:
s = new Solver("Solver");
vs = VF.boolArray("vs", nbV, s);
es = VF.boolArray("es", nbE, s);
w = VF.integer("w", 0, maxW, s);
IntVar[] activeEdgeW = new IntVar[nbE];
for(int i = 0; i < nbE; i++) {
activeEdgeW[i] = VF.enumerated("activeEdgeW["+i+"]", new int[]{0,ws[i]}, s); //Weight is either 0 or ws[i]
ICF.arithm(activeEdgeW[i], "=", ws[i]).reifyWith(es[i]); //weight of edge is ws[i] if edge is in, 0 otherwise
}
UndirectedGraph UB = new UndirectedGraph(s, nbV, SetType.BITSET, false);
UndirectedGraph LB = new UndirectedGraph(s, nbV, SetType.BITSET, false);
//Building upper bound graph: has all nodes and edges
for (int i = 0; i < nbV; i++){
UB.addNode(i);
}
for (int i = 0; i < nbE; i++){
UB.addEdge(endnodes[i][0], endnodes[i][1]);
}
//Building lower bound graph. Must contain Steiner nodes
for (int i = 0; i < nbT; i++) {
LB.addNode(terminals[i]);
}
g = GraphVarFactory.undirected_graph_var("Solution", LB, UB, s);
s.post(GCF.tree(g));
s.post(ICF.sum(activeEdgeW, w));
s.post(GCF.nodes_channeling(g, vs));
for (int i = 0; i < nbE; i++) {
s.post(GCF.edge_channeling(g, es[i], endnodes[i][0], endnodes[i][1]));
}
s.plugMonitor((IMonitorSolution) () -> output());
s.findOptimalSolution(ResolutionPolicy.MINIMIZE, w);
这是我的模型,程序的其余部分只是图表数据。
有没有人知道这是怎么回事?我尝试在UB
中以不同的顺序放置节点,但始终是第一个节点坚持进入。
我试图删除通道约束,它告诉我节点并不总是正确,但是到达它的边必须是,所以它变为真。然而,正如你可以很容易看到的那样,我对数组es
没有任何约束,这会限制边缘是真的。
感谢您的帮助!
答案 0 :(得分:0)
&#34;我对Choco和CP&#34;
全新
在过去,我已经被那些已经或者没有从零开始计数的工具所抓住,我假设相反的情况(计数从一开始)。您描述的行为属于此类错误,因此您可以验证所有这些都是从零基数组开始的。
答案 1 :(得分:0)
我使用的Choco3版本有一个错误。它在3.3.0中得到了解决。如果您遇到同样的问题,请使用那个:)