• Gurobi使用(一)——操作指南(转自知乎)


    好像还是要学一下Gurobi如何使用的,不然这代码着实有点抽象了

    一、入门操作

    一般来说,求解一个数学规划模型的时候,通常会按照如下步骤解决问题:
    设置变量---addVar()。
    更新变量空间---update()。
    设定目标函数---setObjective()。
    设定约束条件---addConstr()。
    执行最优化---optimize()。

    创建模型:

    1. import gurobipy
    2. model = gurobipy.Model('LP模型测试1') # 创建一个模型

    (1) 设置决策变量

    一次创建一个变量:

    x = model.addVar(lb=0.0, ub=gurobipy.GRB.INFINITY, vtype=gurobipy.GRB.CONTINUOUS, name="")
    • lb=0.0:变量的下界,默认为0.0。 
    • ub=gurobipy.GRB.INFINITY:变量的上界,默认为无穷大。 
    • vtype=gurobipy.GRB.CONTINUOUS:变量的类型,默认为连续型号。变为GRB.BINARY则是0-1变量,变为GRB.INTEGER则为整数变量。 
    • name="":变量名,默认为空。 

    一次创建多个变量:

    x = model.addVars(*indexes, lb=0, ub=gurobipy.GRB.INFINITY, vtype=gurobipy.GRB.CONTINUOUS, name="")

    示例: 

    x = model.addVars(3, 4, 5, vtype=gurobipy.GRB.BINARY, name="C")

    一次性生成3x4x5个变量。x包含了3x4x5个变量,可以通过x[i,j,k]来访问单个的变量。

    (2)更新变量空间

    model.update()

    (3)设定目标函数

    单目标优化

    model.setObjective(expression,sense=None)
    • expression:表达式,可以是一次或者二次函数的类型。 
    • sense:求解类型,GRB.MINIMIZE则为最小值,GRB.MAXMIZE则为最大值。 
    model.setObjective(8 * x1 + 10 * x2 + 7 * x3 + 6 * x4 + 11 * x5 + 9 * x6, gurobipy.GRB.MINIMIZE)

    多目标优化代码:

    model.setObjectiveN(expression, index, priority=0, weight=1.0, abstol=0, reltol=0, name="")
    • expression:表达式,可以是一次或者二次函数类型。 
    • index:目标函数对应的序号(默认0,1,2,...),以index=0作为目标函数的值,其余值需要另外设置参数。 
    • priority:分层序列法多目标决策的优先级,值越大优先级越高。 
    • weight:线性加权多目标决策权重(在优先级相同的时候发挥作用)。 
    • abstol:分层序列法多目标决策时允许的目标函数值的最大降低量。 
    • reltol:分层序列法多目标决策时允许的目标函数值的最大降低比率。

    (4)添加约束条件:

    创建一个约束条件

    model.addConstr(expression, name="")
    • expression: 布尔表达式,可以是一次或二次函数类型
    • name: 约束式的名称 
    model.addConstr(12 * x1 + 9 * x2 + 25 * x3 + 20 * x4 + 17 * x5 + 13 * x6 >= 60, "c0")

    创建多个约束条件

    model.addConstrs(expressions, name="")

    创建一个指示变量约束

    model.addGenConstrIndicator(binvar, binval, expression, name="")

    指示变量 binvar 的值取 binval 时, 进行约束 expression 

    或者 
    方法1: 构造指示变量  ,则上述约束转化为: (M是一个很大的数,可以取1000)
    方法2:转化为二次约束,但是如果矩阵为非正定矩阵,则无法求解:

    (5)执行最优化

    1. model.Params.LogToConsole=True # 显示求解过程
    2. model.Params.MIPGap=0.0001 # 百分比界差
    3. model.Params.TimeLimit=100 # 限制求解时间为 100s
    4. model.Params.Presolve = -1 # 预处理程度, 0关闭,1保守,2激进
    5. model.Params.MIPFocus = 0 # 求解侧重点. 1快速找到可行解, 2证明最有, 3侧重边界提升, 0均衡搜索
    6. model.Params.SolutionLimit = inf # 求解数量, 默认求所有解, 比较出最优的结果, 只需要可行解时可以设置该参数为1
    7. model.Params.NonConvex = 1 # 默认求解器,改为 2 时可以解决非凸二次优化问题
    8. model.optimize()

    (6)查看模型优化结果

    • 查看函数值以及变量值
    1. # 查看单目标规划模型的目标函数值
    2. print("Optimal Objective Value", model.objVal)
    3. # 查看多目标规划模型的目标函数值
    4. for i in range(model.NumObj):
    5. MODEL.setParam(gurobipy.GRB.Param.ObjNumber, i)
    6. print(f"Obj {i+1} = {model.ObjNVal}")
    7. # 查看变量取值
    8. for var in model.getVars():
    9. print(f"{var.varName}: {round(var.X, 3)}")

    (7)辅助函数

    quicksum()
    quicksum相当于sum及其求和符号,效率更高。
    写为: 

    1. for i in I:
    2. model.addConstr(quicksum(x[i,j] for j in J) <= 5)

    此外,它还支持迭代器、生成器协议,也就是说,可以通过下面的代码,实现更为复杂的过滤、求和方法. 

    1. for c in C:
    2. model.addConstr(gurobipy.quicksum(x[d,i,j] for d in D for i in range(0, 24) for j in range(i + 1, 25) if i <= c < j) >= R[c])


     

     

     

  • 相关阅读:
    【Try to Hack】Windows系统账户安全
    c++ 模版的一些注意问题
    RDD的执行原理
    力扣-python-滑动窗口合集
    数据结构和算法的笔记1
    [附源码]Python计算机毕业设计SSM教学团队管理系统(程序+LW)
    汇编层面来理解C语言的值传递和引用传递的区别
    pycharm运行os.system出现�����ڲ����ⲿ���Ҳ���ǿ����еij��� ���������ļ���
    这就是艺术,优雅的二维码生成器「GitHub 热点速览」
    对抗博弈决策方法
  • 原文地址:https://blog.csdn.net/zzrh2018/article/details/132745408