IT圈老男孩1 发表于 2022-3-31 19:18

鲁棒优化 | 以Coding入门鲁棒优化:以一个例子引入(二)

作者:刘兴禄, 清华大学,清华-伯克利深圳学院,博士在读 邮箱:hsinglul@163.com
1.投资组合的例子

上一篇我们介绍了一个鲁棒优化求解投资组合的例子,文章链接为:
其中,该例子的Robust Counterpart模型如下:
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%5Cunderset%7Bx%5Cin+%5Cmathbb%7BR%7D%5En%7D%7B%5Cmax%7D%5Cquad%5Cunderset%7Bz%5Cin+%5Cmathcal%7BZ%7D%7D%7B%5Cmin%7D+%5Cqquad+%26%5Csum_%7Bi%3D1%7D%5En%7B%5Cleft%28+%5Cmu+_i%2B%5Csigma+_iz_i+%5Cright%29+x_i%7D%26%26+%5C%5C+%26%5Csum_%7Bi%3D1%7D%5En%7Bx_i%7D%3D100%5C%25%26%26+%5C%5C+%26x_i%5Cgeqslant+0%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C2%2C%5Ccdots+%2Cn+%5Cend%7Baligned%7D
其中, https://www.zhihu.com/equation?tex=%5Cmathcal%7BZ%7D+%3D+%7Bz%7C%5Csum_%7Bi%3D1%7D%5En%7B%7Cz_i%7C%7D%5Cleqslant+%5CGamma%2C+z_i%5Cin+%5Cleft%5B+-1%2C1+%5Cright%5D+%2C%5Cforall+i%3D1%2C%5Ccdots+%2Cn%7D%E3%80%82
该例中,我们采用了预算不确定集(Budgeted uncertainty set)。
我们也在上一篇文章中提到,求解鲁棒优化模型的两大类方法:
1. 将鲁棒优化模型重构(reformulate)为一阶段线性规划,然后直接调用求解器求解;
2. 直接使用鲁棒优化求解器(ROME, RSOME等)建模求解。其中,第2类方法,我们已经在器上一篇文章中做了详细解释,本文我们来介绍第一类求解方法:reformulation。
reformulation又分为很多种,本文仅仅介绍两种:

[*]利用对偶进行reformulation
[*]利用上镜图(epigraph)进行reformulation
两种方法在操作上都需要对偶,有很多类似之处,但是思想却是不同的。
2.鲁棒优化模型的reformulation: 利用对偶进行reformulation

2.1利用对偶进行reformulation

上述模型其实是一个bi-level的模型,也就是 https://www.zhihu.com/equation?tex=%5Cunderset%7Bx%7D%7B%5Cmax%7D+%5C%2C%5C%2C%5Cunderset%7Bz%7D%7B%5Cmin%7D 。上述鲁棒优化模型可以在一定程度上理解为是一个赌场博弈问题(只是为了方便理解,并不一定严谨):

[*]inner level或lower level的决策:不确定变量,可以看做是赌场的庄家,庄家不想让玩家赚钱,所以他控制收益 https://www.zhihu.com/equation?tex=%5Ctilde%7Br%7D 波动(也就是控制风险),尽可能让你赚的少(可以理解为给你制造worst case)
[*]outer level或upper level的决策:投资决策。作为玩家,我们需要跟庄家博弈,我们要最大化收益,使得在worst case下的收益最大化。
在这种设定下,庄家和玩家的目标函数表达式是一致的,都是 https://www.zhihu.com/equation?tex=%5Csum_%7Bi%3D1%7D%5En%7B%5Cleft%28+%5Cmu+i%2B%5Csigma+_iz_i+%5Cright%29+x_i%7D ,但是二者的目的(或者说,优化方向)是相反的,庄家想要 https://www.zhihu.com/equation?tex=%5Cunderset%7Bz%7D%7B%5Cmin%7D+%5Csum%7Bi%3D1%7D%5En%7B%5Cleft%28+%5Cmu+i%2B%5Csigma+_iz_i+%5Cright%29+x_i%7D ,但是玩家想要 https://www.zhihu.com/equation?tex=%5Cunderset%7Bx%7D%7B%5Cmax%7D++%5Csum%7Bi%3D1%7D%5En%7B%5Cleft%28+%5Cmu+_i%2B%5Csigma+_iz_i+%5Cright%29+x_i%7D 。
此外,其实这里有一个隐含的假设:庄家的决策和玩家的决策没有先后顺序。都是基于预判对方的决策,直接做出了自己的决策,后续无论庄家怎么变,玩家都不再改变自己的决策。而不是:庄家真正的先做决策,玩家再去根据对方的决策调整自己的策略。

[*]小拓展: 还有一种bi-level的形式,是两个主体的目标函数或优化方向不一致(也可以目标函数和优化方向都不一致)。这种形式是更为一般的bi-level决策,是典型的的博弈问题。这种情况一般有一个leader和一个follower组成。比如
[*]leader的决策: https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D%5Cmax+%26%5Csum+c_e+x_e%5C+++s.t.+%26%5Ctext%7B+++leader%E7%9A%84%E7%BA%A6%E6%9D%9F%7D%5Cend%7Baligned%7D
[*]follower的决策: https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D%5Cmax+%26%5Csum+d_e+y_e%5C+++s.t.+%26%5Ctext%7B+++follower%E7%9A%84%E7%BA%A6%E6%9D%9F%7D%5Cend%7Baligned%7D
[*]比如,共享出行中,平台想最大化整个系统的利润,但是对于每个个体而言,他们只想最大化自己的收入。这两个目标函数是不同的,但是所做的决策之间却有一部分耦合。 关于这一部分,本文只简单提及,不再做详细介绍。
接着介绍利用对偶进行reformulation。这种方法的主要思想是

