Python中的线性规划?

42
我需要制作一个线性规划模型。以下是我正在使用的不等式(例如):
6x + 4y <= 24
x + 2y <= 6
-x + y <= 1
y <= 2

我需要找到由这些不等式描述的区域,并在图表中进行阴影处理,同时跟踪该区域边界线的顶点,并用不同颜色绘制边界线。请参见下面的图表,以了解我要寻找的示例。

image of the points of intersection.

我正在使用Python 3.2、numpy和matplotlib。在Python中是否有更好的线性规划模块?

4
第一步,将不等式系统转换为矩阵形式。 - Dan D.
2
根据维基百科的说法,线性规划是数学优化的一种方法:http://zh.wikipedia.org/wiki/线性规划 - XORcist
@möter同意-删除我的评论。错误是我的,而不是Op的。 - Ivaylo Strandjev
你的第三个方程式 -x + x <= 1 是一个无操作,因为它可以简化为 0 <= 1,这对于所有的 x 和 y 都是成立的。 - Eric
@user24562,您能否详细说明一下您使用的默认代码过程(使用numpy和matplotlib)? - Shivam Kotwalia
@user24562:这里有一个使用PuLP的详细逐步示例。https://dev59.com/25Dea4cB1Zd3GeqPXiSu - ekta
8个回答

74

