• 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])


     

     

     

  • 相关阅读:
    ue5 小知识点 ue的world type,pie editor game
    H.迷宫,(算法选修)
    Pandas数据分析:处理文本数据(str/object)各类操作+代码一文详解(二)
    VL5 位拆分与运算
    UWB室内定位技术
    第三章 循环
    Dell R720服务器已有win10系统下安装Ubuntu10.04双系统
    MongoDB实验——MongoDB shell操作
    上海亚商投顾: 市场调整分化 两市成交额再创阶段新低
    【C语言】每日一题(旋转数组)
  • 原文地址:https://blog.csdn.net/zzrh2018/article/details/132745408