周四,天气渐渐凉快了下来。
优化求解器之手把手教你申请试用与运行MindOpt求解器.
个人建议:先使用在线版的看一下效果,毕竟本机装环境超麻烦的好吗。
MindOpt 优化求解器-线上版.
例子:这里我们使用官方案例【LP专题-2】营养调配:如何吃少花钱又营养.
MdoModel:用以创建优化模型类对象
类对象所调用的函数介绍:
1、model.add_var(): 向模型引入新变量(列)的函数。参数介绍如下,返回值是创建的变量对象。
2、model.add_cons():向模型引入新约束(行)的函数。
3、 model.solve_prob():
4、 model.get_infinity(): 用于检索无穷大值的函数,返回无穷大的值,返回类型是浮点数。
5、 model.set_int_attr(): 用于更改整数值模型属性的值的函数。
6、 model.set_str_param(): 用于更改字符串值参数的值的函数。
7、model.submit_task(): 此函数将优化模型任务提交到远程服务器进行优化。模型任务文件以二进制格式包含问题数据、参数设置和解决方案。
8、model.retrieve_task(): 该函数检查已提交任务的状态,然后检索相应的优化结果(如果可用)。所有可能的状态值为:“Submitted” “Solving” “Canceled” “Finished” “Failed”
9、model.explain_result():此函数解释求解器结果代码的详细信息。
10、model.explain_status(): 此函数解释求解器状态代码的详细信息。
11、model.display_results(): 显示当前求解器结果的函数。
12、model.get_status(): 用于检索求解器状态的函数。
13、model.get_real_attr():用于检索实值模型属性的值的函数。
MdoExprLinear: 此对象实现数据结构以保存线性约束表达式对象,该对象由一组系数-变量对组成。使用该类的步骤如下:
1、通过使用 model.add_var() 创建一系列变量对象。
2、使用MdoExprLinear()类创建一个空的对象。
3、使用重载运算符(+、-、×、/),或者是使用成员函数MdoExprLinear.add_terms()
官方例子:
MdoVar x1 = model.add_var()
MdoVar x3 = model.add_var()
expr1 = 1 * x1
expr1 = expr1 + x2
MdoVar x3 = model.add_var()
expr2 = expr1 + x3
"""
/**
* example_2_py1.py
* Description
* -----------
*
* Linear optimization (diet problem).
*
* The goal is to select foods that satisfy daily nutritional requirements while minimizing the total cost.
* The constraints in this problem limit the number of calories, the volume of good consumed, and the amount of
* vitamins, protein, carbohydrates, calcium, and iron in the diet.
*
* Note
* ----
*
* The model below will be inputted in a row-wise order.
*
* Formulation
* -----------
*
* Minimize
* Obj: 1.840000000 Cheeseburger + 2.190000000 HamSandwich + 1.840000000 Hamburger + 1.440000000 FishSandwich +
* 2.290000000 ChickenSandwich + 0.770000000 Fries + 1.290000000 SausageBiscuit + 0.600000000 LowfatMilk +
* 0.720000000 OrangeJuice
* Subject To
* Cal: 510 Cheeseburger + 370 HamSandwich + 500 Hamburger + 370 FishSandwich +
* 400 ChickenSandwich + 220 Fries + 345 SausageBiscuit + 110 LowfatMilk + 80 OrangeJuice >= 2000
* Carbo: 34 Cheeseburger + 35 HamSandwich + 42 Hamburger + 38 FishSandwich + 42 ChickenSandwich +
* 26 Fries + 27 SausageBiscuit + 12 LowfatMilk + 20 OrangeJuice <= 375
* Carbo_low: 34 Cheeseburger + 35 HamSandwich + 42 Hamburger + 38 FishSandwich + 42 ChickenSandwich +
* 26 Fries + 27 SausageBiscuit + 12 LowfatMilk + 20 OrangeJuice >= 350
* Protein: 28 Cheeseburger + 24 HamSandwich + 25 Hamburger + 14 FishSandwich + 31 ChickenSandwich +
* 3 Fries + 15 SausageBiscuit + 9 LowfatMilk + OrangeJuice >= 55
* VitA: 15 Cheeseburger + 15 HamSandwich + 6 Hamburger + 2 FishSandwich + 8 ChickenSandwich +
* 4 SausageBiscuit + 10 LowfatMilk + 2 OrangeJuice >= 100
* VitC: 6 Cheeseburger + 10 HamSandwich + 2 Hamburger + 15 ChickenSandwich +
* 15 Fries + 4 LowfatMilk + 120 OrangeJuice >= 100
* Calc: 30 Cheeseburger + 20 HamSandwich + 25 Hamburger + 15 FishSandwich +
* 15 ChickenSandwich + 20 SausageBiscuit + 30 LowfatMilk + 2 OrangeJuice >= 100
* Iron: 20 Cheeseburger + 20 HamSandwich + 20 Hamburger + 10 FishSandwich +
* 8 ChickenSandwich + 2 Fries + 15 SausageBiscuit + 2 OrangeJuice >= 100
* Volume: 4 Cheeseburger + 7.500000000 HamSandwich + 3.500000000 Hamburger + 5 FishSandwich +
* 7.300000000 ChickenSandwich + 2.600000000 Fries + 4.100000000 SausageBiscuit + 8 LowfatMilk + 12 OrangeJuice <= 75
* Bounds
* End
*/
"""
from mindoptpy import *
if __name__ == "__main__":
MDO_INFINITY = MdoModel.get_infinity()
token = "**********"
server = "mindopt.tianchi.aliyun.com"
desc = "tianchi example2 MdoRemotLdDiet PY1"
filepath = "./tmp/"
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
}
# Step 1. Create a model and change the parameters.
model = MdoModel()
try:
# Step 2. Input model.
# Change to minimization problem.
model.set_int_attr("MinSense", 1)
# Add variables.
var = {}
for food_name, food_data in food.items():
var[food_name] = model.add_var(food_data[0], food_data[1], food_data[2], None, food_name, False)
# Add constraints.
for req_name, req_data in req.items():
expr = MdoExprLinear()
for food_name in food.keys():
expr += req_value[req_name, food_name] * var[food_name]
model.add_cons(req_data[0], req_data[1], expr, req_name)
# Step 3. Input parameters related to the remote computing server.
model.set_str_param("Remote/Token", token)
model.set_str_param("Remote/Desc", desc)
model.set_str_param("Remote/Server", server)
model.set_str_param("Remote/File/Path", filepath)
# Step 4. Upload the serialized model and parameters to server, and then optimize the model.
job_id = model.submit_task()
if job_id == "":
print("ERROR: Empty job ID.")
raise MdoError(-1)
else:
print("Job was submitted to server successfully.")
print("User may query the optimization result with the following job ID: {}".format(job_id))
# Step 5. Check the solution status periodically, and
# download the its upon availability.
status = "Submitted"
while status == 'Submitted' or status == 'Solving':
status, model_status, result, has_soln = model.retrieve_task(job_id)
# Sleep for 10 seconds.
time.sleep(10)
model_status_details = model.explain_status(model_status)
result_details = model.explain_result(result)
print(" - Job status : {}".format(status))
print(" - Model status : {0} ({1})".format(model_status_details, model_status))
print(" - Optimization status : {0} ({1})".format(result_details, result))
print(" - Solution availability : {0}".format("available" if has_soln else "not available"))
if has_soln:
print("\nPopulating solution.")
model.display_results()
status_code, status_msg = model.get_status()
if status_msg == "OPTIMAL":
print("Optimizer terminated with an OPTIMAL status (code {0}).".format(status_code))
print("Daily cost : ${0}".format(round(model.get_real_attr("PrimalObjVal"), 2)))
for food_name, food_var in var.items():
val = round(food_var.get_real_attr("PrimalSoln"), 2)
if val > 0.01:
print(f" - {food_name: <17} : {val}")
else:
print("Optimizer terminated with a(n) {0} status (code {1}).".format(status_msg, status_code))
except MdoError as e:
print("Received Mindopt exception.")
print(" - Code : {}".format(e.code))
print(" - Reason : {}".format(e.message))
except Exception as e:
print("Received exception.")
print(" - Reason : {}".format(e))
finally:
pass
参考文章:
MindOpt 优化求解器-线上版.
MindOpt 官方文档.
yeah,快下班了!