【问题标题】:How to quickly get a feasible solution to a linear program in Python?如何在 Python 中快速得到一个线性程序的可行解?
【发布时间】:2018-07-30 16:22:44
【问题描述】:

目标:计算两个凸多面体的交集。

我正在使用scipy.spatial.HalfspaceIntersection 来执行此操作。下图显示了生成的交集:

我的问题:确定一个初始可行点。

您看,scipy.spatial.HalfspaceIntersection 的当前 Python 实现需要将 interior_point 作为参数传递。

interior_point : ndarray of floats, shape (ndim,)
清楚地指向由半空间定义的区域内。也称为可行点,可以通过线性规划得到。

现在,我正在手动提供可行点,因为我只是在起草一个原型来试验HalfspaceIntersection。 但是现在我已经到了不想手动指定它的地步。

SciPy 的优化模块scipy.optimize.linprog 实现了两个通用线性规划 (LP) 求解器:simplexinterior-point .但是,它们似乎需要成本函数。 [1]

由于我想花费尽可能少的处理时间来计算这个可行点,我想知道如何在没有成本函数的情况下运行任何这些 LP 方法,即只运行到解决方案已达到可行状态。

问题:

  1. scipy.optimize.linprog 是计算这个可行内点的正确方法吗?

  2. 如果是,我如何使用 simplexinterior-point 没有成本函数?

  3. 为什么scipy.spatial.HalfspaceIntersection 要求首先将interior point 作为参数传递?据我所知,半空间的交集是消除给定一组不等式的冗余不等式。为什么这需要一个可行点?

【问题讨论】:

标签: python numpy scipy computational-geometry linear-programming


【解决方案1】:

您可以指定一个恒定的成本函数,例如 0。

这是一个例子:

%pylab
from scipy.optimize import linprog
A = array([[1] + 9 * [0], 9 * [0] + [1]])
b = array([1, 1])

衡量这种方法的性能表明它非常有效:

%time
res = linprog(c=zeros(A.shape[1]), A_eq=A, b_eq=b)

输出:

CPU times: user 5 µs, sys: 1 µs, total: 6 µs
Wall time: 11 µs

此外,根据res.nit,我们仅在 2 次迭代后就完成了。

结果res.x是正确的:

array([ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.])

请注意,单纯形算法旨在找到由线性约束定义的多面体的顶点。据我了解,基于内部点的方法没有这样的偏好,尽管我不熟悉 scipy 的 linprog 背后的实现。因此,由于您的要求是“明显在半空间定义的区域内”,因此我建议使用以下任一方法:

  • 要么,method='interior-point' 传递给linprog
  • 或者, 计算不同的顶点并利用多面体是凸的:
    1. 为常量目标函数添加一些噪声(例如,通过np.random.randn
    2. 通过改变噪声种子 (np.random.seed) 求解多个噪声增强 LP 实例。
    3. 最后,使用解的平均值作为最终的内点“明显在区域内”

由于不清楚内部点的边距需要多大,我希望第二种方法(噪声增强 LP)更稳健。

【讨论】:

  • 在执行HalfspaceIntersection():scipy.spatial.qhull.QhullError: QH6023 qhull input error: feasible point is not clearly inside halfspace 时,使用零作为成本函数来查找可行点会导致此问题。我已经多次运行它并且它总是会发生:解决方案位于凸集的边缘或顶点中。
  • 这在于这种方法的本质:LP 的解决方案总是是一个顶点或一条边。如果优化的解决方案既不是由线性约束指定的多面体的顶点也不是边,那么您的目标函数是非线性的,因此您的优化问题不是 LP。这里唯一的例外是恒定目标,但仍然有许多求解器会产生角(或边缘),因为它们更容易找到。你试过传递method='interior-point'吗?
  • 如果传递 method='interior-point' 没有帮助,您可能还想尝试 (i) 向常量目标函数添加一点噪声(例如,通过 np.random.randn) ,(ii) 通过改变噪声种子 (np.random.seed) 解决多个噪声增强 LP 实例,(iii) 最后使用解决方案的平均值作为您正在寻找的最终内部点。这应该是可行的,因为由线性等式/不等式定义的多面体是凸的。
  • 是的,我知道 LP 的性质涉及到这一点,并且接近边界的结果仍然是,显然,一个可行的解决方案。其实我比较疑惑的是HalfspaceIntersection为什么需要这个可行点; “清楚地在半空间内”是什么意思 ---我的意思是,距离边界有多远“清楚地在内部”...无论如何,我有切换到method='interior-point'它解决了问题!!任何直觉为什么?非常感谢!
  • 单纯形算法旨在寻找多面体的顶点。据我了解,基于内部点的方法没有这样的偏好,尽管我不熟悉 scipy 的 linprog 背后的实现。但是,根据您所指出的,尚不清楚解决方案的余量将或需要有多大。因此,第二种方法(噪声增强 LP)可能更稳健。
猜你喜欢
  • 2017-06-28
  • 2022-06-12
  • 2011-06-22
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
  • 2021-05-11
  • 2022-11-19
  • 1970-01-01
相关资源
最近更新 更多