运筹学修炼日记:如何优雅地写出大规模线性规划的对偶问题

  • 运筹学修炼日记:如何优雅地写出大规模线性规划的对偶
    • 最短路问题
    • 多商品流问题`Multicommodity Network Flow Problem`
  • 借助`Excel`和`具体小算例`写出大规模LP的对偶
    • Dual Problem :Shortest Path Problem(最短路问题)
      • 小算例
    • `Excel`+`小算例`写出`SPP`的对偶问题
      • 将`Excel`中的`Dual tabular`转化成公式形式
    • Dual Problem :Multicommodity Network Flow Problem(最短路问题)
      • 具体算例
    • `Excel`+`小算例`写出`MNF`的原模型
      • 将`Excel`中的`Dual tabular`转化成公式形式
    • Python调用Gurobi求解Multicommodity Network Flow Problem (仅原问题)
    • 后记

欢迎关注我们的微信公众号 运小筹

运筹学修炼日记:如何优雅地写出大规模线性规划的对偶

对偶理论Duality Theory在运筹学数学规划部分占据着举足轻重的地位,也属于比较高阶的理论。Duality Theory精确算法设计中也经常用到,在Robust Optimization等涉及到多层规划Multilevel的问题中,也有非常广泛的应用,很多时候可以化腐朽为神奇。尤其在Robust Optimization中,有些问题可以巧妙的将内层inner level的模型转化成LP,从而可以通过对偶,将双层bi-level的模型,转化成单阶段single level的模型,从而用单层的相关算法来求解Robust Optimization问题。

今天我们就来看看,在实际的科研当中,遇到的一些稍微复杂一点的LP,我们如何写出其对偶问题。

实际上在一些顶刊中,例如transportation Science等,比较近期的文章,也时不时会看到这样的操作。这个操作其实并不是抬手就能搞定的,很多时候需要反复修改,才能将对偶问题正确的写出来。
据我所知,我似乎是第一个写这样博文的博主。(如果有比我更早的,请告知我掐了这段)

先来看一个比较容易的线性规划问题:
max ⁡ Z = 2 x 1 + 3 x 2 5 x 1 + 4 x 2 ⩽ 170 → y 1 2 x 1 + 3 x 2 ⩽ 100 → y 2 x 1 , x 1 ⩾ 0 \begin{aligned} \max \quad Z=&2x_1+3x_2 \\ &5x_1+4x_2\leqslant 170 \quad \rightarrow \quad \color{red} y_1 \\ &2x_1+3x_2\leqslant 100 \quad \rightarrow \quad \color{red} y_2 \\ &x_1,x_1\geqslant 0 \end{aligned} maxZ=​2x1​+3x2​5x1​+4x2​⩽170→y1​2x1​+3x2​⩽100→y2​x1​,x1​⩾0​
其对偶问题比较容易写出:
min ⁡ W = 170 y 1 + 100 y 2 5 y 1 + 2 y 2 ⩾ 2 4 y 1 + 3 y 2 ⩾ 3 y 1 , y 1 ⩾ 0 \begin{aligned} \min \quad W=&170y_1+100y_2 \\ &5y_1+2y_2\geqslant 2 \\ &4y_1+3y_2\geqslant 3 \\ &y_1,y_1\geqslant 0 \end{aligned} minW=​170y1​+100y2​5y1​+2y2​⩾24y1​+3y2​⩾3y1​,y1​⩾0​
基本原则如图:

当然了,上面的表格也是比较麻烦的。我们可以将任意的模型,都转化成标准型,再去对偶,这样会方便很多。

但是假如是最短路问题:

最短路问题

