找回密码
 立即注册
查看: 339|回复: 0

优化 | 手把手教你用Python调用SCIP求解最优化模型

[复制链接]
发表于 2022-10-8 16:10 | 显示全部楼层 |阅读模式
作者:刘兴禄,清华大学,清华伯克利深圳学院博士在读
编辑:张瑞三,四川大学,硕士在读,知乎ID:MunSum3
<hr/>关于Python调用SCIP时,SCIP的安装与配置,请查看往期文章:
这一期我们来介绍使用Python调用SCIP完成建模和求解,以及解的输出等。
一个简单的例子

我们用SCIP给出的官方案例作为引入,先让大家大致看一下Python调用SCIP求解最优化模型的大题流程。
我们以最经典的对称旅行商问题(asymmetric traveling salesman problem, ATSP)为例。其具体模型为
\begin{aligned} \min\text{ }\sum_i{\sum_j{c_{ij}x_{ij}}} \\ \sum_{i\in V}{x_{ij}}=\text{1,  }   &  \hspace{1cm}\forall j\in V,i\ne j \\ \sum_{j\in V}{x_{ij}}=\text{1,  }  &  \hspace{1cm}\forall i\in V,i\ne j \\ \mu _i-\mu _j+Nx_{ij}\leqslant N-\text{1,  }  &  \hspace{1cm}\forall i,j\in V,i,j\ne \text{0,}i\ne j   \\ x_{ij}\in \left\{ \text{0,}1 \right\} ,  \mu _i\geqslant \text{0, }\mu _i\in \mathbf{R}^1 &\hspace{1cm}\forall i\in V \end{aligned}  
关于TSP更为细致的介绍,请参照我的另外一篇文章
https://blog.csdn.net/HsinglukLiu/article/details/107848461
运筹学修炼日记:TSP中两种不同消除子环路的方法及callback实现(Python调用Gurobi求解,附以王者荣耀视角解读callback的工作逻辑)
Python调用SCIP求解ATSP的具体代码如下。
##@file atsp.py
#@brief solve the asymmetric traveling salesman problem

"""
formulations implemented:
    - mtz -- Miller-Tucker-Zemlin's potential formulation
Copyright (c) by Joao Pedro PEDROSO and Mikio KUBO, 2012
"""
from pyscipopt import Model, quicksum, multidict

def mtz(n,c):
    """mtz: Miller-Tucker-Zemlin's model for the (asymmetric) traveling salesman problem
    (potential formulation)
    Parameters:
        - n: number of nodes
        - c[i,j]: cost for traversing arc (i,j)
    Returns a model, ready to be solved.
    """

    model = Model("atsp - mtz")

    x,u = {},{}
    for i in range(1,n+1):
        u = model.addVar(lb=0, ub=n-1, vtype="C", name="u(%s)"%i)
        for j in range(1,n+1):
            if i != j:
                x[i,j] = model.addVar(vtype="B", name="x(%s,%s)"%(i,j))

    for i in range(1,n+1):
        model.addCons(quicksum(x[i,j] for j in range(1,n+1) if j != i) == 1, "Out(%s)"%i)
        model.addCons(quicksum(x[j,i] for j in range(1,n+1) if j != i) == 1, "In(%s)"%i)

    for i in range(1,n+1):
        for j in range(2,n+1):
            if i != j:
                model.addCons(u - u[j] + (n-1)*x[i,j] <= n-2, "MTZ(%s,%s)"%(i,j))

    model.setObjective(quicksum(c[i,j]*x[i,j] for (i,j) in x), "minimize")

    model.data = x,u
    return model


def sequence(arcs):
    """sequence: make a list of cities to visit, from set of arcs"""
    succ = {}
    for (i,j) in arcs:
        succ = j
    curr = 1    # first node being visited
    sol = [curr]
    for i in range(len(arcs)-2):
        curr = succ[curr]
        sol.append(curr)
    return sol


