问题描述
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.NO {
after = <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行和第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]),(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;