[*]基于bi-level的模型 https://www.zhihu.com/equation?tex=%5Cmax+%5C%2C+%5Cmin ,对inner level模型取对偶,将bi-level模型转化成为 https://www.zhihu.com/equation?tex=%5Cmax%5C%2C%5Cmax ,进而等价为一阶段问题进行求解
注意:本文介绍的这种基于对偶的reformulation方法有两个非常强的前提条件:
1. inner level的模型需要是线性模型,不能有binary和integer的变量以及非线性项。原因是:
-a) MIP是不能以这种方法直接对偶的(但是可以采用其他方法处理,不过也并不是完全等价转化)。
-b) 有非线性项的情况下,如果决策变量都是连续的,可以用KKT条件等价转化。
2. 强对偶是成立的。只有强对偶是成立的,这种转化才是等价的。验证强对偶成立与否的方法很简单,对偶完成以后,看看对偶问题是否存在可行解,如果存在至少一个有解的可行解,则强对偶必然成立。这也是基于对偶定理得来的,即:如果一个问题有可行解,并且目标函数是有界的(因此也有最优解),那么另一个问题也有可行解和有界的目标函数以及最优解,此时强对偶理论和弱对偶理论都是成立的。
接下来,我们来进行reformulation。
首先我们将模型中的绝对值进行线性化(即 https://www.zhihu.com/equation?tex=%5Csum_%7Bi%3D1%7D%5En%7B%7Cz_i%7C%7D%5Cleqslant+%5CGamma )。
我们引入两组辅助变量 https://www.zhihu.com/equation?tex=z_i%5E%7B%2B%7D%2C+z_i%5E%7B-%7D%2C+%5Cforall+i+%3D1%2C2%2C%5Ccdots%2C+n 。其中
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%26z_i%5E%7B%2B%7D+%3D+%5Cmax%7B0%2C+z_i%7D+%5C+%5C%5C+%26z_i%5E%7B-%7D+%3D+%5Cmax%7B0%2C+-z_i%7D+%5Cend%7Baligned%7D++
因此,就有
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%26z_i+%3D+z_i%5E%7B%2B%7D+-+z_i%5E%7B-%7D+%5C%5C+%26%7Cz_i%7C+%3D+z_i%5E%7B%2B%7D+%2B+z_i%5E%7B-%7D+%5Cend%7Baligned%7D
这个比较容易理解,例如 https://www.zhihu.com/equation?tex=z_i+%3D+-0.5 , 则 https://www.zhihu.com/equation?tex=z_i%5E%7B%2B%7D+%3D+0%2C+z_i%5E%7B-%7D+%3D+0.5 , 因此有 https://www.zhihu.com/equation?tex=+z_i+%3D+z_i%5E%7B%2B%7D+-+z_i%5E%7B-%7D+%3D+0+-+0.5+%3D+-0.5 ;https://www.zhihu.com/equation?tex=%7Cz_i%7C+%3D+z_i%5E%7B%2B%7D+%2B+z_i%5E%7B-%7D+%3D+0+%2B+0.5+%3D+0.5 。
拓展 之前的推文中,有小伙伴纠结这个转化是否等价。一个肯定的回答是:完全等价。 这里我给出证明:
命题:
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%26z%5E%2B%3D%5Cmax+%5Cleft%5C%7B+0%2Cz+%5Cright%5C%7D+%5C%2C%5C%2C++++++%5Cleft%28+1+%5Cright%29++%5C%5C+%26z%5E-%3D%5Cmax+%5Cleft%5C%7B+0%2C-z+%5Cright%5C%7D+%5C%2C%5C%2C+++++%5Cleft%28+2+%5Cright%29+%5Cend%7Baligned%7D

https://www.zhihu.com/equation?tex=+%5Cbegin%7Baligned%7D+%26z%3Dz%5E%2B-z%5E-%5C%2C%5C%2C+%5Cleft%28+3+%5Cright%29++%5C%5C+%26%7Cz%7C%3Dz%5E%2B%2Bz%5E-%5C%2C%5C%2C%5Cleft%28+4+%5Cright%29++%5Cend%7Baligned%7D+
互为充要条件。

证明:充分性:根据(1)(2),我们有
https://www.zhihu.com/equation?tex=++%5Cbegin%7Baligned%7D+%26z%3Dz%5E%2B-z%5E-%5C%2C%5C%2C+%5Cleft%28+3+%5Cright%29++%5C%5C+%26%7Cz%7C%3Dz%5E%2B%2Bz%5E-%5C%2C%5C%2C%5Cleft%28+4+%5Cright%29++%5Cend%7Baligned%7D+
充分性得证 必要性: 根据(3)(4)我们有                                              https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%26%5Cleft%28+3+%5Cright%29+%2B%5Cleft%28+4+%5Cright%29+%3Dz%2B%7Cz%7C%3D2z%5E%2B%5C%2C%5C%2C+%5Crightarrow+%5C%2C%5C%2Cz%5E%2B%3D%5Cfrac%7Bz%2B%7Cz%7C%7D%7B2%7D+%5C%5C+%26%5Cleft%28+3+%5Cright%29+-%5Cleft%28+4+%5Cright%29+%3Dz-%7Cz%7C%3D-2z%5E-%5C%2C%5C%2C+%5Crightarrow+%5C%2C%5C%2Cz%5E-%3D-%5Cfrac%7Bz-%7Cz%7C%7D%7B2%7D+%5C%5C+%26%5Ctext%7B%E6%83%85%E5%86%B5%E4%B8%80%EF%BC%9A%7Dif%5C%2C%5C%2Cz%5Cgeqslant+0%2C+z%5E%2B%3D%5Cfrac%7Bz%2B%7Cz%7C%7D%7B2%7D%3D%5Cfrac%7Bz%2Bz%7D%7B2%7D%3Dz%3D%5Cmax+%5Cleft%5C%7B+0%2Cz+%5Cright%5C%7D++%5C%5C+%26z%5E-%3D-%5Cfrac%7Bz-%7Cz%7C%7D%7B2%7D%3D-%5Cfrac%7Bz-z%7D%7B2%7D%3D0%3D%5Cmax+%5Cleft%5C%7B+0%2C-z+%5Cright%5C%7D++%5C%5C+%26%5Ctext%7B%E6%83%85%E5%86%B5%E4%BA%8C%EF%BC%9A%7Dif%5C%2C%5C%2Cz%5Cleqslant+0%2C+z%5E%2B%3D%5Cfrac%7Bz%2B%7Cz%7C%7D%7B2%7D%3D%5Cfrac%7Bz-z%7D%7B2%7D%3D0%3D%5Cmax+%5Cleft%5C%7B+0%2Cz+%5Cright%5C%7D++%5C%5C+%26z%5E-%3D-%5Cfrac%7Bz-%7Cz%7C%7D%7B2%7D%3D-%5Cfrac%7Bz-%5Cleft%28+-z+%5Cright%29%7D%7B2%7D%3D-%5Cfrac%7B2z%7D%7B2%7D%3D-z%3D%5Cmax+%5Cleft%5C%7B+0%2C-z+%5Cright%5C%7D++%5Cend%7Baligned%7D
因此,必要性得证。 综上,(1)(2)和(3)(4)互为充要条件,以上转化完全等价。
我们就借助这一步转化,将模型进行改写为
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%5Cunderset%7Bx%5Cin+%5Cmathbb%7BR%7D%5En%7D%7B%5Cmax%7D%5Cquad+%5Cunderset%7Bz_i%5E%7B%2B%7D%2C+z_i%5E%7B-%7D+%7D%7B%5Cmin%7D%5Cquad+%26%5Csum_%7Bi%3D1%7D%5En%7B%5Cleft%5B+%5Cmu+_i%2B%5Csigma+_i+%28z_i%5E%7B%2B%7D+-+z_i%5E%7B-%7D%29+%5Cright%5D+x_i%7D+%26%26+%5C%5C+%26%5Csum_%7Bi%3D1%7D%5En%7Bx_i%7D%3D100%5C%25++%26%26+++++%5C%5C+%26+%5Csum_%7Bi%3D1%7D%5En%7B+%28z_i%5E%7B%2B%7D+%2B+z_i%5E%7B-%7D%29++%7D%5Cleqslant+%5CGamma++%26%26+++%5C%5C+%26x_i%5Cgeqslant+0%2C+%5Cqquad+%26%26%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5C%5C+%26z_i%5E%7B%2B%7D%2C+z_i%5E%7B-%7D%5Cin+%5Cleft%5B+0%2C1+%5Cright%5D+%2C+%5Cqquad+%26%26%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5Cend%7Baligned%7D
注意:由于在鲁棒优化中,决策者往往并不关心worst case究竟长什么样子,只在意自己的决策应该怎么做,因此决策者也就不关心的取值。
下面我们来进行对偶。我们将内层模型由$\min$对偶成$\max$问题,这样就可以把双层(bi-level)模型转化为单层(single-level)模型。这里注意,对于内层模型(决策worst-case)而言,决策变量就只有 https://www.zhihu.com/equation?tex=z_i%5E%7B%2B%7D%2C+z_i%5E%7B-%7D ,而第二层的决策变量就要被视为固定值(固定值),也就是视为参数。
因此,内层模型就变化为(因为视为固定值,故相关约束全部可以暂时删除)
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%5Cunderset%7Bz_%7Bi%7D%5E%7B%2B%7D%2Cz_%7Bi%7D%5E%7B-%7D%7D%7B%5Cmin%7D%5Cquad+%26C%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Csigma+_ix_iz_%7Bi%7D%5E%7B%2B%7D-%7D%5Csum_%7Bi%3D1%7D%5En%7B%5Csigma+_ix_iz_%7Bi%7D%5E%7B-%7D%7D+%26%26+%5C%5C+%26%5Csum_%7Bi%3D1%7D%5En%7B%5Cleft%28+z_%7Bi%7D%5E%7B%2B%7D%2Bz_%7Bi%7D%5E%7B-%7D+%5Cright%29%7D%5Cleqslant+%5CGamma+%26%26+%5Cqquad+%5Crightarrow+%5Cquad+%5Cpi+%5C%5C+%26z_%7Bi%7D%5E%7B%2B%7D%5Cleqslant+1%2C%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%26%26+%5Cqquad+%5Crightarrow+%5Cquad+%5Clambda_i++++%5C%5C+%26z_%7Bi%7D%5E%7B-%7D%5Cleqslant+1%2C%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%26%26+%5Cqquad+%5Crightarrow+%5Cquad+%5Ctheta_i+%5C%5C+%26z_%7Bi%7D%5E%7B%2B%7D%2Cz_%7Bi%7D%5E%7B-%7D%5Cgeqslant+0++%5Cqquad%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%26%26+%5Cend%7Baligned%7D其中$C$为常数,且$C = \sum_{i=1}^n{\mu _ix_i}$ https://www.zhihu.com/equation?tex=C+%3D+%5Csum_%7Bi%3D1%7D%5En%7B%5Cmu+_ix_i%7D ,且约束(1)、约束(2)和约束(3)的对偶变量分别是 https://www.zhihu.com/equation?tex=%5Cpi 和 https://www.zhihu.com/equation?tex=%5Clambda 和 https://www.zhihu.com/equation?tex=%5Ctheta 。因此,内层模型的对偶问题为:
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%5Cunderset%7B%5Cpi+%2C%5Clambda+%2C%5Ctheta%7D%7B%5Cmax%7D%5Cqquad+%26%5Cpi+%5CGamma+%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Clambda+_i%7D%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Ctheta+_i%7D%26%26+%5C%5C+%26%5Cpi+%2B%5Clambda+_i%5Cleqslant+%5Csigma+_ix_i%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5C%5C+%26%5Cpi+%2B%5Ctheta+_i%5Cleqslant+-%5Csigma+_ix_i%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5C%5C+%26%5Cpi+%2C%5Clambda+_i%2C%5Ctheta+_i%5Cleqslant+0%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5Cend%7Baligned%7D
这个对偶并不难写出来,此处有困难的读者朋友可以参考《运小筹》公众号的往期推文:
这里,我们来验证模型的强对偶是否成立。我们发现当所有 https://www.zhihu.com/equation?tex=%5Cpi%2C+%5Clambda%2C+%5Ctheta 均为0,是对偶模型的一个可行解,且目标函数值为0。也就是说,所有变量均为0,是一个有界的可行解。因此,强对偶成立。
结合内层的对偶问题,原问题可以转化为单层模型,如下:
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%5Cunderset%7Bx%2C%5Cpi+%2C%5Clambda+%2C%5Ctheta%7D%7B%5Cmax%7D%5Cqquad+%26%5Csum_%7Bi%3D1%7D%5En%7B%5Cmu+_ix_i%7D%2B%5Cpi+%5CGamma+%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Clambda+_i%7D%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Ctheta+_i%7D+%26%26+%5C%5C+%26%5Csum_%7Bi%3D1%7D%5En%7Bx_i%7D%3D1++%26%26+%5C%5C+%26%5Cpi+%2B%5Clambda+_i%5Cleqslant+%5Csigma+_ix_i%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5C%5C+%26%5Cpi+%2B%5Ctheta+_i%5Cleqslant+-%5Csigma+_ix_i%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5C%5C+%26%5Cpi+%2C%5Clambda+_i%2C%5Ctheta+_i%5Cleqslant+0%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5C%5C+%26x_i%5Cgeqslant+0%2C%26%26+%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5Cend%7Baligned%7D
2.2Python调用gurobi求解对偶reformulation后的模型

我们来验证该模型是否正确
# author: Xinglu Liu

from gurobipy import *
import numpy as np

# stock number
stock_num = 150   
Gamma = 4
# input parameters
mu = * stock_num
sigma = * stock_num   
reward = [ ] * stock_num   

# initialize the parameters
for i in range(stock_num):
    mu = 0.15 + (i + 1) * (0.05/150)
    sigma = (0.05/450) * math.sqrt(2 * stock_num * (i + 1) * (stock_num + 1))
    reward = mu - sigma
    reward = mu + sigma
mu = np.array(mu)
sigma = np.array(sigma)   
reward = np.array(reward)


model = Model('Robust portfolio Dual')
x = {}
lam = {}
theta = {}
pi = {}   
pi = model.addVar(lb = -GRB.INFINITY, ub = 0, obj = 0, vtype = GRB.CONTINUOUS, name = 'pi')
for i in range(stock_num):
    x = model.addVar(lb = 0, ub = 1, obj = 0, vtype = GRB.CONTINUOUS, name = 'x_' + str(i+1))
    lam = model.addVar(lb = -GRB.INFINITY, ub = 0, obj = 0, vtype = GRB.CONTINUOUS, name = 'lam_' + str(i+1))
    theta = model.addVar(lb = -GRB.INFINITY, ub = 0, obj = 0, vtype = GRB.CONTINUOUS, name = 'theta_' + str(i+1))   

# set the objective function
obj = LinExpr(0)
obj.addTerms(Gamma, pi)
for i in range(stock_num):
    obj.addTerms(mu, x)
    obj.addTerms(1, lam)
    obj.addTerms(1, theta)
model.setObjective(obj, GRB.MAXIMIZE)

# constraints 1 : invest budget
lhs = LinExpr(0)
for i in range(stock_num):
    lhs.addTerms(1, x)   
model.addConstr(lhs == 1, name = 'invest budget')


# constraints 2: dual constraint
for i in range(stock_num):
    lhs = LinExpr(0)
    rhs = LinExpr(0)
    lhs.addTerms(1, pi)
    lhs.addTerms(1, lam)
    rhs.addTerms(sigma, x)
    model.addConstr(lhs <= rhs, name = 'dual_cons1_' + str(i+1))

# constraints 3: dual constraint
for i in range(stock_num):
    lhs = LinExpr(0)
    rhs = LinExpr(0)
    lhs.addTerms(1, pi)
    lhs.addTerms(1, lam)
    rhs.addTerms(-sigma, x)   
    model.addConstr(lhs <= rhs, name = 'dual_cons2_' + str(i+1))

model.write('model.lp')

model.optimize()


# print out the solution
print('-----------------------------------------------')
print('-----------   optimal solution   -------------')
print('-----------------------------------------------')
print('objective : ', round(model.ObjVal, 10))
for key in x.keys():
    if(x.x > 0):
      print(x.varName, '\t = ', round(x.x, 10))

x_sol = []
for key in x.keys():
    x_sol.append(round(x.x, 4))

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(12,8))

