我是约束编程的新手,试图弄清楚如何进行“至少n个”约束。
例如,我的整数变量x,y和z都在0到5的范围内。
现在,我需要所有至少两个变量在2到3之间的解决方案。
类似于“给定条件之和> = 2”
我该如何在python中,最好是在Google的OR-Tools中做到这一点?
谢谢
答案 0 :(得分:1)
假设您具有这些条件
x = 2.5
y = 4
z = 2.9
然后,您可以构建值列表,然后应用lambda
,map
和sum
来找出问题。例如:
# Create the list of values
values = [x, y, z]
# Apply a lambda to each element of the list, checking if they
# are within [2,3]. This would return a boolean, so I am translating
# those to 1 and 0
ones_or_zeroes = map(lambda x: 1 if 2<=x<=3 else 0, values)
# Check condition of how many matched the condition:
condition = sum(ones_or_zeroes)
当然可以压缩为:
if sum(map(lambda x: 1 if 2<=x<=3 else 0, values)) >= 2:
# then at least 2 variables match the costraint
pass
答案 1 :(得分:1)
from ortools.sat.python import cp_model
import collections
class SolutionPrinter(cp_model.CpSolverSolutionCallback):
"""Print intermediate solutions."""
def __init__(self, variables):
cp_model.CpSolverSolutionCallback.__init__(self)
self.__variables = variables
self.__num_vars = len(variables)
self.__num_values = len(variables[0])
self.__solution_count = 0
def on_solution_callback(self):
self.__solution_count += 1
for var in range(self.__num_vars):
for value in range(self.__num_values):
if self.BooleanValue(self.__variables[var][value]):
print('var[%i]=%i' % (var, value), end=' ')
break
print()
def solution_count(self):
return self.__solution_count
num_vars = 3
max_values = 5
model = cp_model.CpModel()
vars = collections.defaultdict(list)
for var in range(num_vars):
for value in range(max_values + 1):
vars[var].append(model.NewBoolVar('x_%i_%i' % (var, value)))
# Exactly one value per variable
for var in range(num_vars):
model.Add(sum(vars[var]) == 1)
# At least 2 between 2 and 3
model.Add(sum(vars[var][2] for var in range(num_vars)) +
sum(vars[var][3] for var in range(num_vars)) >= 2)
# Enumerate all solutions
solver = cp_model.CpSolver()
solution_printer = SolutionPrinter(vars)
status = solver.SearchForAllSolutions(model, solution_printer)
print('Status = %s' % solver.StatusName(status))
print('Number of solutions found: %i' % solution_printer.solution_count())
输出
var[0]=3 var[1]=2 var[2]=0
var[0]=3 var[1]=2 var[2]=5
var[0]=3 var[1]=2 var[2]=4
var[0]=3 var[1]=2 var[2]=1
var[0]=3 var[1]=2 var[2]=3
var[0]=3 var[1]=0 var[2]=3
var[0]=3 var[1]=1 var[2]=3
var[0]=3 var[1]=5 var[2]=3
var[0]=3 var[1]=4 var[2]=3
var[0]=3 var[1]=4 var[2]=2
var[0]=3 var[1]=0 var[2]=2
var[0]=3 var[1]=1 var[2]=2
var[0]=3 var[1]=2 var[2]=2
var[0]=3 var[1]=5 var[2]=2
var[0]=3 var[1]=3 var[2]=2
var[0]=3 var[1]=3 var[2]=4
var[0]=3 var[1]=3 var[2]=5
var[0]=3 var[1]=3 var[2]=1
var[0]=3 var[1]=3 var[2]=0
var[0]=3 var[1]=3 var[2]=3
var[0]=5 var[1]=3 var[2]=3
var[0]=1 var[1]=3 var[2]=3
var[0]=4 var[1]=3 var[2]=3
var[0]=2 var[1]=3 var[2]=3
var[0]=0 var[1]=3 var[2]=3
var[0]=2 var[1]=3 var[2]=0
var[0]=2 var[1]=3 var[2]=5
var[0]=2 var[1]=3 var[2]=4
var[0]=2 var[1]=3 var[2]=1
var[0]=2 var[1]=3 var[2]=2
var[0]=5 var[1]=3 var[2]=2
var[0]=1 var[1]=3 var[2]=2
var[0]=4 var[1]=3 var[2]=2
var[0]=0 var[1]=3 var[2]=2
var[0]=0 var[1]=2 var[2]=2
var[0]=5 var[1]=2 var[2]=2
var[0]=4 var[1]=2 var[2]=2
var[0]=1 var[1]=2 var[2]=2
var[0]=2 var[1]=2 var[2]=2
var[0]=2 var[1]=0 var[2]=2
var[0]=2 var[1]=1 var[2]=2
var[0]=2 var[1]=5 var[2]=2
var[0]=2 var[1]=4 var[2]=2
var[0]=2 var[1]=2 var[2]=1
var[0]=2 var[1]=2 var[2]=0
var[0]=2 var[1]=2 var[2]=5
var[0]=2 var[1]=2 var[2]=4
var[0]=2 var[1]=2 var[2]=3
var[0]=2 var[1]=0 var[2]=3
var[0]=2 var[1]=1 var[2]=3
var[0]=5 var[1]=2 var[2]=3
var[0]=4 var[1]=2 var[2]=3
var[0]=1 var[1]=2 var[2]=3
var[0]=2 var[1]=5 var[2]=3
var[0]=2 var[1]=4 var[2]=3
var[0]=0 var[1]=2 var[2]=3
Status = OPTIMAL
Number of solutions found: 56