【问题标题】:Why can't I rig SciPy's constrained optimization for integer programming?为什么我不能为整数编程设置 SciPy 的约束优化?
【发布时间】:2013-03-25 11:24:11
【问题描述】:

I've read that integer programming is either very tricky or not possible with SciPy 并且我可能需要使用 zibopt 之类的东西在 Python 中执行此操作。但我真的认为我可以通过为 SciPy 优化的向量中的每个元素创建一个“二元”约束来做到这一点。

为此,我使用了 http://docs.python-guide.org/en/latest/writing/gotchas/#late-binding-closures 的关闭技巧 并为每个元素创建一个约束函数,如下所示:

def get_binary_constraints(vector, indices_to_make_binary=None):
    indices_to_make_binary = indices_to_make_binary or range(len(vector))
    for i in indices_to_make_binary:
        def ith_element_is_binary(vector, index=i):
            return vector[index] == 0 or vector[index] == 1
        yield ith_element_is_binary

test_vector = scipy.array([0.5, 1, 3])
constraints = list(get_binary_constraints(test_vector))
for constraint in constraints:
    print constraint(test_vector)

哪个打印:

False
True
False

然后我修改了 fmin_cobyla 的 get_binary_constraints,它的约束是 "sequence of functions that all must be >=0"

def get_binary_constraints(vector, indices_to_make_binary=None):
    indices_to_make_binary = indices_to_make_binary or range(len(vector))
    for i in indices_to_make_binary:
        def ith_element_is_binary(vector, index=i):
            return int(vector[index] == 0 or vector[index] == 1) - 1
        yield ith_element_is_binary

为相同的测试向量 [0.5, 1, 3] 打印以下内容:

-1
0
-1

因此,只有数组中的第二个值满足 >= 0 的条件。

然后,我设置了一个非常简单的优化问题如下:

from scipy import optimize
import scipy

def get_binary_constraints(vector, indices_to_make_binary=None):
    indices_to_make_binary = indices_to_make_binary or range(len(vector))
    for i in indices_to_make_binary:
        def ith_element_is_binary(vector, index=i):
            return int(vector[index] == 0 or vector[index] == 1) - 1
        yield ith_element_is_binary

def objective_function(vector):
    return scipy.sum(vector)

def main():
    guess_vector = scipy.zeros(3)
    constraints = list(get_binary_constraints(guess_vector))
    result = optimize.fmin_cobyla(objective_function, guess_vector, constraints)
    print result

if __name__ == '__main__':
    main()

这就是我得到的:

Return from subroutine COBYLA because the MAXFUN limit has been reached.

NFVALS = 1000   F =-8.614066E+02    MAXCV = 1.000000E+00
X =-2.863657E+02  -2.875204E+02  -2.875204E+02
[-286.36573349 -287.52043407 -287.52043407]

在我使用 R 的 LPSolve 包或为此安装 zipobt 之前,我真的很想看看我是否可以只使用 SciPy。

是我做错了什么,还是在 SciPy 中不可能做到这一点?

【问题讨论】:

    标签: python numpy scipy mathematical-optimization


    【解决方案1】:

    问题在于,尽管看起来不直观,Integer Programming 是一个比实数线性规划更难的问题。您链接到的 SO 线程中有人提到 SciPy 使用 Simplex 算法。该算法不适用于整数规划。您必须使用不同的算法。

    如果您确实找到了一种使用 Simplex 来有效解决整数规划的方法,那么您已经解决了 P=NP 问题,这值得 US$1,000,000 第一个解决。

    【讨论】:

    • 您可以做的一个简化是将其求解为实数,然后向下舍入。这不会给你最佳的解决方案,但它很可能会给你一些相当不错的东西。像这样的东西可以满足您的需求吗?
    • 另一个线程使用Nelder-Mead,但这里使用的fmin_cobyla也是基于单工的。
    • 严格来说,这个答案的第二段是错误的。如果您可以使用单纯形法有效地解决整数规划问题,那么除非您还证明假设的整数单纯形法在多项式时间内运行,否则您还没有证明 P=NP。虽然有线性规划的多项式算法,但不知道是否有用于LP的多项式单纯形法。
    猜你喜欢
    • 1970-01-01
    • 2017-08-01
    • 2014-07-13
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多