plt.plot(range(1, stock_num+1), x_sol,
         linewidth=2, color='b')
plt.xlabel('Stocks')
plt.ylabel('Fraction of investment')
plt.show()求解结果如下:



图2-1

Gurobi Optimizer version 9.0.1 build v9.0.1rc0 (win64)
Optimize a model with 301 rows, 451 columns and 1050 nonzeros
Model fingerprint: 0xb8185bc2
Coefficient statistics:
Matrix range   
Objective range
Bounds range   
RHS range      
Presolve removed 150 rows and 150 columns
Presolve time: 0.01s
Presolved: 151 rows, 301 columns, 600 nonzeros

Iteration    Objective       Primal Inf.    Dual Inf.      Time
       0    2.0000000e-01   2.896358e-01   0.000000e+00      0s
      79    1.7378554e-01   0.000000e+00   0.000000e+00      0s

Solved in 79 iterations and 0.01 seconds
Optimal objective1.737855434e-01
-----------------------------------------------
-----------   optimal solution   -------------
-----------------------------------------------
objective :0.1737855434
x_72   =0.0154576484
x_73   =0.015351409
x_74   =0.0152473305
x_75   =0.0151453405
x_76   =0.0150453702
x_77   =0.0149473537
x_78   =0.0148512282
x_79   =0.0147569338
x_80   =0.0146644129
x_81   =0.0145736107
x_82   =0.0144844746
x_83   =0.0143969543
x_84   =0.0143110016
x_85   =0.0142265702
x_86   =0.0141436157
x_87   =0.0140620956
x_88   =0.0139819691
x_89   =0.0139031968
x_90   =0.0138257411
x_91   =0.0137495656
x_92   =0.0136746355
x_93   =0.0136009173
x_94   =0.0135283785
x_95   =0.0134569882
x_96   =0.0133867162
x_97   =0.0133175338
x_98   =0.0132494129
x_99   =0.0131823269
x_100    =0.0131162496
x_101    =0.0130511562
x_102    =0.0129870223
x_103    =0.0129238248
x_104    =0.0128615409
x_105    =0.012800149
x_106    =0.0127396278
x_107    =0.0126799571
x_108    =0.0126211171
x_109    =0.0125630887
x_110    =0.0125058533
x_111    =0.0124493932
x_112    =0.0123936909
x_113    =0.0123387297
x_114    =0.0122844933
x_115    =0.0122309658
x_116    =0.012178132
x_117    =0.0121259771
x_118    =0.0120744865
x_119    =0.0120236463
x_120    =0.011973443
x_121    =0.0119238633
x_122    =0.0118748944
x_123    =0.011826524
x_124    =0.0117787399
x_125    =0.0117315303
x_126    =0.0116848839
x_127    =0.0116387895
x_128    =0.0115932363
x_129    =0.0115482139
x_130    =0.0115037119
x_131    =0.0114597205
x_132    =0.0114162299
x_133    =0.0113732308
x_134    =0.0113307139
x_135    =0.0112886703
x_136    =0.0112470913
x_137    =0.0112059683
x_138    =0.0111652931
x_139    =0.0111250577
x_140    =0.0110852542
x_141    =0.0110458748
x_142    =0.0110069122
x_143    =0.0109683589
x_144    =0.010930208
x_145    =0.0108924524
x_146    =0.0108550854
x_147    =0.0108181004
x_148    =0.0107814908
x_149    =0.0107452504
x_150    =0.010709373该结果与上篇推文中直接调用ROME求解的结果相同,说明我们的reformulation是正确的。开心~
3 鲁棒优化模型的reformulation: 利用上镜图reformulation

