权重中间范围使用scipy.optimize.linprog(单纯形算法)

时间:2015-07-16 20:03:17

标签: python scipy

基本问题是给出了这些约束(这是一个简单的例子,我的用例遵循相同的格式但可以引入更多变量):

x + y = C1
C2 <= x <= C3
C4 <= y <= C5

(其中CX是常量,x和y是变量),求解。

scipy.optimize.linprog很容易。我能够获得技术上正确的结果。

实施例。使用这些特定约束:

x + y = 50
5 <= x <= 65
10 <= y <= 40

我们得到:

>>> res = scipy.optimize.linprog([1,1], bounds=([5, 65], [10, 40]), A_eq=[[1,1]], b_eq=[50]  )
>>> res.x
array([ 40.,  10.])

技术上是正确的。请注意,第二个变量是最小的。但由于商业原因,我们更喜欢更多的东西&#34;公平&#34;如果可能的话,每个变量都超过它的最小值,更多的是(但不一定相同):

array([ 25.,  25.])

所以我一直在考虑加权中点。我如何使用这个scipy.optimize.linprog api(或其他一些scipy优化API)修改最小化的函数,以便它更接近每个变量范围中点的值给出更高的优先级?

1 个答案:

答案 0 :(得分:1)

请将此答案视为草案,以了解如何解决这些问题。这当然不是最好的方法,当然也不是解决此类问题的最有效算法。

这里的问题是,您可能无法将您的想法表达为平滑的线性目标函数。你需要某种距离测量,在平滑函数的情况下,它可能至少是二次的。

以下代码将L2向量规范的x添加为惩罚。这在这种情况下是有帮助的,因为L2范数在其组件中是二次的,因此优选所有组件在一个较大和一个较小的组件上同样小。

from scipy.optimize import fmin_slsqp

# equality constraints as h(x) = 0
def h(x):
    return x[0] + x[1] - 50

# inequality constraints as g(x) >= 0
def g(x):
    return [
        x[0] - 5,
        -x[0] + 65,
        x[1] - 10,
        -x[1] + 40,
    ]

# target functions
f1 = lambda x: x[0] + x[1]
f2 = lambda x: x[0] + x[1] + sum(x**2)

结果:

x = fmin_slsqp(f1, (5,45), f_eqcons=h, f_ieqcons=g)
print(x)

输出:

Optimization terminated successfully.    (Exit mode 0)
            Current function value: 50.0
            Iterations: 1
            Function evaluations: 5
            Gradient evaluations: 1
[ 10.  40.]

惩罚版本:

x = fmin_slsqp(f2, (5,45), f_eqcons=h, f_ieqcons=g)
print(x)

打印

Optimization terminated successfully.    (Exit mode 0)
            Current function value: 1300.0
            Iterations: 3
            Function evaluations: 12
            Gradient evaluations: 3
[ 25.  25.]