更新: 过去4年时间里,本回答的内容已经有些过时了,现在您有许多选择:

  • 如果您不一定非要使用Python,那么使用建模语言实现会更容易,可以参考Any good tools to solve integer programs on linux?

  • 我个人现在使用的是Gurobi 的Python API。它是一个商业闭源产品,但对于学术研究免费。

  • 使用PuLP,您可以创建MPSLP文件,然后通过它们的命令行接口使用GLPK、COIN CLP/CBC、CPLEX或XPRESS进行求解。这种方法有其优点和缺点。

  • Google的OR-Tools是一个用于优化的开源软件套件,专门针对车辆路径规划、流量、整数线性规划和约束编程等世界上最棘手的问题。

  • Pyomo是一个基于Python的开源优化建模语言,具有多种优化功能。

  • SciPy提供线性规划:scipy.optimize.linprog。(我从未尝试过这个。)

  • 显然,CVXOPT 提供了一个Python与GLPK交互的接口,我之前并不知道。我已经使用GLPK八年了,我强烈推荐GLPK。CVXOPT的示例和教程看起来很好!

  • 您可以在维基书中的GLPK/Python中找到其他可能性。请注意,其中许多并不一定局限于GLPK。


  • 使用PuLP,它是GLPK、CPLEX或Gurobi的强大Python接口。 - Tom Larkworthy
    4
    匿名的负面评价对任何人都没有帮助。这个回答有什么问题?请说明。 - Ali
    版本1.1的PuLP 链接到 jeannot.org 的主页,但我的 Sophos 软件拦截了它并显示“高风险网站已被阻止访问,因为在该网站上发现了C2/Generic-A威胁。”Sophos 的页面称它是“命令和控制恶意软件。” 有人使用过PuLP吗?你对此有何看法? - miguelmorin
    @mmorin 谢谢,我接受了你的编辑。很高兴看到人们发现这个答案有用。 - Ali
    我认为PuLP应该位于此列表的顶部,其次是Google ortools和Pyomo。 - Evgeny
    @Evgeny 谢谢,我已经添加了这些内容,并更新了链接。非常感谢你的反馈。 - Ali

    20
    我推荐使用Python中的 cvxopt 模块来解决凸优化问题。在 cvxopt 的文档这里中,有一个线性规划的 Python 代码示例。请注意保留原有的HTML标签格式。

    7
    其他回答已经提供了一个求解器的列表,但是只有PuLP被提及作为Python库来制定LP模型。
    另一个很好的选择是Pyomo。像PuLP一样,你可以将问题发送给任何求解器并读取解决方案到Python中。你也可以操作求解器参数。我和一位同学在2015年比较了PuLP和Pyomo的性能,我们发现Pyomo可以为相同的问题生成.LP文件的速度比PuLP快几倍。

    6
    唯一使用图表解决线性规划问题的情况是作业问题。在所有其他情况下,线性规划问题都通过矩阵线性代数来解决。
    至于Python,虽然有一些纯Python库,但大多数人使用带有Python绑定的本地库。有各种免费和商业线性规划库可供选择。有关详细列表,请参见维基百科中的线性规划或OR/MS Today中的线性规划软件调查
    免责声明:我目前在Gurobi Optimization工作,曾经在提供CPLEX的ILOG工作过。

    14
    在作业和工作之间,还有对学习的热情——我认为你写的第一句话不合适... - siemanko
    1
    线性规划问题中哪种方法最快? - Royi

    4
    为了解决线性规划问题,您可以使用SciPy中的scipy.optimize.linprog模块,该模块使用Simplex算法。

    2
    这里是一个图形化展示问题的例子,灵感来自于如何使用Numpy/MatplotLib可视化线性规划的可行区域(带任意不等式)?

    线性规划

    import numpy as np
    import matplotlib.pyplot as plt
    
    m = np.linspace(0,5,200)
    x,y = np.meshgrid(m,m)
    plt.imshow(((6*x+4*y<=24)&(x+2*y<=6)&(-x+y<=1)&(y<=2)&(x>=0)&(y>=0)).astype(int), 
        extent=(x.min(),x.max(),y.min(),y.max()),origin='lower',cmap='Greys',alpha=0.3);
    # plot constraints
    x = np.linspace(0, 5, 2000)
    # 6*x+4*y<=24
    y0 = 6-1.5*x
    # x+2*y<=6
    y1 = 3-0.5*x
    # -x+y<=1
    y2 = 1+x
    # y <= 2
    y3 = (x*0) + 2
    # x >= 0
    y4 = x*0
    plt.plot(x, y0, label=r'$6x+4y\leq24$')
    plt.plot(x, y1, label=r'$x+2y\leq6$')
    plt.plot(x, y2, label=r'$-x+y\leq1$')
    plt.plot(x, 2*np.ones_like(x), label=r'$y\leq2$')
    plt.plot(x, y4, label=r'$x\geq0$')
    plt.plot([0,0],[0,3], label=r'$y\geq0$')
    xv = [0,0,1,2,3,4,0]; yv = [0,1,2,2,1.5,0,0]
    plt.plot(xv,yv,'ko--',markersize=7,linewidth=2)
    for i in range(len(xv)):
        plt.text(xv[i]+0.1,yv[i]+0.1,f'({xv[i]},{yv[i]})')
    plt.xlim(0,5); plt.ylim(0,3); plt.grid(); plt.tight_layout()
    plt.legend(loc=1); plt.xlabel('x'); plt.ylabel('y')
    plt.show()
    

    问题在于缺少一个目标函数,因此任何一个阴影点都满足不等式。如果它有一个目标函数(例如 Maximize x+y),那么许多能力强大的Python求解器可以处理这个问题。这是一个线性规划的例子,在GEKKO中,还支持混合整数、非线性和微分约束。
    from gekko import GEKKO
    m = GEKKO(remote=False)
    x,y = m.Array(m.Var,2,lb=0)
    m.Equations([6*x+4*y<=24,x+2*y<=6,-x+y<=1,y<=2])
    m.Maximize(x+y)
    m.solve(disp=False)
    

    大规模的线性规划问题通常以矩阵形式或稀疏矩阵形式解决,只存储矩阵的非零部分。这里有一个线性规划解决方案教程,其中包含我为一门大学课程开发的几个示例。


    1

    我建议使用PuLP Python包。它有一个很好的界面,您可以使用不同类型的算法来解决线性规划问题。


    0

    对我来说,lpsolve 是最容易的。无需安装单独的求解器,它已经包含在软件包中了。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接