python中的非线性/线性编程

时间:2018-05-29 05:50:53

标签: python optimization linear-programming nonlinear-optimization

我的优化是这样的:

Maximize (x1*a1 + x2*a2+...+xn * an) 

such that :
  any j,  (xj*aj)/sum(all xi*ai) <= 0.35 
  any two j, (xj*aj)/sum(all xi*ai) >= 0.15
  any three j, (xj*aj)/sum(all xi*ai) >= 0.07 
  any j  1<= aj <= 100 and aj is an integer. 

我尝试使用Scipy.optimize实现相同的功能。但是,我不确定所使用的方法是否正确,因为SLSQP给出的任何输入都没有解决它。 我尝试过使用Scipy和纸浆来解决不同的约束配方。但是,似乎都不起作用。我已经分享了下面的scipy代码。我不确定scipy / pulp是否允许ifelse约束或在循环中采取约束。

share = 
[1595798.061003,1595798.061003,1595798.061003,1595798.061003,
6335021.83000001,6335021.83000001,6335021.83000001,
6335021.83000001,42842994.4958]

def objective(factors):
    mult = []
    for i in range(len(share)):
       mult.append(share[i]*factors[i])

return -sum(mult)

def constraint1(factors):
    #n=len(factors)
    sum_w = 0
    for i in range(len(share)):
       sum_w= sum_w+(share[i]*factors[i])
    sum_f =0 
    for j in range(len(share)):
        print((share[j]*factors[j])/sum_w)
        if(((share[j]*factors[j])/sum_w) -0.35) <= 0 :
            sum_f = sum_f + 0
        else:
            sum_f = sum_f + 1
return sum_f 

def constraint2(factors):
    sum_w = 0
    for i in range(len(share)):
        sum_w= sum_w+(share[i]*factors[i])
    sum_f2 =0 
    for j in range(len(share)):
        if(((share[j]*factors[j])*100/sum_w) - 0.15) >= 0 :
            sum_f2 = sum_f2 + 1
        else:
            sum_f2 = sum_f2 + 0
return sum_f2 - 2

def constraint3(factors):
    sum_w = 0
    for i in range(len(share)):
        sum_w= sum_w+(share[i]*factors[i])
    sum_f3 =0 
    for j in range(len(share)):
       if(((share[j]*factors[j])*100/sum_w) - 0.07) >= 0 :
           sum_f3 = sum_f3 + 1
       else:
           sum_f3 = sum_f3 + 0
return sum_f3 - 3 

bounds = []
share0=[]

for i in range(len(share)):
    bounds.append((1,100))
    share0.append(100)

cons1={'type': 'eq','fun' : constraint1}
cons2={'type': 'ineq','fun' : constraint2}
cons3={'type': 'ineq','fun' : constraint3} 

cons=[cons1]
sol=minimize(objective,share0,method='SLSQP',bounds=bounds,constraints=cons) 

我得到的输出显示:

fun: 7387762651.568393
jac: array([ -1595776.,  -1595776.,  -1595776.,  -1595776.,  -6335040.,
    -6335040.,  -6335040.,  -6335040., -42843008.])
message: 'Singular matrix C in LSQ subproblem'
nfev: 11
nit: 1
njev: 1
status: 6
success: False
x: array([ 100. , 100. , 100. , 100. , 100., 100., 100., 100., 100. ])

我应该在这里使用什么方法?

1 个答案:

答案 0 :(得分:0)

PySCIPOpt应该很好地处理这些约束。它比SciPy更可靠,特别是考虑到你正在处理整数变量和一些非线性,你可以像你建议的那样直接建模。