迷你锌。离散背包问题。 Аn难以理解的解决方案
MiniZinc. Discrete knapsack problem. Аn incomprehensible solution
求解(来自https://www.minizinc.org/doc-2.5.5/en/modelling2.html#set-constraints):
enum ITEM = { I1, I2, I3, I4, I5 };
int: capacity = 5;
array[ITEM] of int: profits = [1,2,3,4,5];
array[ITEM] of int: weights = [1,2,3,4,5];
int: maxProfit = sum (profits);
var set of ITEM: knapsack;
var int: weight = sum ([weights[i] | i in knapsack]);
var int: profit = sum ([profits[i] | i in knapsack]);
constraint weight <= capacity;
solve maximize profit;
output ["knapsack = \(knapsack)\n",
"weight = \(weight)/\(capacity)\n",
"profit = \(profit)"]
输出:
knapsack = {I1, I2}
weight = 3/5
profit = 3
----------
knapsack = {I1, I3}
weight = 4/5
profit = 4
----------
knapsack = {I1, I4}
weight = 5/5
profit = 5
----------
==========
请告诉我为什么输出是这样的?
我期待以下形式的回答:
% profit 5 for all
{ I1, I4 }
{ I2, I3 }
{ I5 }
解算器:Gecode 6.3.0
如果我正确理解你的问题,你期望输出应该显示所有最优解。对吗?
但是,这是一个优化问题,只显示一个最优解。前两个“解决方案”是具有增加值 profit
(3 和 4)的中间解决方案。最后一个解(profit = 5
)就是最优解:{I1, I4}
.
如果您想要所有最优解(profit = 5
),您必须将其添加为约束并将 solve maximize profit
更改为 solve satisfy
:
constraint profit = 5;
% solve maximize profit;
solve satisfy;
那么输出将是:
knapsack = {I1, I4}
weight = 5/5
profit = 5
----------
knapsack = {I2, I3}
weight = 5/5
profit = 5
----------
knapsack = {I5}
weight = 5/5
profit = 5
----------
==========
我不知道 MiniZinc(或 FlatZinc 解算器)的任何标志会直接打印所有最优解(即没有上述手动处理)。但是,这可以使用 Python 接口 MiniZinc Python
(https://minizinc-python.readthedocs.io/en/latest/ )
更新
这里有一个 Python 模型(使用 MiniZinc-Python),用于显示所有最优解。除了没有 solve
行外,MiniZinc 模型与所述相同。这是由 Python 程序添加的,是获得所有最优解的关键。
from minizinc import Instance, Model, Solver
gecode = Solver.lookup("gecode")
model = Model("./discrete_knapsack.mzn")
instance = Instance(gecode, model)
with instance.branch() as opt:
opt.add_string("solve maximize profit;\n")
res = opt.solve()
obj = res["objective"]
instance.add_string(f"constraint sum ([profits[i] | i in knapsack]) = {obj};\n")
result = instance.solve(all_solutions=True)
for sol in result.solution:
print(sol)
print()
输出为:
knapsack = {I1, I4}
weight = 5/5
profit = 5
knapsack = {I2, I3}
weight = 5/5
profit = 5
knapsack = {I5}
weight = 5/5
profit = 5
(该程序的灵感来自 MiniZinc-Python 示例 https://minizinc-python.readthedocs.io/en/latest/basic_usage.html#finding-all-optimal-solutions )
求解(来自https://www.minizinc.org/doc-2.5.5/en/modelling2.html#set-constraints):
enum ITEM = { I1, I2, I3, I4, I5 };
int: capacity = 5;
array[ITEM] of int: profits = [1,2,3,4,5];
array[ITEM] of int: weights = [1,2,3,4,5];
int: maxProfit = sum (profits);
var set of ITEM: knapsack;
var int: weight = sum ([weights[i] | i in knapsack]);
var int: profit = sum ([profits[i] | i in knapsack]);
constraint weight <= capacity;
solve maximize profit;
output ["knapsack = \(knapsack)\n",
"weight = \(weight)/\(capacity)\n",
"profit = \(profit)"]
输出:
knapsack = {I1, I2}
weight = 3/5
profit = 3
----------
knapsack = {I1, I3}
weight = 4/5
profit = 4
----------
knapsack = {I1, I4}
weight = 5/5
profit = 5
----------
==========
请告诉我为什么输出是这样的? 我期待以下形式的回答:
% profit 5 for all
{ I1, I4 }
{ I2, I3 }
{ I5 }
解算器:Gecode 6.3.0
如果我正确理解你的问题,你期望输出应该显示所有最优解。对吗?
但是,这是一个优化问题,只显示一个最优解。前两个“解决方案”是具有增加值 profit
(3 和 4)的中间解决方案。最后一个解(profit = 5
)就是最优解:{I1, I4}
.
如果您想要所有最优解(profit = 5
),您必须将其添加为约束并将 solve maximize profit
更改为 solve satisfy
:
constraint profit = 5;
% solve maximize profit;
solve satisfy;
那么输出将是:
knapsack = {I1, I4}
weight = 5/5
profit = 5
----------
knapsack = {I2, I3}
weight = 5/5
profit = 5
----------
knapsack = {I5}
weight = 5/5
profit = 5
----------
==========
我不知道 MiniZinc(或 FlatZinc 解算器)的任何标志会直接打印所有最优解(即没有上述手动处理)。但是,这可以使用 Python 接口 MiniZinc Python
(https://minizinc-python.readthedocs.io/en/latest/ )
更新
这里有一个 Python 模型(使用 MiniZinc-Python),用于显示所有最优解。除了没有 solve
行外,MiniZinc 模型与所述相同。这是由 Python 程序添加的,是获得所有最优解的关键。
from minizinc import Instance, Model, Solver
gecode = Solver.lookup("gecode")
model = Model("./discrete_knapsack.mzn")
instance = Instance(gecode, model)
with instance.branch() as opt:
opt.add_string("solve maximize profit;\n")
res = opt.solve()
obj = res["objective"]
instance.add_string(f"constraint sum ([profits[i] | i in knapsack]) = {obj};\n")
result = instance.solve(all_solutions=True)
for sol in result.solution:
print(sol)
print()
输出为:
knapsack = {I1, I4}
weight = 5/5
profit = 5
knapsack = {I2, I3}
weight = 5/5
profit = 5
knapsack = {I5}
weight = 5/5
profit = 5
(该程序的灵感来自 MiniZinc-Python 示例 https://minizinc-python.readthedocs.io/en/latest/basic_usage.html#finding-all-optimal-solutions )