迷你锌模型因"MiniZinc: internal error: Error: solver backend cannot handle constraint: float_div"而失败



我只是一个初学者,想看看我是否可以在日常生活中使用微量锌。我试图制作的第一个模型在这里,数据文件在这里

基本上,我想做的就是这个。一方面,我有一组具有某些属性的虚拟机,如多个内核、RAM等。另一方面,我们从云提供商那里获得了一组虚拟机。这些也有类似的属性和价格。我想做的是匹配它们,然后在云中相应VM的大小和价格之间找到最佳平衡。

例如,如果我有一个有2个内核和8 GB RAM的虚拟机。为了匹配它,我可能会使用云提供商提供的几种虚拟机,这些虚拟机应该具有不少于2个核心和不少于8 GB的RAM/但对于这组虚拟机,我希望最大限度地降低总体成本,同时尝试最大限度地提高性能,这是以ACUs衡量的云提供商。

我想使用var float: targetFunc = (0.9 * totalPrice) / (0.1 * totalACU);作为目标函数,假设系数将帮助我根据性价比对模型进行微调。但是,也许我做错了。

为了简单起见,我只是复制并粘贴下面的代码。

enum existingVMs;
enum vmSizes;
enum vmDisks;
array[existingVMs] of int: vmCPU;
array[existingVMs] of int: vmRAM;
array[existingVMs] of int: vmDisk;
array[existingVMs] of int: vmCpuToRamRatio;

array[vmSizes] of int: vmSizeCPU;
array[vmSizes] of float: vmSizeRAM;
array[vmSizes] of int: vmSizePrice;
array[vmSizes] of int: vmSizeACU;
array[vmSizes] of int: vmSizeCpuToRamRatio;
array[vmDisks] of int: vmDiskSizes;
array[vmDisks] of float: vmDiskPrice;
array[existingVMs] of var vmSizes: selectedSize;
array[existingVMs] of var vmDisks: selectedDiskSize;

constraint forall(vm in existingVMs)(
vmSizeACU[selectedSize[vm]] > 50
);
constraint forall(vm in existingVMs)(
vmSizeRAM[selectedSize[vm]] >= vmRAM[vm]
);

constraint forall(vm in existingVMs)(
vmSizeCPU[selectedSize[vm]] >=  vmCPU[vm] * 0.8
);
var int: totalPrice = sum(vm in existingVMs)(vmSizePrice[selectedSize[vm]]);
var int: totalACU = sum(vm in existingVMs)( vmSizeACU[selectedSize[vm]] );
var float: targetFunc = (0.9 * totalPrice) / (0.1 * totalACU);
solve maximize targetFunc;
output [ "(totalPrice); (totalACU)n" ++ join("n", ["(vm), (vmCPU[vm]), (vmRAM[vm]), " ++ 
"(vmDisk[vm]), (selectedSize[vm]), (vmSizeCPU[selectedSize[vm]]), " ++ 
"(vmSizeRAM[selectedSize[vm]]), (vmDiskSizes[selectedDiskSize[vm]]), " ++ 
"(vmSizePrice[selectedSize[vm]]), (vmSizeACU[selectedSize[vm]])" | vm in  existingVMs]) ]

我将其运行为:

minizinc.exe  -i --solver coin-bc -s -a C:Worktoolsdemographs-n-minizinc-demovmCostsCalculation.mzn C:Worktoolsdemographs-n-minizinc-demovmData.dzn

并得到以下回应

82 POSTs [ 0,0,0,0,0,0,0,0,0,0, ], LINEQ [ 0,0,0,0,0,0,0,0,82, ], 82 / 82 vars, 82 cliques, 1 / 1 / 1 NSubIntv m/a/m, 252 / 252 / 252 SubIntvSize m/a/m, 82+0(0) clq eq_encoded  ... % Generated FlatZinc statistics:
%%%mzn-stat: paths=0
%%%mzn-stat: flatIntVars=21158
%%%mzn-stat: flatFloatVars=20831
%%%mzn-stat: flatIntConstraints=412
%%%mzn-stat: flatFloatConstraints=20831
%%%mzn-stat: method="maximize"
%%%mzn-stat: flatTime=4.09564
%%%mzn-stat-end
MiniZinc: internal error: Error: solver backend cannot handle constraint: float_div

我试着使用gecode,但它太慢了,永远无法找到最佳解决方案。

我做错什么了吗?在哪里?也许我需要以不同的方式设置目标函数,但我真的不明白我应该改变什么,以及为什么它不能以这种方式工作。

谢谢!

CBC解算器抛出错误backend cannot handle constraint: float_div的原因是该解算器不支持非线性约束,例如目标targetFunc中的div约束。它只支持线性约束。

有些解算器确实支持非线性浮点约束,例如Gecode、JaCoP、OptiMathSAT和Choco。

为了加快Gecode求解器的速度,您可以尝试在solve函数中添加搜索启发式,例如:

solve :: int_search(selectedDiskSize,first_fail,indomain_split) maximize targetFunc;

此处介绍了搜索注释:https://www.minizinc.org/doc-2.4.3/en/lib-annotations.html#search-注释。

我要求更小的数据集的原因是,在这些情况下,人们可能会尝试不同的启发式方法,然后更小的数据集中获得更好的选择要快得多。

在数据和模型中使用浮点值会限制可以使用的FlatZinc解算器的范围。还有相当多的解算器只处理具有整数变量和值的模型。

因此,另一种方法可能是将所有浮点值转换为整数(通过乘以某个常数,并相应地调整其他值(。然后可以使用所有其他FlatZinc解算器,例如Chuffed、OR工具、PicatSAT等。

最新更新