3.1 利用上镜图reformulation

由于上述模型是bi-level的模型,即 https://www.zhihu.com/equation?tex=%5Cmax+%5C%2C%5C%2C+%5Cmin 问题,我们可以通过上镜图的方法将其转化为single level的模型(这种做法也是参考一些文献的做法,参见参考文献7),具体方法为:

[*]引入辅助决策变量 https://www.zhihu.com/equation?tex=t
则上述模型可以转化为
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%5Cunderset%7Bx%5Cin+%5Cmathbb%7BR%7D%5En%7D%7B%5Cmax%7D+%5Cquad+%26t++++%26%26+%5C%5C+%26t%5Cleqslant+%5Csum_%7Bi%3D1%7D%5En%7B%5Cleft%28+%5Cmu+_i%2B%5Csigma+_iz_i+%5Cright%29+x_i%7D%2C++%26%26+%5Cforall+%5Cmathbf%7Bz%7D%3D%28z_1%2C+%5Ccdots%2C+z_n%29%5ET+%5Cin+%5Cmathcal%7BZ%7D+%5C%5C+%26%5Csum_%7Bi%3D1%7D%5En%7Bx_i%7D%3D100%5C%25++%26%26+%5C%5C+%26x_i%5Cgeqslant+0%2C%26+%26%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5Cend%7Baligned%7D
其中,约束 https://www.zhihu.com/equation?tex=t%5Cleqslant+%5Csum_%7Bi%3D1%7D%5En%7B%5Cleft%28+%5Cmu+i%2B%5Csigma+_iz_i+%5Cright%29+x_i%7D%2C+%5C%2C%5C%2C++%5Cforall+%5Cmathbf%7Bz%7D%3D%28z_1%2C+%5Ccdots%2C+z_n%29%5ET+%5Cin+%5Cmathcal%7BZ%7D 就等价于 https://www.zhihu.com/equation?tex=%5Cunderset%7Bz%5Cin+%5Cmathcal%7BZ%7D%7D%7B%5Cmin%7D+%5Csum%7Bi%3D1%7D%5En%7B%5Cleft%28+%5Cmu+_i%2B%5Csigma+_iz_i+%5Cright%29+x_i%7D 。

