赞
踩
接上篇学会了如何用python调用gurobipy之后,这篇总结一些学到的基本操作。
tuplelist、tupledict、multidict、创建list、
tuplelist是Python list的扩展对象,使用tuplelist()不能忘记from gurobipy import *,tuplelist增加了快速筛选select功能,比传统的if...else...筛选速度快。
- from gurobipy import *
- import time
-
- T1 = time.time()
- Cities=[("A","B"),("A","C"),("B","C"),("B","D"),("C","D")]
- Routes=tuplelist(Cities)
- print(Routes.select("A","*"))
- T2 =time.time()
-
- print('程序运行时间:%s毫秒' % ((T2 - T1)*1000))
tuplelist运行结果:
- C:\Users\xzr\.conda\envs\py310gurobi\python.exe F:\PycharmProjects\workspace\untitled\jizulunban\caogao.py
- <gurobi.tuplelist (2 tuples, 2 values each):
- ( A , B )
- ( A , C )
- >
- 程序运行时间:1.9958019256591797毫秒
-
- 进程已结束,退出代码0
for...else...方法:
- from gurobipy import *
- import time
-
- T1 = time.time()
- Cities=[("A","B"),("A","C"),("B","C"),("B","D"),("C","D")]
- Result=[]
- for i,j in Cities:
- if i=="A":
- Result.append((i,j))
- print(Result)
- T2 =time.time()
-
- print('程序运行时间:%s毫秒' % ((T2 - T1)*1000))
for...else...运行结果:
- C:\Users\xzr\.conda\envs\py310gurobi\python.exe F:\PycharmProjects\workspace\untitled\jizulunban\caogao.py
- [('A', 'B'), ('A', 'C')]
- 程序运行时间:0.0毫秒
-
- 进程已结束,退出代码0
尴尬了,竟然是for...else...的运行速度更快,原因是数据量太少了体现不出效果。
tupledict是Python Dictionary的扩展对象,键值是tuple(元组),可以使用select、sum、prob函数。用于变量和约束。后面有详细介绍。
multidict()创建tuplelist和tupledict的便捷方法。代码示例:
- from gurobipy import *
- import time
-
- # T1 = time.time()
- cities,supply,demand = multidict({
- "A":[100,20],
- "B":[150,50],
- "C":[20,300],
- "D":[10,200]})
- print(cities)
- print(supply)
- print(demand)
- # T2 =time.time()
运行结果:
- C:\Users\xzr\.conda\envs\py310gurobi\python.exe F:\PycharmProjects\workspace\untitled\jizulunban\caogao.py
- ['A', 'B', 'C', 'D']
- {'A': 100, 'B': 150, 'C': 20, 'D': 10}
- {'A': 20, 'B': 50, 'C': 300, 'D': 200}
-
- 进程已结束,退出代码0
运行结果第一行是list,第二三行是dictionary。
python有多种创建list的方法:
- a=[]
- a.append("A")
b=[i**2 for i in range(6)] #[0,1,4,9,16,25]
c=[(i,j)for j in range(4) for i in range(j)] #[(0,1),(0,2),(1,2),(0,3),(1,3),(2,3)]
d=[i for i in range(10) if i not in b] #[2,3,5,6,7,8]
- Pairs=[]
- for j in range(4):
- for i in range(j):
- Pairs.append((i,j))
对于求和,Python的Generator(生成器):
SumSquares=sum(i**2 for i in range(6)) #55
Gurobi中采用quicksum,效率更高:
obj=quicksum(cost[i,j]*x[i,j] for i,j in arcs)
tupledict(Gurobi变量一般都是tupledict类型)有sum函数
- from gurobipy import *
- import time
-
- # T1 = time.time()
- m=Model()
- x=m.addVars(3,4,vtype=GRB.BINARY,name="x")
- m.addConstrs((x.sum(i,"*")<=1 for i in range(3)),name="con")
- m.update()
- m.write("test.lp")
- # T2 =time.time()
-
- # print('程序运行时间:%s毫秒' % ((T2 - T1)*1000))
运行后,打开“test.lp”文件查看写入的模型
- \ LP format - for model browsing. Use MPS format to capture full model detail.
- Minimize
-
- Subject To
- con[0]: x[0,0] + x[0,1] + x[0,2] + x[0,3] <= 1
- con[1]: x[1,0] + x[1,1] + x[1,2] + x[1,3] <= 1
- con[2]: x[2,0] + x[2,1] + x[2,2] + x[2,3] <= 1
- Bounds
- Binaries
- x[0,0] x[0,1] x[0,2] x[0,3] x[1,0] x[1,1] x[1,2] x[1,3] x[2,0] x[2,1]
- x[2,2] x[2,3]
- End
太妙了太妙了
tupledict(Gurobi变量一般都是tupledict类型)还有prob函数,用于变量和系数相乘后累加
以下表达式等效
obj=quicksum(cost[i,j]*x[i,j] for i,j in arcs)
obj=x.prod(cost)
建模建议,尽量采用稀疏方式,采用tuplelists筛选和指定合适的下标组合关系,基于这些组合关系建立变量和数据字典,利用tuplelist.select()以及tupledict.select(),tupledict.sum(),tupledict.prob()来对下标进行组合处理。
- from gurobipy import *
-
- # T1 = time.time()
-
- try:
- #Create a new model
- m=Model("mip1")
-
- #Create variables
- x=m.addVar(vtype=GRB.BINARY,name="x")
- y=m.addVar(vtype=GRB.BINARY,name="y")
- z=m.addVar(vtype=GRB.BINARY,name="z")
-
- #Set objective
- m.setObjective(x+y+2*z,GRB.MAXIMIZE)
-
- #Add constraint:x+2y+3z<=4
- m.addConstr(x+2*y+3*z<=4,"c0")
-
- #Add constraint:x+y>=1
- m.addConstr(x+y>=1,"c1")
-
- m.optimize()
-
- for v in m.getVars(): #getVars获取所有变量
- print("%s %g" % (v.varName,v.x)) #(v.varName,v.x)是(变量名字,优化结果)
- print("Obj: %g" % m.objVal)
-
- except GurobiError as e:
- print("Error code" + str(e.errno)+":"+str(e))
-
- except AttributeError:
- print("Encountered an attribute error")
-
-
- # T2 =time.time()
- # print('程序运行时间:%s毫秒' % ((T2 - T1)*1000))
运行结果
- C:\Users\xzr\.conda\envs\py310gurobi\python.exe F:\PycharmProjects\workspace\untitled\jizulunban\caogao.py
- Gurobi Optimizer version 10.0.0 build v10.0.0rc2 (win64)
-
- CPU model: Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz, instruction set [SSE2|AVX|AVX2]
- Thread count: 2 physical cores, 4 logical processors, using up to 4 threads
-
- Optimize a model with 2 rows, 3 columns and 5 nonzeros
- Model fingerprint: 0x98886187
- Variable types: 0 continuous, 3 integer (3 binary)
- Coefficient statistics:
- Matrix range [1e+00, 3e+00]
- Objective range [1e+00, 2e+00]
- Bounds range [1e+00, 1e+00]
- RHS range [1e+00, 4e+00]
- Found heuristic solution: objective 2.0000000
- Presolve removed 2 rows and 3 columns
- Presolve time: 0.02s
- Presolve: All rows and columns removed
-
- Explored 0 nodes (0 simplex iterations) in 0.03 seconds (0.00 work units)
- Thread count was 1 (of 4 available processors)
-
- Solution count 2: 3 2
-
- Optimal solution found (tolerance 1.00e-04)
- Best objective 3.000000000000e+00, best bound 3.000000000000e+00, gap 0.0000%
- x 1
- y 0
- z 1
- Obj: 3
-
- 进程已结束,退出代码0
- from gurobipy import *
-
- categories,minNutrition,maxNutrition=multidict({
- "calories":[1800,2200],
- "protein":[91,GRB.INFINITY],
- "fat":[0,65],
- "sodium":[0,1779]
- })
-
- foods,cost=multidict({
- "hamburger":2.49,
- "chicken":2.89,
- "hot dog":1.50,
- "fries":1.89,
- "macaroni":2.09,
- "pizza":1.99,
- "salad":2.49,
- "milk":0.89,
- "ice cream":1.59
- })
-
- #Nutrition values for the foods
- nutritionValues={
- ("hamburger","calories"):410,
- ("hamburger","protein"):24,
- ("hamburger","fat"):26,
- ("hamburger","sodium"):730,
- ("chicken","calories"):420,
- ("chicken", "protein"):32,
- ("chicken", "fat"):10,
- ("chicken", "sodium"):1190,
- ("hot dog","calories"):560,
- ("hot dog", "protein"):20,
- ("hot dog", "fat"):32,
- ("hot dog", "sodium"):1800,
- ("fries","calories"):380,
- ("fries", "protein"):4,
- ("fries", "fat"):19,
- ("fries", "sodium"):720,
- ("macaroni", "calories"): 320,
- ("macaroni", "protein"): 12,
- ("macaroni", "fat"): 10,
- ("macaroni", "sodium"): 930,
- ("pizza", "calories"): 320,
- ("pizza", "protein"): 15,
- ("pizza", "fat"): 12,
- ("pizza", "sodium"): 820,
- ("salad", "calories"): 320,
- ("salad", "protein"): 31,
- ("salad", "fat"): 12,
- ("salad", "sodium"): 1230,
- ("milk", "calories"): 100,
- ("milk", "protein"): 8,
- ("milk", "fat"): 2.5,
- ("milk", "sodium"): 125,
- ("ice cream", "calories"): 330,
- ("ice cream", "protein"): 8,
- ("ice cream", "fat"): 10,
- ("ice cream", "sodium"): 180
- }
-
- #Model
- m=Model("diet")
-
- #Create decision variables for the foods to buy
- buy=m.addVars(foods,name="buy")
- #也可以是:
- # buy=[]
- # for f in foods:
- # buy[f]=m.addVar(name=f)
-
- #目标函数是最小化cost
- m.setObjective(buy.prod(cost),GRB.MINIMIZE)
- #如果使用循环结构,应该是:
- # m.setObjective(sum(buy[f]*cost[f] for f in foods),GRB.MINIMIZE)
-
- #Nutrition constraints
- m.addConstrs(
- (quicksum(nutritionValues[f,c]*buy[f] for f in foods)
- == [minNutrition[c],maxNutrition[c]]
- for c in categories),"_")
- #如果使用循环结构,应该是:
- # for c in categories:
- # m.addRange(
- # sum(nutritionValues[f,c] * buy[f] for f in foods),minNutrition[c],maxNutrition[c],c)
- # )
-
- def printSolution():
- if m.status == GRB.Status.OPTIMAL:
- print("\nCost:%g" % m.objval)
- print("\nBuy:")
- buyx=m.getAttr("x",buy)
- for f in foods:
- if buy[f].x>0.0001:
- print("%s %g" % (f,buyx[f]))
- else:
- print("No solution")
-
- #solve
- m.optimize()
- printSolution()
-
-
- # T1 = time.time()
-
-
-
-
- # T2 =time.time()
- # print('程序运行时间:%s毫秒' % ((T2 - T1)*1000))
运行结果
- C:\Users\xzr\.conda\envs\py310gurobi\python.exe F:\PycharmProjects\workspace\untitled\jizulunban\caogao.py
- Gurobi Optimizer version 10.0.0 build v10.0.0rc2 (win64)
-
- CPU model: Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz, instruction set [SSE2|AVX|AVX2]
- Thread count: 2 physical cores, 4 logical processors, using up to 4 threads
-
- Optimize a model with 4 rows, 12 columns and 39 nonzeros
- Model fingerprint: 0xed649f3c
- Coefficient statistics:
- Matrix range [1e+00, 2e+03]
- Objective range [9e-01, 3e+00]
- Bounds range [7e+01, 2e+03]
- RHS range [7e+01, 2e+03]
- Presolve removed 0 rows and 2 columns
- Presolve time: 0.01s
- Presolved: 4 rows, 10 columns, 37 nonzeros
-
- Iteration Objective Primal Inf. Dual Inf. Time
- 0 0.0000000e+00 1.472500e+02 0.000000e+00 0s
- 4 1.1828861e+01 0.000000e+00 0.000000e+00 0s
-
- Solved in 4 iterations and 0.03 seconds (0.00 work units)
- Optimal objective 1.182886111e+01
—————————————————————————————————————————
注意:
若出现众多warning,删去warning给的路径下的带“~”的文件
若出现ERROR: Could not find a version that satisfies the requirement time (from versions: none),是找不到适应现有python版本的包
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。