if __name__ == "__main__":
    n = 5
    c = { (1,1):0,  (1,2):1989,  (1,3):102, (1,4):102, (1,5):103,
          (2,1):104, (2,2):0,  (2,3):11,  (2,4):104, (2,5):108,
          (3,1):107, (3,2):108, (3,3):0,  (3,4):19,  (3,5):102,
          (4,1):109, (4,2):102, (4,3):107, (4,4):0,  (4,5):15,
          (5,1):13,  (5,2):103, (5,3):104, (5,4):101, (5,5):0,
         }

    model = mtz(n,c)
    model.hideOutput() # silent mode
    model.optimize()
    cost = model.getObjVal()
    print()
    print("Miller-Tucker-Zemlin's model:")
    print("Optimal value:", cost)
    #model.printAttr("X")
    for v in model.getVars():
        if model.getVal(v) > 0.001:
            print(v.name, "=", model.getVal(v))

    x,u = model.data
    sol = [i for (p,i) in sorted([(int(model.getVal(u)+.5),i) for i in range(1,n+1)])]
    print(sol)
    arcs = [(i,j) for (i,j) in x if model.getVal(x[i,j]) > .5]
    sol = sequence(arcs)
    print(sol)运行结果为
Miller-Tucker-Zemlin's model:
Optimal value: 330.0
x(1,4) = 1.0
x(2,3) = 1.0
x(3,5) = 1.0
x(4,2) = 1.0
x(5,1) = 1.0
u(5) = 4.0
u(2) = 2.0
u(3) = 3.0
u(4) = 1.0

[1, 4, 2, 3, 5]
[1, 4, 2, 3]接下来我们来详细介绍具体的用法。
Python调用SCIP求解最优化模型的一般步骤