max ⁡ ∑ e ∈ A d e x e ∑ e ∈ o u t ( i ) x e − ∑ e ∈ i n ( i ) x e = { 1 , if i = s − 1 , if i = t 0 , else 0 ⩽ x e ⩽ 1 , ∀ e ∈ A \begin{aligned} \max \quad & \sum_{e\in A}{d_ex_e} \\ &\sum_{e\in \mathrm{out}\left( i \right)}{x_e}-\sum_{e\in \mathrm{in}\left( i \right)}{x_e}=\begin{cases} 1,& \text{if}\,\,i=s\\ -1,& \text{if}\,\,i=t\\ 0,& \text{else}\\ \end{cases} \\ & 0 \leqslant x_e \leqslant 1 ,\qquad \forall e\in A \end{aligned} max​e∈A∑​de​xe​e∈out(i)∑​xe​−e∈in(i)∑​xe​=⎩⎪⎨⎪⎧​1,−1,0,​ifi=sifi=telse​0⩽xe​⩽1,∀e∈A​

这里大括号里有几个条件判断,就不是那么容易了。也许这个还比较容易,那再看看这个。多商品流问题Multicommodity Network Flow Problem

多商品流问题Multicommodity Network Flow Problem

  • K K K origin-destination pairs of nodes, ( s 1 , t 1 , d 1 ) , ( s 2 , t 2 , d 2 ) , ⋯ , ( s k , t k , d k ) (s_1, t_1, d_1), (s_2, t_2, d_2), \cdots, (s_k, t_k, d_k) (s1​,t1​,d1​),(s2​,t2​,d2​),⋯,(sk​,tk​,dk​).
  • d k d_k dk​ : demand, amount of flow that must be sent from s k s_k sk​ to t k t_k tk​.
  • u i j u_{ij} uij​ : capacity on ( i , j ) (i,j) (i,j) shared by all commodities
  • c i j k c_{ij}^k cijk​ : cost of sending 1 unit of commodity k k k in ( i , j ) (i,j) (i,j)
  • x i j k x_{ij}^k xijk​ : flow of commodity k k k in ( i , j ) (i,j) (i,j)

模型如下
min ⁡ ∑ ( i , j ) ∈ A ∑ k c i j k x i j k ∑ j x i j k − ∑ j x j i k = { d k , i f i = s k − d k , i f i = t k 0 , o t h e r w i s e ∑ k x i j k ⩽ u i j , ∀ ( i , j ) ∈ A x i j k ⩾ 0 , ∀ ( i , j ) ∈ A , k ∈ K \begin{aligned} \min \quad &\sum_{\left( i,j \right) \in A}{\sum_k{c_{ij}^{k}x_{ij}^{k}}} \\ &\sum_j{x_{ij}^{k}}-\sum_j{x_{ji}^{k}}=\begin{cases} d_k,& \qquad \mathrm{if}\,\,\,\, i=s_k\\ -d_k,& \qquad \mathrm{if}\,\,\,\, i=t_k\\ 0,& \qquad \mathrm{otherwise}\\ \end{cases} \\ &\sum_k{x_{ij}^{k}}\leqslant u_{ij}, \qquad \forall \left( i,j \right) \in A \\ &x_{ij}^{k}\geqslant 0, \qquad \forall \left( i,j \right) \in A, k\in K \end{aligned} min​(i,j)∈A∑​k∑​cijk​xijk​j∑​xijk​−j∑​xjik​=⎩⎪⎨⎪⎧​dk​,−dk​,0,​ifi=sk​ifi=tk​otherwise​k∑​xijk​⩽uij​,∀(i,j)∈Axijk​⩾0,∀(i,j)∈A,k∈K​
现在呢?还能很容易的写出来吗?若果还能,大神请受小弟一拜!哈哈哈

能轻松写出来的非人类大神可以前走左拐去刷剧了,咱这些普通人就接着往下看把。

注意,上面的Multicommodity Flow Problem和Shortest Path Problem都是Linear Programming,可以对偶的。但是对于Integer Programming和Mixed Integer Programming来讲,是不能对偶的。这一点一定要搞清楚。

对于这种稍微复杂一些的LP,我们怎么能写出对偶还保证正确,可debug找错的呢?我的方法就是借助Excel+具体小算例

借助Excel具体小算例写出大规模LP的对偶

为了大家理解方便,我们不要直接去硬钢Multicommodity Network Flow(理论上搞定了Multicommodity Network Flow,其实就具备搞定大多数可以对偶的LP的潜力了).我们先以SPP来开个胃。

Dual Problem :Shortest Path Problem(最短路问题)

小算例

我们先来引入一个小算例。该算例来自参考文献[^2],我做了点修改。为了显示我比较认真,我还专门无聊用LaTeX+Tikz重新画了一个小花图:
(咋样,看着还舒服吧)

我们再来看一下SPP的模型:
max ⁡ ∑ e ∈ A d e x e ∑ e ∈ o u t ( i ) x e − ∑ e ∈ i n ( i ) x e = { 1 , if i = s − 1 , if i = t 0 , else 0 ⩽ x e ⩽ 1 , ∀ e ∈ A \begin{aligned} \max \quad & \sum_{e\in A}{d_ex_e} \\ &\sum_{e\in \mathrm{out}\left( i \right)}{x_e}-\sum_{e\in \mathrm{in}\left( i \right)}{x_e}=\begin{cases} 1,& \text{if}\,\,i=s\\ -1,& \text{if}\,\,i=t\\ 0,& \text{else}\\ \end{cases} \\ & 0 \leqslant x_e \leqslant 1 ,\qquad \forall e\in A \end{aligned} max​e∈A∑​de​xe​e∈out(i)∑​xe​−e∈in(i)∑​xe​=⎩⎪⎨⎪⎧​1,−1,0,​ifi=sifi=telse​0⩽xe​⩽1,∀e∈A​
按照这个模型,我们手动把这个模型具体的写出来。为了之后的操作,我们直接写到Excel里。

Excel+小算例写出SPP的对偶问题

SPP模型如下:


我们把这个表叫Primal tabular其中,每一列代表一个变量 x i j , ∀ ( i , j ) ∈ A x_{ij}, \forall (i,j)\in A xij​,∀(i,j)∈A

  1. 第一行代表该条 ( i , j ) (i,j) (i,j)的距离
  2. 第二行代表变量 x i j , ∀ ( i , j ) ∈ A x_{ij}, \forall (i,j)\in A xij​,∀(i,j)∈A
  3. 第一行和第二行就组成了目标函数 ∑ e ∈ A d e x e \sum_{e\in A}{d_ex_e} ∑e∈A​de​xe​
  4. 第3-9行代表每个结点 ∀ i ∈ V \forall i \in V ∀i∈V的约束
  5. 最后一列代表每个约束的Dual variable

OK,我们按照对偶的方法,将Primal tabularRHSDual variabe拷贝,转置成2行,放在一个新表格(我们叫做Dual tabular)的头两行,然后将Primal tabular的整个约束系数矩阵拷贝,转置到Dual tabular头两行下面。再把原问题Primal tabulardistance行和min行拷贝,转置,放在Dual tabular的右面。
再把Dual tabular中改成max。为了明确Dual Problem各个变量的符号(正负性)以及每个约束的符号(relation),我们在Dual tabular中加入一行(就是第三行),表示变量的符号。同时在Dual tabular约束矩阵后加入一列,表示约束的符号。

操作完就是这样的


按照上面那个关系图中的信息,我们可以确定,对偶变量 π i \pi_i πi​都是无约束的,我们用=表示,Dual Problem中的约束都是 ⩽ \leqslant ⩽的。这样,对偶就完成了。

但是,这还是一个具体的算例的Dual,我们需要将这个具体的算例,通过提取信息整理,化成一个general的公式形式。

Excel中的Dual tabular转化成公式形式

我们观察上图,每一行都对应一条弧 ( i , j ) ∈ A (i,j)\in A (i,j)∈A,例如第一行是 ( 1 , 2 ) (1, 2) (1,2),第二行是 ( 1 , 4 ) (1,4) (1,4)等。可以看到,对应出发点的变量系数全是1,对应终点的系数全是-1,无一例外,因此,我们可以断定,这个约束可以这么写:
π i − π j ⩽ d i j , ∀ ( i , j ) ∈ A \pi _i-\pi _j \leqslant d_{ij}, \qquad \forall \left( i,j \right) \in A πi​−πj​⩽dij​,∀(i,j)∈A
结合目标函数,以及变量的符号,我们可以写出SPP的对偶问题:
max ⁡ π s − π t π i − π j ⩽ d i j , ∀ ( i , j ) ∈ A π i free \begin{aligned} \max \qquad &\pi _s-\pi _t \\ &\pi _i-\pi _j \leqslant d_{ij}, \qquad \forall \left( i,j \right) \in A \\ &\pi _i\,\,\,\,\text{free} \end{aligned} max​πs​−πt​πi​−πj​⩽dij​,∀(i,j)∈Aπi​free​
大功告成,怎么样,有没有点内味了

接下来,我们啃一个稍微难啃一些的骨头Multicommodity Network Flow Problem.

Dual Problem :Multicommodity Network Flow Problem(最短路问题)

这个问题相比SPP难度还是大挺多的。我们首先上数学模型。

min ⁡ ∑ ( i , j ) ∈ A ∑ k c i j k x i j k ∑ j x i j k − ∑ j x j i k = { d k , i f i = s k − d k , i f i = t k 0 , o t h e r w i s e ∑ k x i j k ⩽ u i j , ∀ ( i , j ) ∈ A x i j k ⩾ 0 , ∀ ( i , j ) ∈ A , k ∈ K \begin{aligned} \min \quad &\sum_{\left( i,j \right) \in A}{\sum_k{c_{ij}^{k}x_{ij}^{k}}} \\ &\sum_j{x_{ij}^{k}}-\sum_j{x_{ji}^{k}}=\begin{cases} d_k,& \qquad \mathrm{if}\,\,\,\, i=s_k\\ -d_k,& \qquad \mathrm{if}\,\,\,\, i=t_k\\ 0,& \qquad \mathrm{otherwise}\\ \end{cases} \\ &\sum_k{x_{ij}^{k}}\leqslant u_{ij}, \qquad \forall \left( i,j \right) \in A \\ &x_{ij}^{k}\geqslant 0, \qquad \forall \left( i,j \right) \in A, k\in K \end{aligned} min​(i,j)∈A∑​k∑​cijk​xijk​j∑​xijk​−j∑​xjik​=⎩⎪⎨⎪⎧​dk​,−dk​,0,​ifi=sk​ifi=tk​otherwise​k∑​xijk​⩽uij​,∀(i,j)∈Axijk​⩾0,∀(i,j)∈A,k∈K​

看看吧,又有什么 i f i = s k \mathrm{if}\,\, i=s_k ifi=sk​之类的,变量还是 x i j k x_{ij}^k xijk​,你尝试自己先写一下,是不是觉得脑瓜子嗡嗡的,哈哈哈。

具体算例

都不是事儿,咱一起来刚一下。同样的把文献[^2]中的算例原模原样搬过来看看(当然图还是我自己画的)

Excel+小算例写出MNF的原模型

我们考虑有两个commodity:

commodity = [[1, 7, 25],  # s_i, d_i, demand[2, 6, 2]]

本来想把代码也放上的,感觉太多了,有需要的话,大家私信我,我在修改把代码放上来。

然后我们按照模型和算例网络结构,把模型具体的写出来,如下图所示

第二行的变量x_1_2_0就代表 x i j k x_{ij}^k xijk​,其中0代表 k k k。

这个看上去不太有规律,我们按照commodity k k k把上面的表格整一下,变成:


现在看上去就比较清楚了。我们仍然把这个表格叫做Primal Tabular.
接下来我们按照同样的方法,根据Primal Tabular生成Dual Tabular,如下图

Excel中的Dual tabular转化成公式形式

为了区分 u u u和 μ \mu μ,表格中的mu我就用 λ \lambda λ代替了,因为表格中写mu省地儿。
所以大家注意 λ i j \lambda _{ij} λij​就是上面表格中的mu

max ⁡ ∑ k ∈ K d k ( π i = s k k − π i = t k k ) + ∑ ( i , j ) ∈ A u i j λ i j π i k − π j k + λ i j ⩽ c i j k , ∀ k ∈ K , ∀ ( i , j ) ∈ A π i k free , ∀ k ∈ K , ∀ i ∈ V λ i j ⩽ 0 , ∀ ( i , j ) ∈ A \begin{aligned} \max & \sum_{k\in K}{d_k\left( \pi _{i=s_k}^{k}-\pi _{i=t_k}^{k} \right)}+\sum_{\left( i,j \right) \in A}{u_{ij}\lambda _{ij}} \\ &\pi _{i}^{k}-\pi _{j}^{k}+\lambda _{ij}\leqslant c_{ij}^{k}, \qquad \forall k\in K,\forall \left( i,j \right) \in A \\ &\pi _{i}^{k}\,\,\,\,\text{free}, \qquad \forall k\in K,\forall i\in V \\ &\lambda _{ij}\leqslant 0, \qquad \forall \left( i,j \right) \in A \end{aligned} max​k∈K∑​dk​(πi=sk​k​−πi=tk​k​)+(i,j)∈A∑​uij​λij​πik​−πjk​+λij​⩽cijk​,∀k∈K,∀(i,j)∈Aπik​free,∀k∈K,∀i∈Vλij​⩽0,∀(i,j)∈A​

当然了,按照国际惯例(搞OR大佬的惯例),我们还是跟之前我写的讲SPP对偶的博文
https://blog.csdn.net/HsinglukLiu/article/details/107834197
中的操作一样:

  1. 将所有对偶变量 π i k \pi _{i}^{k} πik​取相反数
  2. 把原约束中 π i k − π j k \pi _{i}^{k}-\pi _{j}^{k} πik​−πjk​改成 π j k − π i k \pi _{j}^{k}-\pi _{i}^{k} πjk​−πik​
  3. 将 π i = s k k \pi _{i=s_k}^{k} πi=sk​k​设置成0,也就是 π i = s k k = 0 \pi _{i=s_k}^{k}=0 πi=sk​k​=0

这三个隐含小动作,大佬是不会在论文里面写的,要是没仔细钻研,你一般会一头雾水。

OK,按照国际惯例操作完后,最终Multicommodity Network Flow Problem模型的Dual Problem就变成了下面的样子
max ⁡ ∑ k ∈ K d k π i = t k k + ∑ ( i , j ) ∈ A u i j λ i j π j k − π i k + λ i j ⩽ c i j k , ∀ k ∈ K , ∀ ( i , j ) ∈ A π i k free , π s k k = 0 , ∀ k ∈ K , ∀ i ∈ V λ i j ⩽ 0 , ∀ ( i , j ) ∈ A \begin{aligned} \max & \sum_{k\in K}{d_k\pi _{i=t_k}^{k}}+\sum_{\left( i,j \right) \in A}{u_{ij}\lambda _{ij}} \\ &\pi _{j}^{k}-\pi _{i}^{k}+\lambda _{ij}\leqslant c_{ij}^{k}, \qquad \forall k\in K,\forall \left( i,j \right) \in A \\ &\pi _{i}^{k}\,\,\,\,\text{free}, \pi _{s_k}^{k} = 0, \qquad \forall k\in K,\forall i\in V \\ &\lambda _{ij}\leqslant 0, \qquad \forall \left( i,j \right) \in A \end{aligned} max​k∈K∑​dk​πi=tk​k​+(i,j)∈A∑​uij​λij​πjk​−πik​+λij​⩽cijk​,∀k∈K,∀(i,j)∈Aπik​free,πsk​k​=0,∀k∈K,∀i∈Vλij​⩽0,∀(i,j)∈A​

OK,所有的动作都完成了。一块硬骨头啃完了。

Python调用Gurobi求解Multicommodity Network Flow Problem (仅原问题)

最后再附上求解这个问题的Python代码(对偶问题的不想写了)

from gurobipy import *
import pandas as pd
import numpy as np
from pandas import Series, DataFrame
import mathArcs = {'1,2': [15, 15]    # cost flow ,'1,4': [25, 25],'1,3': [45, 45],'2,5': [30, 60],'2,4': [2, 2],'5,7': [2, 2],'4,7': [50, 100],'4,3': [2, 2],'3,6': [25, 50],'6,7': [1, 1]}
ArcsNodes = [1, 2, 3, 4, 5, 6, 7] commodity = [[1, 7, 25],  # s_i, d_i, demand [2, 6, 2]
]model = Model('MultiCommodity')  # add variables
X = {}
for key in Arcs.keys():for k in range(len(commodity)):key_x = key + ',' + str(k)X[key_x] = model.addVar(lb=0,ub=Arcs[key][1],vtype=GRB.CONTINUOUS,name= 'x_' + key_x )
# add objective function
obj = LinExpr(0)
for key in Arcs.keys():for k in range(len(commodity)):key_x = key + ',' + str(k)obj.addTerms(Arcs[key][0], X[key_x])
model.setObjective(obj, GRB.MINIMIZE)# constraints 1
for k in range(len(commodity)):for i in Nodes:lhs = LinExpr(0)for key_x in X.keys():
#             nodes = key_x.split(',')if(i == (int)(key_x.split(',')[0]) and k == (int)(key_x.split(',')[2])):lhs.addTerms(1, X[key_x])if(i == (int)(key_x.split(',')[1]) and k == (int)(key_x.split(',')[2])):lhs.addTerms(-1, X[key_x])if(i == commodity[k][0]):model.addConstr(lhs == commodity[k][2], name='org_, ' + str(i) + '_' + str(k))elif(i == commodity[k][1]): model.addConstr(lhs == -commodity[k][2], name='des_, ' + str(i) + '_' + str(k))else:model.addConstr(lhs == 0, name='inter_, ' + str(i) + '_' + str(k))# constraints 2
for key in Arcs.keys():lhs = LinExpr(0)for k in range(len(commodity)):key_x = key + ',' + str(k)lhs.addTerms(1, X[key_x])model.addConstr(lhs <= Arcs[key][1], name = 'capacity_, ' + key) model.write('Multicommodity_model.lp')
model.optimize()for var in model.getVars():if(var.x > 0):print(var.varName, '\t', var.x)
dual = model.getAttr("Pi", model.getConstrs())

原问题求解结果如下:

Solved in 0 iterations and 0.01 seconds
Optimal objective  1.873000000e+03
x_1,2,0      2.0
x_1,4,0      22.0
x_1,3,0      1.0
x_2,5,0      2.0
x_2,4,1      2.0
x_5,7,0      2.0
x_4,7,0      22.0
x_4,3,1      2.0
x_3,6,0      1.0
x_3,6,1      2.0
x_6,7,0      1.0

对偶问题求解

后记

硕士的时候搞这个搞了几天,还请教了我师兄挺多。师兄的研究Robust Service Network Design的文章里也用到了类似这样问题的对偶,发了Transportation Science,我把文章也贴在这里,欢迎大家去读一读,做的非常好[^3]。可以看到,这样的技巧在科研中还是有用武之地的。

[1] :Garg, N., & Koenemann, J. (2007). Faster and simpler algorithms for multicommodity flow and other fractional packing problems. SIAM Journal on Computing, 37(2), 630-652https://doi.org/10.1137/S0097539704446232
[2]:Cappanera, P., & Scaparra, M. P. (2011). Optimal allocation of protective resources in shortest-path networks. Transportation Science, 45(1), 64-80.
http://dx.doi.org/10.1287/trsc.1100.0340
[3]:Wang, Z., & Qi, M. (2020). Robust service network design under demand uncertainty. Transportation Science, 54(3), 676-689.https://doi.org/10.1287/trsc.2019.0935


欢迎关注我们的微信公众号 运小筹

公众号往期推文如下




运筹学修炼日记:如何优雅地写出大规模线性规划的对偶相关推荐

  1. 如何写好日记?让写日记工具助你写出精彩

    很多人小时候都被父母.老师要求写日记,写日记不仅可以锻炼我们的文笔,也可以让我们记录下来美好.有意思的事情,从而更好地反思自我,慢慢进步.但是随着自己长大,每天要完成的任务越来越多,也就逐渐放弃每天写 ...

  2. 【运筹学】由原问题直接写出对偶问题

    <运筹学>第二章,对偶问题.本篇文章的目标是,找到原问题与对偶问题的规律,给定原问题,快速写出其对偶问题(在考试中可以节省时间). 该方法是同学给我讲的,在此感谢. 以<运筹学基础及 ...

  3. 优雅的写出 JavaScript 代码

    目录 前言 避免使用 js 糟粕和鸡肋 编写简洁的 JavaScript 代码 使用 ES6/ES7 新特性 Babel ESLint Prettier 采用函数式编程 优雅的敲 JS 代码的几个原则 ...

  4. java 怎么优雅的写出代码_【Java】基础50:如何让写的代码像诗一样优雅?

    今天是刘小爱自学Java的第50天. 感谢你的观看,谢谢你. 话不多说,开始今天的学习: ‍ 一.Stream流引入 这个流和IO流中的流很容易弄混淆. 但是它们是两个完全不一样的概念,Stream流 ...

  5. 如何更优雅的写出你的SQL语句

    毫无疑问,编写代码是一门艺术而非科学,没有程序员可以编写出既可读又可维护的漂亮代码,即使有经验也是如此. 一般来说,当您学习编码的艺术时,编码水平会随着经验而提高,例如,你会变得更喜欢组合而不是继承或 ...

  6. 如何才能写出优质的代码?

    优秀的代码是如何编写而成的?相信每个人都有自己的答案.在本文中,我们不妨从更为直观的角度加以理解:"如何才能写出优质的代码?" 1. 确保代码易于阅读 不论什么代码,首先我们要关注 ...

  7. 如何写出优雅的 Golang 代码

    Go 语言是一门简单.易学的编程语言,对于有编程背景的工程师来说,学习 Go 语言并写出能够运行的代码并不是一件困难的事情,对于之前有过其他语言经验的开发者来说,写什么语言都像自己学过的语言其实是有问 ...

  8. python写出的程序如何给别人使用-涨姿势!这些小技巧让小白也可以写出更优雅的Python代码!...

    原标题:涨姿势!这些小技巧让小白也可以写出更优雅的Python代码! 一.前言 我前两天回答了两个Python相关的问题,收到了很多赞,从答案被收藏的情况来看,确实对不少人都很有帮助,所以我也很开心. ...

  9. python代码大全p-如何写出优雅又地道的Python代码?【转载】

    在Python社区文化的浇灌下,演化出了一种独特的代码风格,去指导如何正确地使用Python,这就是常说的pythonic.一般说地道(idiomatic)的python代码,就是指这份代码很pyth ...

最新文章

  1. AprilTag程序的获取
  2. gdb coredump
  3. WinAPI: GetDoubleClickTime、SetDoubleClickTime - 获取与设置鼠标双击间隔时间
  4. Ubuntu 下 Git 服务器的安装和初级配置
  5. 08.Eclipse下Ndk开发(使用fmod实现QQ变声功能)
  6. php上操作redis,PHP操作redis
  7. WordPress企业一号主题模板
  8. k8s之scheduler
  9. dell网卡linux驱动,Dell R720上安装linux网卡驱动
  10. vscode 经常弹出unins000.exe报错,尝试在目标目录创造文件时发生错误 重试 跳过这个文件 关闭安装程序
  11. 最新BXP2006无盘教学办公系统
  12. windows图片查看器背景颜色更改
  13. 共享停车位的市场现状,共享车位盘活城市闲置车位!
  14. 招投标概念及注意事项
  15. Microsoft Cartoon Maker(微软卡通头像制作软件)使用方法详解
  16. 什么是正则化?他是如何起作用的?
  17. 如何让AutoHotkey在大部分游戏中好用
  18. CTP程序化交易入门系列之一:准备
  19. 今天,传说中的老方给我们班上课了
  20. Linux_基本指令

热门文章

  1. Jolly Jumpers_UVA10038
  2. hydd的Linux笔记Day72
  3. 【毕设教学】基于python的爬虫实现
  4. 小东吖 之 java 类的多态
  5. 传研发人员被「祭天」,继小红书「崩」上热搜后,网友:“这难道不是测试的锅?”...
  6. uploadify ie9 empty() 缺少对象
  7. fiddler 自动响应数据保存_十分钟学IT:测试工程师得力助手Fiddler抓包之日常使用...
  8. CSS层叠样式表(一)基本内容
  9. 关于肌电、脑电的期刊记录
  10. python星星_python中怎么实现星星排列