根据约束最大化

时间:2020-09-04 13:18:18

标签: minizinc

3个数组f1,f2和f3具有子元素(f1a,f1b); (f2a,f2b,f2c); (分别是f3a,f3b,f3c,f3d)。它们都是bool变量

在具有2列的列表中,我将这些子元素组合在一起。第一列为ID,第二列为子元素的组合,如下所示

  • 第1行:2345 | f1a,f2b
  • 第2行:2345 | f1a,f2a,f3c
  • 第3行:2346 | f2c,f3a
  • 第4行:2347 | f1b,f2c
  • .... ....

我需要选择每个数组的一个元素并形成一个选定的数组 如果row的所有元素都在所选数组中表示,则为该Row设置1,否则为0

因此,如果选择的数组是[f1a,f2a,f3c],则(使用上面的列表示例)

  • 行1为0(因为f2b不在所选数组中)
  • 第2行为1,因为该行的所有元素都在所选列表中
  • row3为0,因为f2c且f3a不在所选数组中
  • 第4行为0,因为所选数组中不存在f2c

我需要选择选定的数组,以便最大化所有唯一ID的行数之和(0 + 1 + 0 + 0 ...) 例如,如果list如下所示,并且所选数组为[f1a,f2b,f3c],尽管两行都设置为1, 我只会从两行中取1,因为两行中的ID都相同

  • 第1行:2345 | f1a,f2b
  • 第2行:2345 | f1a,f2b,f3c

感谢您的帮助,因为我是Minizinc的新手,并且正在努力用Minizinc制定约束条件

2 个答案:

答案 0 :(得分:1)

如果您的2.NO { after = &nbsp;<span class="nouveau">New</span> after.if.value.data = date:U after.if.isGreaterThan.data = field:f1 after.if.value.data = field:f2 after.if.isGreaterThan.data = field:f1 after.if.value.data = date:U after.if.isGreaterThan.data = field:f2 } 变量本身也位于数组中,那么

row

应将行的激活设置为目标。

如果数组中没有它们,您仍然可以手动将它们加在一起以形成目标:

solve maximize sum(row);

我不确定您是否也在询问行激活本身如何工作,但是如果仅在选择了行的所有元素时才激活行,那么可以使用简单的solve maximize row1 + row2 + row3 + row4; 约束来强制执行该行:

forall

答案 1 :(得分:0)

我终于可以使用此代码了。第1行和第2行具有相同的ID,类似地,第3行和第4行具有另一个公共ID

array[1..2] of var bool: f1 ;
array[1..2] of var bool: f1 ;
array[1..3] of var bool: f2 ;
array[1..4] of var bool: f3 ;
var bool: row1;
var bool: row2 ;
var bool: row3 ;
var bool: row4 ;
constraint sum(f1) == 1;  
constraint sum(f2) == 1;
constraint sum(f3) == 1;

constraint  row1 = forall ( [(f1[1])  ]  ) ;
constraint  row2 = forall ( [(f1[2]) , (f2[2]) , (f3[3]) ] );

constraint  row3 = forall ( [(f1[1]) , (f2[2]) , (f3[3]) ] ) ;
constraint  row4 = forall ( [(f1[2]) , (f2[1]) , (f3[4]) ] ) ;

var int: rown1 = bool2int(row1) ;
var int: rown2 = bool2int(row2) ;
var int: rown2a = max(rown1,rown2) ;

var int: rown3 = bool2int(row3) ;
var int: rown4 = bool2int(row4) ;
var int: rown4a = max( rown3,rown4) ;
var int: rown =  rown2a + rown4a ;

solve maximize rown;
相关问题