使用 ortools select 列表中的两个最小整数值
Using ortools to select the two smallest integer values in a list
我知道 ortools 在这里有点矫枉过正,但这是为了我自己边做边学的目的。
问题是:如何使用 ortools 找到列表中的两个最小整数值?
这是我得到的代码,基于我得到的另一个例子,它只是找到单个最小值。
from __future__ import print_function
from ortools.sat.python import cp_model
# 2. A simple problem
# Select the two smallest numbers from a list of integers
# Define data
cost_data = [
5, 4, 3, 4, 5, 6, 7, 1, 2, 3
]
num_hours = len(cost_data)
hours = range(num_hours)
# Create model
model = cp_model.CpModel()
# Create variables
cost_vars = {}
pick_vars = {}
for i in hours:
for j in hours:
cost_vars[(i, j)] = model.NewIntVar(0, 100, 'c_%i_%i' % (i, j))
pick_vars[(i, j)] = model.NewBoolVar('p_%i_%i' % (i, j))
# Create constraints
# An hour can only be picked once
for i in hours:
model.Add(sum(pick_vars[(i, j)] for j in hours) == 1)
# Only set cost if applicable
for i in hours:
for j in hours:
model.Add(cost_vars[(i, j)] == cost_data[i] + cost_data[j]).OnlyEnforceIf(pick_vars[(i, j)])
model.Add(cost_vars[(i, j)] == 0).OnlyEnforceIf(pick_vars[(i, j)].Not())
# Set objective function
for i in hours:
model.Minimize(sum([cost_vars[(i, j)] for j in hours]))
# Solve problem
solver = cp_model.CpSolver()
status = solver.Solve(model)
if status == cp_model.INFEASIBLE:
print("INFEASIBLE")
elif status == cp_model.FEASIBLE:
print("FEASIBLE")
elif status == cp_model.OPTIMAL:
print("OPTIMAL")
print("ObjectiveValue()")
print(solver.ObjectiveValue())
# print(solver.Value(cost_vars[(1, 2)]))
它returns值4,当实际值应该是3...
存在多个问题:
你应该只调用一次 Minimize 或 Maximize,只有最后一个才会生效,所以我猜你想要 model.Minimize(sum(cost_vars.values()))
这个我也不懂:
for i in hours:
model.Add(sum(pick_vars[(i, j)] for j in hours) == 1)
也许你的意思是:
model.Add(sum(pick_vars.values()) == 1)
而且在这里你应该检查是否 i != j
:
for i in hours:
for j in hours:
编辑:如果i != j
那么一开始就不要创造可能性
for i in hours:
for j in hours:
if i != j:
cost_vars[(i, j)] = model.NewIntVar(0, 100, 'c_%i_%i' % (i, j))
pick_vars[(i, j)] = model.NewBoolVar('p_%i_%i' % (i, j))
我知道 ortools 在这里有点矫枉过正,但这是为了我自己边做边学的目的。
问题是:如何使用 ortools 找到列表中的两个最小整数值?
这是我得到的代码,基于我得到的另一个例子,它只是找到单个最小值。
from __future__ import print_function
from ortools.sat.python import cp_model
# 2. A simple problem
# Select the two smallest numbers from a list of integers
# Define data
cost_data = [
5, 4, 3, 4, 5, 6, 7, 1, 2, 3
]
num_hours = len(cost_data)
hours = range(num_hours)
# Create model
model = cp_model.CpModel()
# Create variables
cost_vars = {}
pick_vars = {}
for i in hours:
for j in hours:
cost_vars[(i, j)] = model.NewIntVar(0, 100, 'c_%i_%i' % (i, j))
pick_vars[(i, j)] = model.NewBoolVar('p_%i_%i' % (i, j))
# Create constraints
# An hour can only be picked once
for i in hours:
model.Add(sum(pick_vars[(i, j)] for j in hours) == 1)
# Only set cost if applicable
for i in hours:
for j in hours:
model.Add(cost_vars[(i, j)] == cost_data[i] + cost_data[j]).OnlyEnforceIf(pick_vars[(i, j)])
model.Add(cost_vars[(i, j)] == 0).OnlyEnforceIf(pick_vars[(i, j)].Not())
# Set objective function
for i in hours:
model.Minimize(sum([cost_vars[(i, j)] for j in hours]))
# Solve problem
solver = cp_model.CpSolver()
status = solver.Solve(model)
if status == cp_model.INFEASIBLE:
print("INFEASIBLE")
elif status == cp_model.FEASIBLE:
print("FEASIBLE")
elif status == cp_model.OPTIMAL:
print("OPTIMAL")
print("ObjectiveValue()")
print(solver.ObjectiveValue())
# print(solver.Value(cost_vars[(1, 2)]))
它returns值4,当实际值应该是3...
存在多个问题:
你应该只调用一次 Minimize 或 Maximize,只有最后一个才会生效,所以我猜你想要 model.Minimize(sum(cost_vars.values()))
这个我也不懂:
for i in hours:
model.Add(sum(pick_vars[(i, j)] for j in hours) == 1)
也许你的意思是:
model.Add(sum(pick_vars.values()) == 1)
而且在这里你应该检查是否 i != j
:
for i in hours:
for j in hours:
编辑:如果i != j
那么一开始就不要创造可能性
for i in hours:
for j in hours:
if i != j:
cost_vars[(i, j)] = model.NewIntVar(0, 100, 'c_%i_%i' % (i, j))
pick_vars[(i, j)] = model.NewBoolVar('p_%i_%i' % (i, j))