[*]一定要注意约束 https://www.zhihu.com/equation?tex=t%5Cleqslant+%5Csum_%7Bi%3D1%7D%5En%7B%5Cleft%28+%5Cmu+_i%2B%5Csigma+_iz_i+%5Cright%29+x_i%7D 后面的 https://www.zhihu.com/equation?tex=%5Cforall+%5Cmathbf%7Bz%7D%3D%28z_1%2C+%5Ccdots%2C+z_n%29%5ET+%5Cin+%5Cmathcal%7BZ%7D ,这个一定不能少。
上述约束其实也可以写为
https://www.zhihu.com/equation?tex=+%5Cbegin%7Baligned%7D++t%5Cleqslant+%5Cunderset%7Bz%7D%7B%5Cmin%7D+%5Csum_%7Bi%3D1%7D%5En%7B%5Cleft%28+%5Cmu+_i%2B%5Csigma+_iz_i+%5Cright%29+x_i%7D%2C+%5C%2C%5C%2C++%5Cforall+%5Cmathbf%7Bz%7D%3D%28z_1%2C+%5Ccdots%2C+z_n%29%5ET+%5Cin+%5Cmathcal%7BZ%7D+++%5Cqquad++%281%29+%5Cend%7Baligned%7D
这种写法也上面的写法是等价的。因为,右端项所有可能的取值,就等价于右端项的最小值。
实际上,约束(1)自己就是一个小优化问题,并不是能够直接处理的约束。
接下来,我们的任务就是要将(1)转化成为可处理的形式。
我们需要将其作进一步处理。我们将(1)改写成
https://www.zhihu.com/equation?tex=+%5Cbegin%7Baligned%7D++t%5Cleqslant+%5Cunderset%7Bz_i%5Cin+%5Cleft%5B+-1%2C1+%5Cright%5D+%2C%5Cforall+i%3B%5Csum%7B%7Cz_i%7C%7D%5Cleqslant+%5CGamma%7D%7B%5Cmin%7D%5Csum_%7Bi%3D1%7D%5En%7B%5Cleft%28+%5Cmu+_i%2B%5Csigma+_iz_i+%5Cright%29+x_i%7D%2C+++%5Cqquad+++%282%29++%5Cend%7Baligned%7D
转化的方法,是将 https://www.zhihu.com/equation?tex=%5Cunderset%7Bz_%5Cin+%5Cmathcal%7BZ%7D%7D%7B%5Cmin%7D%5Csum_%7Bi%3D1%7D%5En%7B%5Cleft%28+%5Cmu+_i%2B%5Csigma+_iz_i+%5Cright%29+x_i%7D 取对偶。方法与上面介绍的直接对偶的方法一致,我们可以直接把结果拿过来。
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%5Cunderset%7B%5Cpi+%2C%5Clambda+%2C%5Ctheta%7D%7B%5Cmax%7D%5Cqquad+%26+%5Csum_%7Bi%3D1%7D%5En%7B%5Cmu+_ix_i%7D+%2B+%5Cpi+%5CGamma+%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Clambda+_i%7D%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Ctheta+_i%7D%26%26+%5C%5C+%26%5Cpi+%2B%5Clambda+_i%5Cleqslant+%5Csigma+_ix_i%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5C%5C+%26%5Cpi+%2B%5Ctheta+_i%5Cleqslant+-%5Csigma+_ix_i%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5C%5C+%26%5Cpi+%2C%5Clambda+_i%2C%5Ctheta+_i%5Cleqslant+0%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5Cend%7Baligned%7D 于是,(3)就可以写成
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D++%26t%5Cleqslant+%5Cunderset%7B%5Cpi+%2C%5Clambda+%2C%5Ctheta%7D%7B%5Cmax%7D%5C%2C%5C%2C%5Csum_%7Bi%3D1%7D%5En%7B%5Cmu+_ix_i%7D%2B%5Cpi+%5CGamma+%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Clambda+_i%7D%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Ctheta+_i%7D%2C+++%5Cqquad+++%284%29++%5C%5C+%26%5Cpi+%2B%5Clambda+_i%5Cleqslant+%5Csigma+_ix_i%2C+%5Cqquad+%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+++%5Cqquad++%285%29+%5C%5C+%26%5Cpi+%2B%5Ctheta+_i%5Cleqslant+-%5Csigma+_ix_i%2C+%5Cqquad+%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+++%5Cqquad++%286%29+%5C%5C+%26%5Cpi+%2C%5Clambda+_i%2C%5Ctheta+_i%5Cleqslant+0%2C+%5Cqquad+%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn++++%5Cqquad++%287%29+%5Cend%7Baligned%7D当然,这里也需要验证强对偶成立(我们在上面已经验证过了)。对于(4),我们可以直接将拿掉,变成
https://www.zhihu.com/equation?tex=+%5Cbegin%7Baligned%7D+%26t%5Cleqslant+%5Csum_%7Bi%3D1%7D%5En%7B%5Cmu+ix_i%7D%2B+%5Cpi+%5CGamma+%2B%5Csum%7Bi%3D1%7D%5En%7B%5Clambda+i%7D%2B%5Csum%7Bi%3D1%7D%5En%7B%5Ctheta+_i%7D%2C+++%5Cqquad+++%288%29+%5Cend%7Baligned%7D
因为,右端项的任意一个值,就能推出 https://www.zhihu.com/equation?tex=t%5Cleqslant+%5Cunderset%7B%5Cpi+%2C%5Clambda+%2C%5Ctheta%7D%7B%5Cmax%7D%5C%2C%5C%2C+%5Csum_%7Bi%3D1%7D%5En%7B%5Cmu+ix_i%7D%2B%5Cpi+%5CGamma+%2B%5Csum%7Bi%3D1%7D%5En%7B%5Clambda+i%7D%2B%5Csum%7Bi%3D1%7D%5En%7B%5Ctheta+_i%7D 。
基于上述讨论,我们可以整理出最终的等价形式。
利用epigraph转化后的最终形式:

