8.7. Python API¶
本章节提供MindOpt的Python API手册,内容见下文。
- 8.7.1. 全局函数
- 8.7.2. MindoptError
- 8.7.3. tuplelist
- 8.7.4. tupledict
- 8.7.5. Var
- 8.7.6. MVar
- 8.7.7. PsdVar
- 8.7.8. Constr
- 8.7.9. SOS
- 8.7.10. GenConstr
- 8.7.11. MConstr
- 8.7.12. PsdConstr
- 8.7.13. TempConstr
- 8.7.14. Column
- 8.7.15. LinExpr
- 8.7.16. QuadExpr
- 8.7.17. MLinExpr
- 8.7.18. MQuadExpr
- 8.7.19. PsdExpr
- 8.7.20. Env
- 8.7.21. Model
8.7.22. Examples¶
8.7.22.1. 定制食谱¶
from mindoptpy import *
req = {
# requirement: ( lower bound, upper bound)
"Cal" : ( 2000, MDO.INFINITY),
"Carbo" : ( 350, 375),
"Protein" : ( 55, MDO.INFINITY),
"VitA" : ( 100, MDO.INFINITY),
"VitC" : ( 100, MDO.INFINITY),
"Calc" : ( 100, MDO.INFINITY),
"Iron" : ( 100, MDO.INFINITY),
"Volume" : (-MDO.INFINITY, 75)
}
food = {
# food : ( lower bound, upper bound, cost)
"Cheeseburger" : ( 0, MDO.INFINITY, 1.84),
"HamSandwich" : ( 0, MDO.INFINITY, 2.19),
"Hamburger" : ( 0, MDO.INFINITY, 1.84),
"FishSandwich" : ( 0, MDO.INFINITY, 1.44),
"ChickenSandwich" : ( 0, MDO.INFINITY, 2.29),
"Fries" : ( 0, MDO.INFINITY, 0.77),
"SausageBiscuit" : ( 0, MDO.INFINITY, 1.29),
"LowfatMilk" : ( 0, MDO.INFINITY, 0.60),
"OrangeJuice" : ( 0, MDO.INFINITY, 0.72)
}
req_value = {
# (requirement, food ) : value
( "Cal", "Cheeseburger" ) : 510,
( "Cal", "HamSandwich" ) : 370,
( "Cal", "Hamburger" ) : 500,
( "Cal", "FishSandwich" ) : 370,
( "Cal", "ChickenSandwich" ) : 400,
( "Cal", "Fries" ) : 220,
( "Cal", "SausageBiscuit" ) : 345,
( "Cal", "LowfatMilk" ) : 110,
( "Cal", "OrangeJuice" ) : 80,
( "Carbo", "Cheeseburger" ) : 34,
( "Carbo", "HamSandwich" ) : 35,
( "Carbo", "Hamburger" ) : 42,
( "Carbo", "FishSandwich" ) : 38,
( "Carbo", "ChickenSandwich" ) : 42,
( "Carbo", "Fries" ) : 26,
( "Carbo", "SausageBiscuit" ) : 27,
( "Carbo", "LowfatMilk" ) : 12,
( "Carbo", "OrangeJuice" ) : 20,
( "Protein", "Cheeseburger" ) : 28,
( "Protein", "HamSandwich" ) : 24,
( "Protein", "Hamburger" ) : 25,
( "Protein", "FishSandwich" ) : 14,
( "Protein", "ChickenSandwich" ) : 31,
( "Protein", "Fries" ) : 3,
( "Protein", "SausageBiscuit" ) : 15,
( "Protein", "LowfatMilk" ) : 9,
( "Protein", "OrangeJuice" ) : 1,
( "VitA", "Cheeseburger" ) : 15,
( "VitA", "HamSandwich" ) : 15,
( "VitA", "Hamburger" ) : 6,
( "VitA", "FishSandwich" ) : 2,
( "VitA", "ChickenSandwich" ) : 8,
( "VitA", "Fries" ) : 0,
( "VitA", "SausageBiscuit" ) : 4,
( "VitA", "LowfatMilk" ) : 10,
( "VitA", "OrangeJuice" ) : 2,
( "VitC", "Cheeseburger" ) : 6,
( "VitC", "HamSandwich" ) : 10,
( "VitC", "Hamburger" ) : 2,
( "VitC", "FishSandwich" ) : 0,
( "VitC", "ChickenSandwich" ) : 15,
( "VitC", "Fries" ) : 15,
( "VitC", "SausageBiscuit" ) : 0,
( "VitC", "OrangeJuice" ) : 4,
( "VitC", "LowfatMilk" ) : 120,
( "Calc", "Cheeseburger" ) : 30,
( "Calc", "HamSandwich" ) : 20,
( "Calc", "Hamburger" ) : 25,
( "Calc", "FishSandwich" ) : 15,
( "Calc", "ChickenSandwich" ) : 15,
( "Calc", "Fries" ) : 0,
( "Calc", "SausageBiscuit" ) : 20,
( "Calc", "LowfatMilk" ) : 30,
( "Calc", "OrangeJuice" ) : 2,
( "Iron", "Cheeseburger" ) : 20,
( "Iron", "HamSandwich" ) : 20,
( "Iron", "Hamburger" ) : 20,
( "Iron", "FishSandwich" ) : 10,
( "Iron", "ChickenSandwich" ) : 8,
( "Iron", "Fries" ) : 2,
( "Iron", "SausageBiscuit" ) : 15,
( "Iron", "LowfatMilk" ) : 0,
( "Iron", "OrangeJuice" ) : 2,
( "Volume", "Cheeseburger" ) : 4,
( "Volume", "HamSandwich" ) : 7.5,
( "Volume", "Hamburger" ) : 3.5,
( "Volume", "FishSandwich" ) : 5,
( "Volume", "ChickenSandwich" ) : 7.3,
( "Volume", "Fries" ) : 2.6,
( "Volume", "SausageBiscuit" ) : 4.1,
( "Volume", "LowfatMilk" ) : 8,
( "Volume", "OrangeJuice" ) : 12
}
# 建立模型
m = Model()
# 添加决策变量
variable = {}
for food_name, food_data in food.items():
variable[food_name] = m.addVar(
lb=food_data[0], ub=food_data[1], vtype=MDO.CONTINUOUS, name=food_name
)
# 添加约束
# 应满足每日获取的各种营养素在建议的范围内
cons = {}
for req_name, req_data in req.items():
cons[req_name] = m.addRange(
quicksum(
variable[food_name] * req_value[(req_name, food_name)]
for food_name in food.keys()
),
req_data[0],
req_data[1],
)
# 添加目标函数
objective = quicksum(variable[i] * food[i][2] for i in food.keys())
m.setObjective(objective, MDO.MINIMIZE)
m.optimize()
# 打印结果
for i in variable:
print("Amount of " + i + " intake :" + str(variable[i].X))
print("Total meal cost : " + str(objective.getValue()))
for req_name, req_data in req.items():
print(
"Final intake amount of "
+ req_name
+ ": "
+ str(
quicksum(
variable[food_name] * req_value[(req_name, food_name)]
for food_name in food.keys()
).getValue()
)
)
8.7.22.2. 设施选址¶
from mindoptpy import *
# 本例子的目标是为了找到最小成本的仓库建造和运输方案
# 有两个商场,商场的位置已经确定,分别是(0, 1.7)和(1.4, 2.9), 所需要的货物重量为100单位和200单位
market_info = tupledict([((0, 1.7), 100), ((1.4, 2.9), 200)])
market_keys = list(market_info.keys())
market_num = len(market_info)
# 仓库位置和建造成本
facilities_info = tupledict(
[
((0, 1), 3),
((0, 2), 1),
((1, 0), 1.5),
((1, 1), 1.3),
((1, 2), 1.8),
((2, 0), 1.6),
((2, 1), 1.1),
((2, 2), 1.9),
]
)
facilities_keys = list(facilities_info.keys())
facilities_num = len(facilities_info)
transport_fee_per_m = 1.23
# 建立模型
m = Model("Facilities")
# 添加决策变量
# x代表是否在该地建仓库
x = m.addVars(len(facilities_info), vtype=MDO.BINARY)
# y代表从j仓库运向i商场的货物量,值的类型为CONTINUOUS类型,下限为0代表不能从j仓库运送小于0单位的货物到i商场
provide_quantity = [(i, j) for j in range(facilities_num) for i in range(market_num)]
y = m.addVars(provide_quantity, lb=0, vtype=MDO.CONTINUOUS)
# 增加约束
# 约束1 已经决定建造的仓库必须满足所有商场的货物需求
m.addConstrs(
(
quicksum(y[(i, j)] for j in range(facilities_num))
== market_info[market_keys[i]]
for i in range(market_num)
),
name="is_satisfy",
)
# 约束2 如果不建仓库,则此仓库位置运送给所有商场的货物为0
m.addConstrs(
(
y[(i, j)] / market_info[market_keys[i]] <= x[j]
for i in range(market_num)
for j in range(facilities_num)
),
name="is_built",
)
# 增加目标函数: 最小化运输费用和建造仓库的费用的总和
# 假设从a地运往b地的运输费用只和距离有关,和货物重量无关
def transportation_fee(pos1, pos2):
x1 = pos1[0] - pos2[0]
x2 = pos1[1] - pos2[1]
return (x1 * x1 + x2 * x2) * transport_fee_per_m
objective1 = quicksum(
x[j] * facilities_info[facilities_keys[j]] for j in range(facilities_num)
)
objective2 = quicksum(
x[j] * transportation_fee(market_keys[i], facilities_keys[j])
for j in range(facilities_num)
for i in range(market_num)
)
m.setObjective(objective1+objective2, MDO.MINIMIZE)
# 开始优化
m.optimize()
# 打印结果
for i in x:
if x[i].X:
print(
"A warehouse should build at No."
+ str(i + 1)
+ " location at "
+ str(facilities_keys[i])
)
for j in range(market_num):
print(
"This warehouse transport "
+ str(y[(j, i)].X)
+ " units of goods to "
+ str(j)
+ "supermarkets"
)
8.7.22.3. 人力分配¶
from mindoptpy import *
# 每天需要的人力数
day_name, workers_per_day = multidict(
{
"Monday": 3,
"Tuesday": 1,
"Wednesday": 4,
"Thursday": 2,
"Friday": 1,
"Saturday": 3,
"Sunday": 3,
}
)
# 每个工人一天的工资
workers, pay = multidict(
{
"Xiaoming": 13,
"Huahua": 10,
"HongHong": 11,
"Dahua": 8,
"Lihua": 9,
"Niuniu": 14,
"Gouzi": 14,
}
)
# 每个工人可以出勤的时间
availability = tuplelist(
[
("Xiaoming", "Tuesday"),
("Xiaoming", "Wednesday"),
("Xiaoming", "Friday"),
("Xiaoming", "Sunday"),
("Huahua", "Monday"),
("Huahua", "Tuesday"),
("Huahua", "Friday"),
("Huahua", "Saturday"),
("HongHong", "Wednesday"),
("HongHong", "Thursday"),
("HongHong", "Friday"),
("HongHong", "Sunday"),
("Dahua", "Tuesday"),
("Dahua", "Wednesday"),
("Dahua", "Friday"),
("Dahua", "Saturday"),
("Lihua", "Monday"),
("Lihua", "Tuesday"),
("Lihua", "Wednesday"),
("Lihua", "Thursday"),
("Lihua", "Friday"),
("Lihua", "Sunday"),
("Niuniu", "Monday"),
("Niuniu", "Tuesday"),
("Niuniu", "Wednesday"),
("Niuniu", "Saturday"),
("Gouzi", "Monday"),
("Gouzi", "Tuesday"),
("Gouzi", "Wednesday"),
("Gouzi", "Friday"),
("Gouzi", "Saturday"),
("Gouzi", "Sunday"),
]
)
# 建立模型
m = Model('WorkForce')
# 添加决策变量
# x[(worker, day)]这个变量代表该工人是否在当天工作
# 用(worker, day)来初始化决策变量,可以保证每个工人只在他们允许的天内出勤
x = m.addVars(availability, vtype=MDO.BINARY, name="schedule")
# 增加约束
# 约束: 满足每天的人力需求
c1 = m.addConstrs((x.sum("*", day) == workers_per_day[day] for day in day_name))
# 增加目标函数
objective = quicksum(
pay[worker_day[0]] * x[(worker_day[0], worker_day[1])]
for worker_day in availability
)
m.setObjective(objective, MDO.MINIMIZE)
# 开始优化
m.optimize()
# 打印结果
for worker, day in availability:
if x[(worker, day)].X:
print(worker + " should work at " + day)
print("The total cost is " + str(objective.getValue()))