from pyscipopt import Model, quicksum
def IP(A, B, time_limit):
m, n = len(A), len(A[0])
model = Model("IP_CSP")
#切分方式分布
X = [model.addVar(vtype="I", name="x[%s]" % j) for j in range(n)]
#分布和最小
model.setObjective(quicksum(X[j] for j in range(n)), "minimize")
# 使用箱子个数限制
for i in range(m):
model.addCons(quicksum(A[i][j]*X[j] for j in range(n)) >= B[i])
#设置求解时间
model.setRealParam("limits/time", time_limit)
model.optimize()
print("\ngap:",model.getGap())
X1 = [round(model.getVal(X[j])) for j in range(n)]
return X1
def A_and_B_generate(material, demand):
#先给大的分,再分小的
demand.sort(key=lambda x:x[0], reverse=True)
B = [x[1] for x in demand]
L = [x[0] for x in demand]
#制作备选集,需要一般化
A = []
for i in range(material//L[0]+1):
for j in range((material-i*L[0])//L[1]+1):
A.append([i, j, (material-i*L[0]-j*L[1])//L[2]])
#转置一下
A = [[A[i][j] for i in range(len(A))] for j in range(len(A[0]))]
return A, B
def f(material, demand):
#构造约束
A, B = A_and_B_generate(material, demand)
#求解
X = IP(A, B, 10000)
return X
if __name__ == '__main__':
material = 17
demand = [[3,25], [5,20], [7,18]]
X = f(material, demand)
print(X)