https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%5Cunderset%7Bx%5Cin+%5Cmathbb%7BR%7D%5En%7D%7B%5Cmax%7D+%5Cquad+%26t++++%26%26+%5C%5C+%3E+%26t%5Cleqslant+%5Csum_%7Bi%3D1%7D%5En%7B%5Cmu+_ix_i%7D%2B+%5Cpi+%5CGamma+%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Clambda+_i%7D%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Ctheta+_i%7D%2C++%26%26+%3E+%5C%5C+%26%5Cpi+%2B%5Clambda+_i%5Cleqslant+%5Csigma+_ix_i%2C+%26%26%5Cforall+i%3D1%2C%5Ccdots+%2Cn+++%5C%5C+%26%5Cpi+%2B%5Ctheta+_i%5Cleqslant+-%5Csigma+_ix_i%2C+%26%26%5Cforall+i%3D1%2C%5Ccdots+%2Cn+++%5C%5C+%26%5Cpi+%2C%5Clambda+_i%2C%5Ctheta+_i%5Cleqslant+0%2C+%26%26%5Cforall+i%3D1%2C%5Ccdots+%2Cn+++%5C%5C+%26%5Csum_%7Bi%3D1%7D%5En%7Bx_i%7D%3D100%5C%25++%26%26+%5C%5C+%26x_i%5Cgeqslant+0%2C%26+%26%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%26%26+%5C%5C+%26+t+%5Ctext%7B++free%7D+%5Cend%7Baligned%7D 我们发现,实质上和直接使用对偶方法获得的结果是等价的。最后的差别只是多了一个辅助变量$t$而已。为了方便读者对照,我们将直接使用对偶得到的结果也放在这里。
结合内层的对偶问题,原问题可以转化为单层模型,如下

