【发布时间】:2018-07-31 14:14:48
【问题描述】:
我试图在下图中找到从 G 到 C 的最短路径,我编写了以下代码来完成此操作。
首先,我给出我认为应该使用的方程式和约束:
我们最大化直流受制于:
db-da
df-da
dc-db
dd-dc
de-dd
df-dd
dd-de
dg-de
da-df
db-df
dc-df
de-df
dd-dg
dh-dg
da-dh
db-dh
import numpy as np
import scipy as scp
from scipy.optimize import minimize
a,b,c,d,e,f,g,h = 0,1,2,3,4,5,6,7
def objective(x, sign = -1.0):
return sign*x[c]
def c1(x, sign = -1.0):
return sign*(x[b]-x[a]-8)
def c2(x, sign = -1.0):
return sign*(x[f]-x[a]-10)
def c3(x, sign = -1.0):
return sign*(x[c]-x[b]-4)
def c4(x, sign = -1.0):
return sign*(x[d]-x[c]-3)
def c5(x, sign = -1.0):
return sign*(x[e]-x[d]-25)
def c6(x, sign = -1.0):
return sign*(x[f]-x[d]-18)
def c7(x, sign = -1.0):
return sign*(x[d]-x[e]-9)
def c8(x, sign = -1.0):
return sign*(x[g]-x[e]-7)
def c9(x, sign = -1.0):
return sign*(x[a]-x[f]-5)
def c10(x, sign = -1.0):
return sign*(x[b]-x[f]-7)
def c11(x, sign = -1.0):
return sign*(x[c]-x[f]-3)
def c12(x, sign = -1.0):
return sign*(x[e]-x[f]-2)
def c13(x, sign = -1.0):
return sign*(x[d]-x[g]-2)
def c14(x, sign = -1.0):
return sign*(x[h]-x[g]-3)
def c15(x, sign = -1.0):
return sign*(x[a]-x[h]-4)
def c16(x, sign = -1.0):
return sign*(x[b]-x[h]-9)
def c17(x, sign = -1.0):
return x[g]
cs = [c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17]
x0 = [0 for i in range(8)]
b = (0,None)
bs = tuple([b for i in range(8)])
cons = []
for i in range(16):
cons.append({'type': 'ineq', 'fun':cs[i]})
cons.append({'type': 'eq', 'fun':c17})
sol = minimize(objective, x0, method = 'SLSQP', bounds=bs, constraints=cons)
for val in sol['x']:
print(round(val))
可以只使用代数来求解每个变量,但使用 LP 来代替应该是有效的。
我相信仅通过图形的手动跟踪,最佳路径是 GHBC,总成本为 16。但是,上面的代码表明最佳路径是 GHAFC,其成本在没有意义之前是有意义的:3 -4-1-3。它说最佳路径长度是 11。它似乎非常接近有效答案,只是它认为您可以以 1 的成本从 A 走到 F。
[编辑:我刚刚注意到我错过了从 B 到 E 的边缘,但这似乎并不重要,事实上,当我将它添加到算法中时,答案并没有改变。]
【问题讨论】:
-
这行不通有两个原因:1. 图中的可能路径是离散集,但
minimize设计用于在连续域上工作。 2.minimize会找到一个局部最优解,不保证能找到全局最优解。像differential_evolution这样的全局优化器可能会让你更幸运。 -
目标函数中全局变量
c的索引应该做什么? -
这是一种使用 LP 计算最短路径的有效方法(无需整数编程)。这是基于完全单模性的概念。 但是对求解器(基本解决方案)有一些假设,
scipy.minimize不是 LP 求解器!有scipy.optimize.linprog(method='simplex'),但它的质量不是很高,尽管它可能会起作用。 (不要使用像 SLSQP 这样的通用 NLP 方法来解决 LP;事情可能会改变并且会在这里发生;另一个不相关的例子:SOCP-solver vs. SOCP with NLP: in NLP an SOC-constraint is non-smooth and can't be无需重新制定即可解决)。
标签: python scipy mathematical-optimization