我想在python中解决一个线性程序。变量的数量(我将从现在开始称之为N)非常大(~50000)并且为了以scipy.optimize.linprog
所需的方式来表示问题,我必须构造两个N×N矩阵({ {1}}和A
以下)。 LP可以写成
B
其中minimize: c.x
subject to:
A.x <= a
B.x = b
x_i >= 0 for all i in {0, ..., n}
表示点积,.
,a
和b
是长度为N的向量。
我的经验是构建如此大的矩阵(c
和A
都有大约50000x50000 = 25 * 10 ^ 8个条目)带来一些问题:如果硬件不是很强大,NumPy可能会拒绝构建这样大的矩阵(例如参见Very large matrices using Python and NumPy),即使NumPy创建矩阵没有问题,也存在巨大的性能问题。对于NumPy必须处理的大量数据,这是很自然的。
然而,即使我的线性程序带有N个变量,我使用的矩阵也非常稀疏。其中一个在第一行中只有条目,另一个仅在前M行中有条目,其中M <1。 N / 2。当然我想利用这个事实。
据我所读(例如Trying to solve a Scipy optimization problem using sparse matrices and failing),B
不适用于稀疏矩阵。因此,我有以下问题:
答案 0 :(得分:2)
我想说形成一个密集矩阵(或两个)来解决一个大的稀疏LP可能不是正确的事情。在求解大型稀疏LP时,使用具有处理此类问题的工具的解算器以及以不明确创建任何这些零元素的方式生成模型非常重要。
在Python中编写一个稳定,快速,稀疏的Simplex LP解算器作为SciPy密集解算器的替代并非易事。此外,用纯Python编写的求解器可能效果不佳。
对于您指出的大小,虽然不是非常非常大(可能是大型中型模型将是一个很好的分类),您可能需要考虑商业求解器,如Cplex,Gurobi或{ {3}}。这些求解器非常快速且非常可靠(它们基本上解决了你向它们抛出的任何LP问题)。它们都有Python API。对于学者来说,解算器是免费或非常便宜的。
如果要使用开源解算器,可能需要查看COIN CLP解算器。它还有一个Mosek。
如果您的模型更复杂,那么您也可能需要考虑使用Python建模工具,例如Python interface或Pulp(Gurobi在Python中也有很好的建模支持)。
答案 1 :(得分:0)
我无法相信没有人指出你PuLP的方向!您将能够有效地创建问题,如下所示:
import pulp
prob = pulp.LpProblem("test problem",pulp.LpMaximize)
x = pulp.LpVariable.dicts('x', range(5), lowBound=0.0)
prob += pulp.lpSum([(ix+1)*x[ix] for ix in range(5)]), "objective"
prob += pulp.lpSum(x)<=3, "capacity"
prob.solve()
for k, v in prob.variablesDict().iteritems():
print k, v.value()
PuLP很棒,有一个非常好的求解器(CBC),可以连接到开源和商业求解器。我目前正在林业公司的生产中使用它,并为我们遇到的最困难(整数)问题探索Dippy。祝你好运!
答案 2 :(得分:0)