[*]直接对偶得到的结果:

https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%5Cunderset%7Bx%2C%5Cpi+%2C%5Clambda+%2C%5Ctheta%7D%7B%5Cmax%7D%5Cqquad+%26%5Csum_%7Bi%3D1%7D%5En%7B%5Cmu+_ix_i%7D%2B%5Cpi+%5CGamma+%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Clambda+_i%7D%2B%5Csum_%7Bi%3D1%7D%5En%7B%5Ctheta+_i%7D+%26%26+%5C%5C+%26%5Csum_%7Bi%3D1%7D%5En%7Bx_i%7D%3D1++%26%26+%5C%5C+%26%5Cpi+%2B%5Clambda+_i%5Cleqslant+%5Csigma+_ix_i%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5C%5C+%26%5Cpi+%2B%5Ctheta+_i%5Cleqslant+-%5Csigma+_ix_i%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5C%5C+%26%5Cpi+%2C%5Clambda+_i%2C%5Ctheta+_i%5Cleqslant+0%2C+%26%26%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5C%5C+%26x_i%5Cgeqslant+0%2C%26%26+%5Cqquad+%5Cforall+i%3D1%2C%5Ccdots+%2Cn+%5Cend%7Baligned%7D+
当然了,这个结果不用代码验证都能看出来是等价的。但是为了亲眼看一看,我们就多此一举地再来验证一下了,毕竟都到这个份儿上了。当然,也是顺便凑点字数。
3.2 Python调用gurobi求解reformulation后的模型

完整代码如下:
# author: Xinglu Liu

from gurobipy import *
import numpy as np

# stock number
stock_num = 150
Gamma = 4
# input parameters
mu = * stock_num
sigma = * stock_num
reward = [] * stock_num

# initialize the parameters
for i in range(stock_num):
    mu = 0.15 + (i + 1) * (0.05 / 150)
    sigma = (0.05 / 450) * math.sqrt(2 * stock_num * (i + 1) * (stock_num + 1))
    reward = mu - sigma
    reward = mu + sigma
mu = np.array(mu)
sigma = np.array(sigma)
reward = np.array(reward)

model = Model('Robust portfolio Dual')
x = {}
lam = {}
theta = {}
pi = {}
pi = model.addVar(lb=-GRB.INFINITY, ub=0, obj=0, vtype=GRB.CONTINUOUS, name='pi')
t = model.addVar(lb=-GRB.INFINITY, ub=GRB.INFINITY, obj=1, vtype=GRB.CONTINUOUS, name='t')
for i in range(stock_num):
   x = model.addVar(lb=0, ub=1, obj=0, vtype=GRB.CONTINUOUS, name='x_' + str(i + 1))
    lam = model.addVar(lb=-GRB.INFINITY, ub=0, obj=0, vtype=GRB.CONTINUOUS, name='lam_' + str(i + 1))
    theta = model.addVar(lb=-GRB.INFINITY, ub=0, obj=0, vtype=GRB.CONTINUOUS, name='theta_' + str(i + 1))

# set the objective function
model.setObjective(t, GRB.MAXIMIZE)

# constraints 1 : dual constraint
rhs = LinExpr(0)
rhs.addTerms(Gamma, pi)
for i in range(stock_num):
    rhs.addTerms(mu, x)
    rhs.addTerms(1, lam)
    rhs.addTerms(1, theta)
model.addConstr(t <= rhs, name='dual constraint')

# constraints 1 : invest budget
lhs = LinExpr(0)
for i in range(stock_num):
    lhs.addTerms(1, x)
model.addConstr(lhs == 1, name='invest budget')

# constraints 2: dual constraint
for i in range(stock_num):
    lhs = LinExpr(0)
    rhs = LinExpr(0)
    lhs.addTerms(1, pi)
    lhs.addTerms(1, lam)
    rhs.addTerms(sigma, x)
    model.addConstr(lhs <= rhs, name='dual_cons1_' + str(i + 1))

# constraints 3: dual constraint
for i in range(stock_num):
    lhs = LinExpr(0)
    rhs = LinExpr(0)
    lhs.addTerms(1, pi)
    lhs.addTerms(1, lam)
    rhs.addTerms(-sigma, x)
    model.addConstr(lhs <= rhs, name='dual_cons2_' + str(i + 1))

model.write('model.lp')

model.optimize()

# print out the solution
print('-----------------------------------------------')
print('-----------   optimal solution   -------------')
print('-----------------------------------------------')
print('objective : ', round(model.ObjVal, 10))
print('t =: ', t.x)
for key in x.keys():
    if (x.x > 0):
      print(x.varName, '\t = ', round(x.x, 10))

x_sol = []
for key in x.keys():
    x_sol.append(round(x.x, 4))

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(12, 8))

plt.plot(range(1, stock_num + 1), x_sol,
         linewidth=2, color='b')
plt.xlabel('Stocks')
plt.ylabel('Fraction of investment')
plt.show()求解结果如下
Iteration    Objective       Primal Inf.    Dual Inf.      Time
       0    2.0000000e-01   2.896358e-01   0.000000e+00      0s
      79    1.7378554e-01   0.000000e+00   0.000000e+00      0s

