1.问题背景:
一家企业拥有一批原料棒材,他要将这些棒材进行切割加工成为规定尺寸的产品,然后卖给顾客。这家企业需要设计最优的棒材切割方案,以最小的原材料消耗,生产出规定尺寸的产品,以满足顾客的需求。
2.数学模型:
3.程序:
# -*- coding : utf-8 -*-
# @Time : 2022/5/2 19:11
# @Author : wkb
from gurobipy import *
import time
import random
# parameter
Demand_dic = {} # ID:(long,number)
L = 20
I = 2
K = 20
# for i in range(I):
# long = random.randint(1,10)
# number = random.randint(1,10)
# Demand_dic[i] = (long,number)
Demand_dic = {0:(6,20),1:(9,15)}
print(Demand_dic)
# declare variable
model = Model("CSP")
x={}
y={}
for i in range(I):
for k in range(K):
x[i,k] = model.addVar(0,GRB.INFINITY,vtype=GRB.INTEGER,name="x[{0},{1}]".format(i,k))
for k in range(K):
y[k] = model.addVar(0, 1, vtype=GRB.BINARY, name="y[{0}]".format(k))
# add constraint_1
for i in range(I):
expr = LinExpr(0)
for k in range(K):
expr.addTerms(1,x[i,k])
model.addConstr(expr >= Demand_dic[i][1],name="c_1_{0}".format(i+1))
# add constraint_2
for k in range(K):
expr = LinExpr(0)
for i in range(I):
expr.addTerms(Demand_dic[i][0],x[i,k])
model.addConstr(expr <= L*y[k],name="c_2_{0}".format(k+1))
# set objective
expr = LinExpr(0)
for k in range(K):
expr.addTerms(1,y[k])
model.setObjective(expr,sense=GRB.MINIMIZE)
#optimal
start_time = time.time()
model.optimize()
end_time = time.time()
cpu_time = end_time - start_time
print("CPU_run time = {0} sec".format(cpu_time))
if model.status == GRB.OPTIMAL:
soltion_x = {}
for key in x.keys():
soltion_x[key] = x[key].x
solution_y = {}
for key in y.keys():
solution_y[key] = y[key].x
obj = model.getObjective()
print("obj = ",obj.getValue())
for i in range(I):
for k in range(K):
if soltion_x[i,k] != 0:
print("x[{0},{1}] = {2}".format(i,k,soltion_x[i,k]))
for k in range(K):
if solution_y[k] == 1:
print("y[{0}]={1}".format(k, solution_y[k]))
model.write("csp.lp")
4.求解:
Using license file C:\Users\WKB\gurobi.lic
Gurobi Optimizer version 9.1.2 build v9.1.2rc0 (win64)
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 22 rows, 60 columns and 100 nonzeros
Model fingerprint: 0x9c470235
Variable types: 0 continuous, 60 integer (20 binary)
Coefficient statistics:
Matrix range [1e+00, 2e+01]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 1e+00]
RHS range [2e+01, 2e+01]
Presolve time: 0.00s
Presolved: 22 rows, 60 columns, 100 nonzeros
Variable types: 0 continuous, 60 integer (20 binary)
Found heuristic solution: objective 15.0000000
Root relaxation: cutoff, 40 iterations, 0.00 seconds
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 cutoff 0 15.00000 15.00000 0.00% - 0s
Explored 0 nodes (40 simplex iterations) in 0.00 seconds
Thread count was 8 (of 8 available processors)
Solution count 1: 15
Optimal solution found (tolerance 1.00e-04)
Best objective 1.500000000000e+01, best bound 1.500000000000e+01, gap 0.0000%
obj = 15.0
5.分析:
对于需求比较少的CTP问题gurobi能快速的进行求解,但是问题规模一旦很大之后,gurobi就很难进行求解了,这个时候就需要新的求解方式和建模方式来解决:CG(Column generation)
6.变量输出:
此时我们看到的只是最佳的目标函数值和CPU的求解时间,我们还需要知道具体的切割方案:也就是我们需要输出x[i,k] 和 y[k].
x[0,5] = 3.0
x[0,6] = 3.0
x[0,7] = 3.0
x[0,8] = 3.0
x[0,9] = 3.0
x[0,10] = 3.0
x[0,11] = 3.0
x[1,12] = 1.0
x[1,13] = 2.0
x[1,14] = 2.0
x[1,15] = 2.0
x[1,16] = 2.0
x[1,17] = 2.0
x[1,18] = 2.0
x[1,19] = 2.0
y[5]=1.0
y[6]=1.0
y[7]=1.0
y[8]=1.0
y[9]=1.0
y[10]=1.0
y[11]=1.0
y[12]=1.0
y[13]=1.0
y[14]=1.0
y[15]=1.0
y[16]=1.0
y[17]=1.0
y[18]=1.0
y[19]=1.0
其中x[0,5]=3表示0号需求在5号钢卷中切了3段出来。