首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Minizinc模型在"MiniZinc:内部错误:错误:解决程序后端无法处理约束: float_div“中失败

Minizinc模型在"MiniZinc:内部错误:错误:解决程序后端无法处理约束: float_div“中失败
EN

Stack Overflow用户
提问于 2021-11-24 08:01:17
回答 1查看 152关注 0票数 0

我只是个初学者,想看看我是否能在日常生活中使用minizinc。我试图建立的第一个模型是这里,数据文件是这里

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

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

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

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

代码语言:javascript
复制
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]) ]

我把它作为:

代码语言:javascript
复制
minizinc.exe  -i --solver coin-bc -s -a C:\Work\tools\demo\graphs-n-minizinc-demo\vmCostsCalculation.mzn C:\Work\tools\demo\graphs-n-minizinc-demo\vmData.dzn

并得到以下回应

代码语言:javascript
复制
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,但是它太慢了,永远无法找到最优的解决方案。

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

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-25 06:01:02

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

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

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

代码语言:javascript
复制
solve :: int_search(selectedDiskSize,first_fail,indomain_split) maximize targetFunc;

搜索注释在这里描述:https://www.minizinc.org/doc-2.4.3/en/lib-annotations.html#search-annotations

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

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70092487

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档