为集合选择合适的集合

  • 本文关键字:集合 选择 minizinc
  • 更新时间 :
  • 英文 :


我需要以下情况的帮助。 假设我有以下代码:

enum x= {p,k,m};
enum y= {t1,t2,t3,t4};
array[y] of set of int:against=[{1,3,6},{3,3,6},{6,1,1},{6,3,6}];
array[x] of set of int:attack=[{3,3,6},{6,2,2},{3,1,3}];
array[x] of set of y: NodesD=[{t2,t3},{t2,t3,t4},{t1,t4}];
array[x]of var y: Select; 
constraint forall(p in x)(Select[p] in NodesD[p]);

因此,对于 x 的每个枚举,我应该只在 Y 的枚举上选择。 然后我想通过以下方式选择适合每组攻击的一种:

让我们取 x {p} 的第一个枚举,它有两个可能的 y{t2,t3} 选择,所以我想这样做:t2={1,1,6},t3={6,3,3} 所以我想从 y against [] 中的每个值中减去 x attack[] {3,3,6} 中的每个值,并对结果求和:

{1,1,6}-
{3,3,6}
-----------
{-2,-2,0} then sum them which is equal to -4

然后对 T2 执行相同的操作

{6,3,3}-
{3,3,6}
------------
{3,0,-3} which is equal to 0 

在这种情况下,等于 0 的 t3 比 t2=-4 更好。 我想对每个枚举 x 做同样的事情并最大化功率。 我尝试通过以下方式执行此操作,但它不起作用

var int: power = sum(p in x)(card(against[Select[p]])-(card(attack[p])*Select[p]) );
solve maximize power ;

请提供任何帮助或提示:)

如果要逐个元素进行比较,矩阵比集合数组更适合于此,因为这样可以确保两个矩阵具有相同的宽度,并且语法也不那么麻烦,因此,与其使用从 1 到集合基数的索引求和,不如使用不同的集合对矩阵的列求和。

您可以计算集合的元素明智差之和

sum(i in 1..min(card(set_A),card(set_B)))(set_A[i] - set_B[i]);

使用min确保仅循环访问最小的集合,并且不访问不存在的元素。

但是这样写在我看来更干净,基本上,更改|的集合{}以分隔矩阵的行attackagainst,并添加一个新变量来索引矩阵的列,我在这个例子中称之为FRONTS,所以你选择一个X并比较不同战场的力量差异。

enum X = {p,k,m};
enum y = {t1,t2,t3,t4};
set of int : FRONTS = 1..3;
array[y,FRONTS] of int : against=[|1,3,6|3,3,6|6,1,1|6,3,6|];
array[X,FRONTS] of int : attack=[|3,3,6|6,2,2|3,1,3|];
array[X] of set of y : nodesD=[{t2,t3},{t2,t3,t4},{t1,t4}];
array[X] of var y : select; 
var int: power;
constraint forall(p in X)(select[p] in nodesD[p]);
constraint power = sum(p in X)( sum(i in FRONTS)( against[ select[p], i] - attack[ p, i ] ) );
solve maximize power;
output [show(select) ++ " = " ++ show(power)];