使用Python调用SCIP求解最优化模型的一般步骤一般分为

  • 创建模型对象: pyscipopt.scip.Model(modelname)
  • 创建决策变量:addVar(name='', vtype='C', lb=0.0, ub=None, obj=0.0, priceVar=False)
  • 创建目标函数:pyscipopt.scip.Model.setObjective(coeffs, sense='minimize', clear='true)
  • 创建约束条件:addCons()、addConsAnd()、addConsOr()、addConsXor() 等
  • 求解模型:model.optimize()
  • 获得解的信息并输出:model.getBestSol()、model.getObjVal()、model.getVal(z)等。
接下来我们来逐步介绍。
创建模型对象

调用过程中,所有的组成部分,包括决策变量,约束等,都是存储在一个模型对象中的,也就是一个pyscipopt.scip.Model类的对象。需要用到的函数为

  • pyscipopt.scip.Model(modelname) : creat and return a pyscipopt.scip.Model object
下面举一个例子
from pyscipopt import Model
model = Model("puzzle")创建决策变量

创建决策变量,一般用函数

  • addVar(name='', vtype='C', lb=0.0, ub=None, obj=0.0, priceVar=False)
其中各个参数的详细解读如下:



在这里插入图片描述

下面我们给出几个例子
from pyscipopt import Model
model = Model()

# Create decision variables : example
x = model.addVar(vtype="I", name="octopusses")
y = model.addVar(vtype="I", name="turtles")
z = model.addVar(vtype="I", name="cranes")如果是较多的变量,我们可以用字典进行存储,比如上面的ATSP的例子。
x,u = {},{}
for i in range(1,n+1):
    u = model.addVar(lb=0, ub=n-1, vtype="C", name="u(%s)"%i)
    for j in range(1,n+1):
        if i != j:
            x[i,j] = model.addVar(vtype="B", name="x(%s,%s)"%(i,j))之后,如果我们想提取变量的名字等信息,可以使用

  • var.name



图1-提取变量的名字等信息

设置目标函数

设置目标函数,一般使用函数

  • pyscipopt.scip.Model.setObjective(coeffs, sense='minimize', clear='true)
具体的参数解释如下



图2-目标函数参数

可以看下面的例子
model.setObjective(x + y)如果是比较复杂的目标函数,就可以使用创建表达式的全局函数quicksum()来完成。
比如下面的目标函数
\begin{aligned} \min\text{ }\sum_{i=1}^{5}{c_{i}x_{i}} \end{aligned}  
具体代码如下
model = Model()
c = [1, 2, 3, 4, 5]
x = {}
for i in range(len(c)):
    x = model.addVar(vtype="I", name="x" + str(i))

# set objective function by quicksum function
model.setObjective(
        quicksum(c*x for i in range(len(c))),
        "minimize")创建完目标函数以后,可以查看目标函数的一些属性,比如

  • 查看目标函数的sense,也就是 \max 还是 \min
  • model.getObjectiveSense()
  • model.setMaximize: 直接设置模型的sense为 \max
创建约束

创建约束的函数主要是:addCons()、addConsAnd()、addConsOr()、addConsXor() 等



图3-创建约束1



图4-创建约束2

创建一般约束

比如,想要加入下面的约束
\begin{aligned} \sum_{i=1}^{5}{c_{i}x_{i}} \leqslant 10  \end{aligned}  
则代码如下
model.addCons(quicksum(x for i in range(len(c))) <= 10, "Width")更为复杂的情况,可以见下面的例子
\begin{aligned} \min\text{ }\sum_i{\sum_j{c_{ij}x_{ij}}} \\ \sum_{i\in V}{x_{ij}}=\text{1,  }   &  \hspace{1cm}\forall j\in V,i\ne j \\ \sum_{j\in V}{x_{ij}}=\text{1,  }  &  \hspace{1cm}\forall i\in V,i\ne j \\ \mu _i-\mu _j+Nx_{ij}\leqslant N-\text{1,  }  &  \hspace{1cm}\forall i,j\in V,i,j\ne \text{0,}i\ne j   \\ x_{ij}\in \left\{ \text{0,}1 \right\} ,  \mu _i\geqslant \text{0, }\mu _i\in \mathbf{R}^1 &\hspace{1cm}\forall i\in V \end{aligned}  
# 一些例子
model = Model("atsp - mtz")

x,u = {},{}
for i in range(1,n+1):
    u = model.addVar(lb=0, ub=n-1, vtype="C", name="u(%s)"%i)
    for j in range(1,n+1):
        if i != j:
            x[i,j] = model.addVar(vtype="B", name="x(%s,%s)"%(i,j))

for i in range(1,n+1):
    model.addCons(quicksum(x[i,j] for j in range(1,n+1) if j != i) == 1, "Out(%s)"%i)
    model.addCons(quicksum(x[j,i] for j in range(1,n+1) if j != i) == 1, "In(%s)"%i)

for i in range(1,n+1):
    for j in range(2,n+1):
        if i != j:
            model.addCons(u - u[j] + (n-1)*x[i,j] <= n-2, "MTZ(%s,%s)"%(i,j))创建广义约束

这里的广义约束就指逻辑约束等。比如And, Or等。 具体函数为

  • model.addConsAnd([x,y,z], r): 表示, 当 x=y=z=1 时, r=1 ; 否则 r=0 ;
  • model.addConsOr([x,y,z], r) 表示, 当 x=1 \text{ or } y=1  \text{ or }  z=1 时, r=1 ; 否则 r=0 ;
  • model.addConsXor([x,y,z], r):表示异或



图5-添加广义约束

下面是SCIP给出的例子
##@file tutorial/logical.py
#@brief Tutorial example on how to use AND/OR/XOR constraints.
"""
N.B.: standard SCIP XOR constraint works differently from AND/OR by design.
The constraint is set with a boolean rhs instead of an integer resultant.
cf. http://listserv.zib.de/pipermail/scip/2018-May/003392.html
A workaround to get the resultant as variable is here proposed.
Public Domain, WTFNMFPL Public Licence
"""
from pyscipopt import Model
from pyscipopt import quicksum

def _init():
    model = Model()
    model.hideOutput()
    x = model.addVar("x","B")
    y = model.addVar("y","B")
    z = model.addVar("z","B")
    return model, x, y, z

def _optimize(name, m):
    m.optimize()
    print("* %s constraint *" % name)
    objSet = bool(m.getObjective().terms.keys())
    print("* Is objective set? %s" % objSet)
    if objSet:
        print("* Sense: %s" % m.getObjectiveSense())
    status = m.getStatus()
    print("* Model status: %s" % status)
    if status == 'optimal':
        for v in m.getVars():
            if v.name != "n":
                print("%s: %d" % (v, round(m.getVal(v))))
    else:
        print("* No variable is printed if model status is not optimal")
    print("")

def and_constraint(v=1, sense="minimize"):
    """ AND constraint """
    assert v in [0,1], "v must be 0 or 1 instead of %s" % v.__repr__()
    model, x, y, z = _init()
    r = model.addVar("r", "B")
    model.addConsAnd([x,y,z], r)
    model.addCons(x==v)
    model.setObjective(r, sense=sense)
    _optimize("AND", model)


def or_constraint(v=0, sense="maximize"):
    """ OR constraint"""
    assert v in [0,1], "v must be 0 or 1 instead of %s" % v.__repr__()
    model, x, y, z = _init()
    r = model.addVar("r", "B")
    model.addConsOr([x,y,z], r)
    model.addCons(x==v)
    model.setObjective(r, sense=sense)
    _optimize("OR", model)

def xors_constraint(v=1):
    """ XOR (r as boolean) standard constraint"""
    assert v in [0,1], "v must be 0 or 1 instead of %s" % v.__repr__()
    model, x, y, z = _init()
    r = True   
    model.addConsXor([x,y,z], r)
    model.addCons(x==v)
#     print('v=', v)  
    _optimize("Standard XOR (as boolean)", model)

def xorc_constraint(v=0, sense="maximize"):
    """ XOR (r as variable) custom constraint"""
    assert v in [0,1], "v must be 0 or 1 instead of %s" % v.__repr__()
    model, x, y, z = _init()
    r = model.addVar("r", "B")
    n = model.addVar("n", "I") # auxiliary
    model.addCons(r+quicksum([x,y,z]) == 2*n)
    model.addCons(x==v)
    model.setObjective(r, sense=sense)
    _optimize("Custom XOR (as variable)", model)

if __name__ == "__main__":
    and_constraint()  
    or_constraint()
    xors_constraint()
    xorc_constraint()运行结果如下
* AND constraint *
* Is objective set? True
* Sense: minimize
* Model status: optimal
x: 1
y: 0
z: 0
r: 0

* OR constraint *
* Is objective set? True
* Sense: maximize
* Model status: optimal
x: 0
y: 1
z: 1
r: 1

* Standard XOR (as boolean) constraint *
* Is objective set? False
* Model status: optimal
x: 1
y: 1
z: 1

* Custom XOR (as variable) constraint *
* Is objective set? True
* Sense: maximize
* Model status: optimal
x: 0
y: 1
z: 0
r: 1还有addGenConsIndicator()也是类似的用法,例如加入指示约束,

  • 如果 y=1 ,则 x+2y = 1
这样的约束就可以使用addGenConsIndicator()完成。
注意:SCIP似乎没有experssion的对象,也就是没有linear expression等的表达式对象,因此在添加约束的时候,也不能使用addTerms等的操作,只能通过quicksum拼凑表达式。
但是在Column Generation的时候,按列建模的时候,是可以使用addTerms的。
例如
# add new column to the master problem
        col = Column()
        for i in range(m):
            if t[K] > 0:
                col.addTerms(t[K], orders)
        x[K] = master.addVar(obj=1, vtype="I", name="x(%s)"%K, column=col)说实话,这一点有一些些不太方便。
求解模型

求解模型非常简单,直接model.optimize()就可以,但是有几个涉及到的相关函数需要注意一下

  • model.hideOutput(quiet = False) # silent mode : 关闭log信息
  • model.optimize():求解模型
model.hideOutput(quiet = False) # silent mode
model.optimize()当然,求解之前,还可以对模型进行松弛等。

  • relax = model.relax():就是获得model的LP relaxation
获得解的信息

相关函数如下

  • model.getObjVal(): 获得最优解对应的目标函数值
  • model.getBestSol() :获得最好解
  • model.getVal(x) :获得最优解中 x 的取值
例如
sol = model.getBestSol()
print("x: {}".format(sol[x]))
print("y: {}".format(sol[y]))运行结果
x: 0.0
y: 0.0再比如
print("Optimal value:", model.getObjVal())
print((x.name, y.name), " = ", (model.getVal(x), model.getVal(y)))运行结果
Optimal value: 0.0
('x', 'y')  =  (0.0, 0.0)至此,Python(pyscipopt)调用SCIP求解最优化模型的一套流程就结束了,大家可以开开心心的调用了。
当然,很多小伙伴也许还会有些其他需求,见下文。
一些其他常用函数


  • model.chgLhs():改变约束的左端项
model.chgLhs(Constraint cons, lhs)
-----------------------------
Docstring:
Change left hand side value of a constraint.

:param Constraint cons: linear or quadratic constraint
:param lhs: new left hand side (set to None for -infinity)
Type:      builtin_function_or_method

  • model.chgRhs():改变约束的右端项
model.chgRhs(Constraint cons, rhs)
-----------------------------
Docstring:
Change left hand side value of a constraint.

:param Constraint cons: linear or quadratic constraint
:param lhs: new left hand side (set to None for -infinity)
Type:      builtin_function_or_method

  • model.chgVarLb():改变决策变量的下界
model.chgRhs(Variable var, lb)
-----------------------------
Docstring:
Changes the lower bound of the specified variable.

:param Variable var: variable to change bound of
:param lb: new lower bound (set to None for -infinity)
Type:      builtin_function_or_method

  • model.chgVarUb():改变决策变量的上界
model.chgVarUb(Variable var, ub)
-----------------------------
Docstring:
Changes the upper bound of the specified variable.

:param Variable var: variable to change bound of
:param ub: new upper bound (set to None for +infinity)
Type:      builtin_function_or_method

  • model.chgVarType():改变决策变量的类型
model.chgVarType(Variable var, vtype)
-----------------------------
Docstring:
Changes the type of a variable

:param Variable var: variable to change type of
:param vtype: new variable type
Type:      builtin_function_or_method

  • model.writeLP('Lp.lp'):将模型导出
  • model.delCons(Constraint cons):删除约束
  • model.delVar(var):删除一个决策变量
  • model.getGap(): 获得当前模型的Gap, Docstring: Retrieve the gap, i.e. |(primalbound - dualbound)/min(|primalbound|,|dualbound|)|.
  • model.getLhs(Constraint cons):获得约束的左端项
  • model.getRhs(Constraint cons):获得约束的右端项
  • model.getObjective():Retrieve objective function as Expr
  • model.getObjVal():Retrieve the objective value of value of best solution.
  • model.getStatus(): Retrieve solution status. 可能为optimal
  • model.setParams(): Sets multiple parameters at once. :param params: dict mapping parameter names to their values.
  • model.getNConss(): Retrieve the number of constraints.
  • model.getNVars(): Retrieve number of variables in the problems
  • model.getNVars(): Retrieve number of variables in the problems
  • model.getDualMultiplier(Constraint cons):  Retrieve the dual solution to a linear constraint.
这些函数,大概可以满足大部分的需求了。
今天就介绍到这里,下一期再见。
<hr/>
参考文献: [1] Gerald Gamrath, Daniel Anderson, Ksenia Bestuzheva, Wei-Kun Chen, Leon Eifler, Maxime Gasse, Patrick Gemander, Ambros Gleixner, Leona Gottwald, Katrin Halbig, Gregor Hendel, Christopher Hojny, Thorsten Koch, Pierre Le Bodic, Stephen J. Maher, Frederic Matter, Matthias Miltenberger, Erik Mühmer, Benjamin Müller, Marc Pfetsch, Franziska Schlsser, Felipe Serrano, Yuji Shinano, Christine Tawfik, Stefan Vigerske, Fabian Wegscheider, Dieter Weninger, Jakob Witzig Available at Optimization Online and as ZIB-Report 20-10, March 2020
<hr/>关注我们运小筹公众号
运小筹公众号致力于分享运筹优化(LP、MIP、NLP、随机规划、鲁棒优化)、凸优化、强化学习等研究领域的内容以及涉及到的算法的代码实现。编程语言和工具包括Java、Python、Matlab、CPLEX、Gurobi、SCIP 等。欢迎广大同行投稿!欢迎大家关注我们的公众号“运小筹”以及粉丝群!
如果群满加不进去,可以加本文作者微信,然后备注姓名+机构+专业,然后拉您入群。
<hr/>往期推文合集

第112篇:优化 | 分支定界算法案例实战:Python调用COPT实现
第111篇:优化 | 五个经典设施选址模型的详解及其实践:Python调用Gurobi实现
第110篇:始于初心,回馈教育:运筹与智能决策教学平台——杉数CORIDM全新升级上线!
第109篇:求解器COPT实践详解丨数学规划视角下的分货优化解题思路
第108篇:论文代码复现 | 考虑客户位置移动的车辆路径规划问题:MIP模型详解及Java调用CPLEX求解的完整代码
第107篇:求解器COPT实践丨地铁乘务排班问题如何优化求解
第106篇:优化求解器 | 求解器加速的高级技能包:MIP模型初始解设置相关操作的超详细解读
第105篇:OR Talk Pool:【8月26日-9月3日】近期讲座、课程和研讨会
第104篇:OR Talk Pool:【8月17日-8月31日】近期研讨会、论坛和培训
第103篇:进展 | 清华大学SIGS戚铭尧及其合作者在顶级期刊Operations Research上发表竞争性设施选址问题的最新研究进展
第102篇:启发式算法和优化算法设计及调试技巧 | AIRS in the AIR“运筹优化”系列讲座
第101篇:OR Talk Pool【8月9日-8月31号】:近期研讨会、论坛和培训
第100篇:理论算法与精确算法 | AIRS in the AIR”运筹优化“系列讲座
第99篇:OR Talk Pool【7月27日-8月】:近期研讨会、论坛和培训
第98篇:优化求解器|Solution Pool用法的超详细解读(Gurobi):最优解与多个可行解的获取与分析(案例与代码实现)
第97篇:新书推荐《整数规划:模型、应用及求解》
第96篇:OR Talk Pool【7月6日-7月13日】:近期研讨会、论坛和培训
第95篇:从大规模的复杂应用,来解析杉数求解器的硬核能力
第94篇:优化 | 手把手教你用C++调用Gurobi求解CVRP:环境配置、数学模型及完整代码
第93篇:OR Talk Pool:近期研讨会、暑期学校和学术报告推荐
第92篇:优化求解器 | Gurobi的MVar类:矩阵建模利器、求解对偶问题的备选方案 (附详细案例+代码)
第91篇:【求解器】Gurobi中非线性约束的对偶值的获取:QCP、QCQP、SOCP | 以及求解器最优性理论证明
第90篇:优化 | 二部图最大匹配问题的精确算法详解(HK算法和匈牙利算法):一份让您满意的【理论介绍+代码实现】学习笔记
第89篇:优化算法 | Benders Decomposition: 一份让你满意的【入门-编程实战-深入理解】的学习笔记
第88篇:优化 | 史上最【皮】数学题求解的新尝试:一种求解器的视角 (Python调用Gurobi实现)
第87篇:优化 | 寻找新的建模视角——从直观解释对偶问题入手:以Cutting Stock Problem的对偶问题为例
第86篇:ORers‘ Bling Chat【03】 | 【高光聊天记录集锦】:运小筹读者群里那些热烈的讨论
第85篇:非线性优化 | 非线性问题线性化以及求解的详细案例及Python+Gurobi求解
第84篇:ORers' Bling Chat | 【高光聊天记录集锦-02】:运小筹读者群里那些热烈的讨论
第83篇:Machine-Learning–Based Column Selection for Column Generation
第82篇:最新!205页运小筹优化理论学习笔记发布(2021年9月--2022年3月)!
第81篇:【鲁棒优化】| 补充证明:为什么最优解一定满足取值等于绝对值(论文笔记:The Price of Robustness)
第80篇:【鲁棒优化】| 论文笔记:The Price of Robustness - 列不确定性模型部分的推导和一些思考
第79篇:ORers' Bling Chat | 【高光聊天记录集锦-01】:运小筹读者群里那些热烈的讨论
第78篇:优化| 手把手教你学会杉数求解器(COPT)的安装、配置与测试
第77篇:【教学视频】优化 | 线性化(2):连续变量 * 0-1变量的线性化
第76篇:【教学视频】优化 | 线性化:两个0-1变量相乘的线性化
第75篇:强化学习实战 | DQN和Double DQN保姆级教程:以Cart-Pole为例
第74篇:强化学习| 概念梳理:强化学习、马尔科夫决策过程与动态规划
第73篇:强化学习实战 | Q-learning求解最短路(SPP)问题
第72篇:鲁棒优化 | 以Coding入门鲁棒优化:以一个例子引入(二)
第71篇:鲁棒优化|基于ROME编程入门鲁棒优化:以一个例子引入(一)
第70篇:优化|含分式的非线性规划求解: 基于Outer Approximation的Branch-and-cut 算法及其Java实现
第69篇:科研工具 | 手把手教你玩转文献管理神器:Endnote
第68篇:相约深圳 | 2022 INFORMS 服务科学国际会议·征稿通知
第67篇:鲁棒优化| 利用rome求解鲁棒优化简单案例:以CVaR不确定性集为例
第66篇:机器学习 | 交通流特征工程小技巧和思考
第65篇:最新!145页运小筹优化理论学习笔记发布(2021年4月--9月)!
第64篇:优化 | 手把手教你用Python调用SCIP求解最优化模型
第63篇:优化 | 随机规划案例:The value of the stochastic solution
第62篇:工具 | draw.io: 科研流程示意图必备大杀器
第61篇:优化 | 开源求解器SCIP的安装与入门教程(Windows+Python)
第60篇:优化|Gurobi处理非线性目标函数和约束的详细案例
第59篇:让出租车更“懂”您的出行
第58篇:测试算例下载:《运筹优化常用模型、算法及案例实战:代码手册》
第57篇:鲁棒优化|分布式鲁棒优化转化为SOCP案例及代码实现(Python+RSOME)
第56篇:鲁棒优化 | 分布式鲁棒优化简单案例及实战(RSOME+Gurobi)
第55篇:【尾款+发货】|【代码手册】 《运筹优化常用模型、算法及案例实战:Python+Java
第54篇:深度强化学习之:PPO训练红白机1942
第53篇:简单装配线平衡问题
第52篇:【视频讲解】CPLEX的OPL语言:可视化的优化模型求解解决方案
第51篇:算法 | 基于英雄联盟寻路背景的A星算法及python实现
第50篇:【转发】清华大学深圳国际研究生院2021年物流工程与管理项目优秀大学生夏令营报名通知
第49篇:优化 | 精确算法之分支定界介绍和实现(附Python代码)
第48篇:【顶刊论文速递】综述:服务科学视角下的金融科技
第47篇:【重新发布】|《运筹优化常用模型、算法及案例实战:Python+Java实现》 【代码手册】 开始预购啦!!!
第46篇:智慧交通可视化:手把手教你用Python做出行数据可视化-osmnx 包入门教程
第45篇:优化 | Pick and delivery problem的介绍与建模实现(二)
第44篇:推一个知乎学弱猹的公众号
第43篇:元启发式算法 | 遗传算法(GA)解决TSP问题(Python实现)
第42篇:优化|视频详解Python调用Gurobi的应用案例:TSP
第41篇:最新!213页运小筹优化理论系列笔记发布!
第40篇:运小筹第四期月刊发布!
第39篇:开源交通仿真平台SimMobility的安装教程
第38篇:浅谈 | P问题、NP问题、NPC问题、NP-Hard问题
第37篇:一份掏心掏肺的信息素养笔记分享
第36篇:强化学习|Q-learning (王者荣耀视角)
第35篇:优化|高级建模方法(Gurobi):线性化表达小技巧
第34篇:深度强化学习介绍 | Deep Q Network——理论与代码实现
第33篇:优化 | 列生成算法及Java调用cplex实现
第32篇:优化 | Pick and delivery problem的简介与建模实现(一)
第31篇:最新!运小筹月刊-1月份发布!
第30篇:“Learn to Improve”(L2I):ICLR文章分享 | 运用RL解决VRP问题
第29篇:线性规划求解小程序 | 基于Python 的Cplex 求解器图形化界面
第28篇:运筹学与管理科学TOP期刊揭秘 —TR系列
第27篇:Julia安装与配置Jupyter Notebook
第26篇:期刊征文| IEEE TRANSACTIONS应对COVID-19的特刊征文消息速递
第25篇:两阶段随机规划(Two-stage Stochastic Programming):一个详细的例子
第24篇:最新!运小筹月刊-12月份发布!
第23篇:Python调用Gurobi:Assignment Problem简单案例
第22篇:初识随机规划:一个小小例子
第21篇:机器学习运用到VRP的若干小知识
第20篇:运筹学与管理科学TOP期刊揭秘 —Service Science
第19篇:手把手教你用Python实现Dijkstra算法(伪代码+Python实现)
第18篇:运筹学与管理科学大揭秘—TOP期刊主编及研究方向一览
第17篇:优化 | 手把手教你用Python实现动态规划Labeling算法求解SPPRC问题
第16篇:代码 | 运小筹GitHub项目上线啦,快来标星收藏吧!!
第15篇:最新!运小筹月刊首次发布!
第14篇:优化| 手把手教你用Python实现Dijkstra算法(附Python代码和可视化)
第13篇:优化|手把手教你用Python调用Gurobi求解最短路问题
第12篇:优化| 手把手教你用Java实现单纯形法
第11篇:优化| 手把手教你用Python调用Gurobi求解VRPTW
第10篇:优化 | 两阶段启发式算法求解带时间窗车辆路径问题(附Java代码)
第9篇:Java调用cplex求解运输问题
第8篇:优化 | 如何优雅地写出大规模线性规划的对偶
第7篇:优化 | TSP中两种不同消除子环路的方法及Callback实现(Python调用Gurobi求解)
第6篇:元启发式算法 | 禁忌搜索(Tabu Search)解决TSP问题(Python代码实现)
第5篇:论文代码复现 | 无人机与卡车联合配送(Python+Gurobi)
第4篇:优化|Shortest Path Problem及其对偶问题的一些探讨(附Python调用Gurobi实现)
第3篇:可视化|Python+OpenStreetMap的交通数据可视化(二):OpenStreetMap+Python画城市交通路网图
第2篇:优化|最速下降法:详细案例+Python实现
第1篇:Python+networkX+OpenStreetMap实现交通数据可视化(一):用OpenStreetMap下载地图数据
<hr/>作者:刘兴禄,清华大学,清华大学深圳国际研究生院,清华-伯克利深圳学院,博士在读
编辑:张瑞三,四川大学硕士在读,知乎账号:MunSum3
编辑于 2022-10-01 国庆节快乐!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-15 10:07 , Processed in 0.094791 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表