我有一个约束问题,我正试图用python-constraint
解决所以我想说我有3个地点:loc1,...loc3
另外,我有7个设备:device1,...device7
每个位置的最大设备数量:loc1:3, loc2:4, loc3:2
(例如loc1
中最多3个设备,依此类推......)
关于位置和设备的一些限制:
loc1: device1, device3, device7
,
loc2: device1, device3, device4, device5, device6, device7
loc3: device2, device4, device5, device6
(仅作为示例device1
,device3
和device7
可以在loc1
中。)
我正在尝试为各个位置的设备提供一组可能的选项。
from constraint import *
problem = Problem()
for key in locations_devices_dict:
problem.addVariable(key,locations_devices_dict[key])
# problem.addVariable("loc1", ['device1', 'device3', 'device7'])
problem.addConstraint(AllDifferentConstraint())
我坚持如何做约束。我试过了:
problem.addConstraint(MaxSumConstraint(3), 'loc1')
但它不起作用,MaxSumConstraint并不总结我需要的东西。
所有设备必须放在某处
可能的解决方案:
loc1: device1, device3
loc2: device4, device6, device7
loc3: device2, device5
有人有想法吗?
(另一个python包/不使用任何包,如果有人有任何建议也是个好主意...)
答案 0 :(得分:3)
这是一个类似于任务的简单模型:
所以我们有一个二进制变量,指示设备 d 是否分配给位置 L 。线性约束只是:
allowed(L,d)
建模)任何约束求解器都可以处理此问题。
列举所有可能的解决方案有点危险。对于大型实例,有太多的方法。即使对于这个小问题,我们已经有25个解决方案:
对于大问题,这个数字将是天文数字。
使用Python约束包,它可能如下所示:
from constraint import *
D = 7 # number of devices
L = 3 # number of locations
maxdev = [3,4,2]
allowed = [[1,3,7],[1,3,4,5,6,7],[2,4,5,6]]
problem = Problem()
problem.addVariables(["x_L%d_d%d" %(loc+1,d+1) for loc in range(L) for d in range(D) if d+1 in allowed[loc]],[0,1])
for loc in range(L):
problem.addConstraint(MaxSumConstraint(maxdev[loc]),["x_L%d_d%d" %(loc+1,d+1) for d in range(D) if d+1 in allowed[loc]])
for d in range(D):
problem.addConstraint(ExactSumConstraint(1),["x_L%d_d%d" %(loc+1,d+1) for loc in range(L) if d+1 in allowed[loc]])
S = problem.getSolutions()
n = len(S)
n
对于大问题,您可能希望使用dicts来加快速度。
答案 1 :(得分:0)
编辑:在我看到@ ErwinKalvelagen的代码之前,我写了这个答案。所以我没有检查他的解决方案......
所以我使用@ErwinKalvelagen方法创建了一个表示问题的矩阵。 对于每个(i,j),如果设备i可以到达位置j,则x [i,j] = 1,否则为0。
然后,我为每一行使用addConstraint(MaxSumConstraint(maxAmount[i]), row)
- 这是表示每个位置中最大设备的约束。
和addConstraint(ExactSumConstraint(1), col)
- 这是每个设备只能放在一个位置的约束。
接下来,我把所有x [i,j] = 0(设备我不能在位置j)和每个t(i,j)addConstraint(lambda var, val=0: var == val, (t,))
此问题类似于数独问题,我使用this示例获取帮助
上面示例的矩阵是:
(devices:) 1 2 3 4 5 6 7
loc1: 1 0 1 0 0 0 1
loc2: 1 0 1 1 1 1 1
loc3: 0 1 0 1 1 1 0
我的代码:
problem = Problem()
rows = range(locations_amount)
cols = range(devices_amount)
matrix = [(row, col) for row in rows for col in cols]
problem.addVariables(matrix, range(0, 2)) #each cell can get 0 or 1
rowSet = [zip([el] * len(cols), cols) for el in rows]
colSet = [zip(rows, [el] * len(rows)) for el in cols]
rowsConstrains = getRowConstrains() # list that has the maximum amount in each location(3,4,2)
#from my example: loc1:3, loc2:4, loc3:2
for i,row in enumerate(rowSet):
problem.addConstraint(MaxSumConstraint(rowsConstrains[i]), row)
for col in colSet:
problem.addConstraint(ExactSumConstraint(1), col)
s = getLocationsSet() # set that has all the tuples that x[i,j] = 1
for i, loc in enumerate(locations_list):
for j, iot in enumerate(devices_list):
t=(i,j)
if t in s:
continue
problem.addConstraint(lambda var, val=0: var == val, (t,)) # the value in these cells must be 0
solver = problem.getSolution()
解决方案的示例:
(devices:) 1 2 3 4 5 6 7
loc1: 1 0 1 0 0 0 1
loc2: 0 0 0 1 1 1 0
loc3: 0 1 0 0 0 0 0