Solved in 79 iterations and 0.00 seconds
Optimal objective1.737855434e-01
-----------------------------------------------
-----------   optimal solution   -------------
-----------------------------------------------
objective :0.1737855434
t =:0.17378554337248034
x_72   =0.0154576484
x_73   =0.015351409
x_74   =0.0152473305
x_75   =0.0151453405
x_76   =0.0150453702
x_77   =0.0149473537
x_78   =0.0148512282
x_79   =0.0147569338
x_80   =0.0146644129
x_81   =0.0145736107
x_82   =0.0144844746
x_83   =0.0143969543
x_84   =0.0143110016
x_85   =0.0142265702
x_86   =0.0141436157
x_87   =0.0140620956
x_88   =0.0139819691
x_89   =0.0139031968
x_90   =0.0138257411
x_91   =0.0137495656
x_92   =0.0136746355
x_93   =0.0136009173
x_94   =0.0135283785
x_95   =0.0134569882
x_96   =0.0133867162
x_97   =0.0133175338
x_98   =0.0132494129
x_99   =0.0131823269
x_100    =0.0131162496
x_101    =0.0130511562
x_102    =0.0129870223
x_103    =0.0129238248
x_104    =0.0128615409
x_105    =0.012800149
x_106    =0.0127396278
x_107    =0.0126799571
x_108    =0.0126211171
x_109    =0.0125630887
x_110    =0.0125058533
x_111    =0.0124493932
x_112    =0.0123936909
x_113    =0.0123387297
x_114    =0.0122844933
x_115    =0.0122309658
x_116    =0.012178132
x_117    =0.0121259771
x_118    =0.0120744865
x_119    =0.0120236463
x_120    =0.011973443
x_121    =0.0119238633
x_122    =0.0118748944
x_123    =0.011826524
x_124    =0.0117787399
x_125    =0.0117315303
x_126    =0.0116848839
x_127    =0.0116387895
x_128    =0.0115932363
x_129    =0.0115482139
x_130    =0.0115037119
x_131    =0.0114597205
x_132    =0.0114162299
x_133    =0.0113732308
x_134    =0.0113307139
x_135    =0.0112886703
x_136    =0.0112470913
x_137    =0.0112059683
x_138    =0.0111652931
x_139    =0.0111250577
x_140    =0.0110852542
x_141    =0.0110458748
x_142    =0.0110069122
x_143    =0.0109683589
x_144    =0.010930208
x_145    =0.0108924524
x_146    =0.0108550854
x_147    =0.0108181004
x_148    =0.0107814908
x_149    =0.0107452504
x_150    =0.010709373我们发现,这个解与之前直接调用ROME求解的解,以及直接用对偶得到的结果都是相同的。
4 小结

求解鲁棒优化模型的两大类方法:
求解鲁棒优化一般有两大类方法:
1. 将鲁棒优化模型重构(reformulate)为单层(single-level)段线性规划模型,然后直接调用通用的求解器求解;
2. 直接使用鲁棒优化求解器(ROME, RSOME等)建模求解。
Reformulate鲁棒优化模型的几种方法:

[*]对偶reformulation,但是需要注意,这种方法应用的前提是内层模型一定需要是线性规划,以及reformulate之后一定要验证强对偶成立。
[*]上镜图reformulation,这种方法也涉及到对偶。最后得到的模型与第一种方法的结果是等价的。
[*]其他方法:这里暂不介绍,等到后面有涉及到再做详细介绍。
最近的两篇推文:

[*]【鲁棒优化笔记】基于ROME编程入门鲁棒优化:以一个例子引入(一)


[*]【鲁棒优化笔记】以Coding入门鲁棒优化:以一个例子引入(二)
是笔者学习鲁棒优化过程中精心整理的学习笔记,理论+模型+推导+代码都是一整套的,目前鲁棒优化的基础入门资料相对较少,希望这些资料可以对读者朋友们有所帮助。
由于笔者水平有限,推文中难免有错误,如果读者朋友们发现有错误,请及时联系我更正,非常感谢。
5 参考文献


[*]E. Guslitzer A. Ben-Tal, A. Goryashko and A. Nemirovski. Robust optimization.2009.
[*]https://robustopt.com/
[*]ROME: Joel Goh and Melvyn Sim. Robust Optimization Made Easy with ROME. Operations Research, 2011, 59(4), pp.973-985.
[*]Joel Goh and Melvyn Sim. Distributionally Robust Optimization and its Tractable Approximations. Operations Research, 2010, 58(4), pp. 902-917.
[*]Chen, Zhi, and Peng Xiong. 2021. RSOME in Python: an open-source package for robust stochastic optimization made easy. Optimization Online.
[*]Chen, Zhi, Melvyn Sim, Peng Xiong. 2020. Robust stochastic optimization made easy with RSOME. Management Science 66(8) 3329–3339.
[*]Gorissen B L, Yankolu , den Hertog D. A practical guide to robust optimization. Omega, 2015, 53: 124-137.

<hr/>运小筹公众号致力于分享运筹优化(LP、MIP、NLP、随机规划、鲁棒优化)、凸优化、强化学习等研究领域的内容以及涉及到的算法的代码实现。编程语言和工具包括Java、Python、Matlab、CPLEX、Gurobi、SCIP 等。欢迎广大同行投稿!欢迎大家关注我们的公众号“运小筹”以及粉丝群!
如果群满加不进去,可以加本文作者微信,然后备注姓名+机构+专业,然后拉您入群。
QQ群:
QQ群里有我们共享的一些书籍、论文、算例等资料,欢迎大家加入。
<hr/>往期推文合集

第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/> 作者:刘兴禄, 清华大学,清华-伯克利深圳学院,博士在读
编辑: 张瑞三, 四川大学, 硕士在读, 邮箱:493810171@qq.com、sum3rebirth@gmail.com
页: [1]
查看完整版本: 鲁棒优化 | 以Coding入门鲁棒优化:以一个例子引入(二)