Ограничения не работают при оптимизации с использованием Scipy

Я пытаюсь решить проблему максимизации прибыли. Компания предлагает несколько схем продвижения. Я делаю целевую функцию для максимизации прибыли с некоторыми ограничениями. Я хочу наложить ограничение, которое гласит, что компания не может запускать более двух схем продвижения одновременно. Однако это условие не работает

Вот мой код:

from scipy.optimize import minimize
from math import floor

#Objective function
def objective(x):
    return -((-14.12*x[0]+1*floor(x[1])+2*floor(x[2])+4*floor(x[3]))*x[0] \ #total revenue (qty*price)
            -(-14.12*x[0]+1*floor(x[1])+2*floor(x[2])+4*floor(x[3]))*10000*0.05\ #Gold price cost
            -(-14.12*x[0]+1*floor(x[1])+2*floor(x[2])+4*floor(x[3]))*x[0]*0.1\ #Rebate cost
            -(-14.12*x[0]+1*floor(x[1])+2*floor(x[2])+4*floor(x[3])/15000*100000)) 

#Points constraint

#Constraints
def PriceConstraint(x):
    return x[0]-3000

def GoldCoinConstraint(x):
    return floor(x[1])-1

def PointsConstraint(x):
    return floor(x[2])-1

def ProgressiveRebateConstraint(x):
    return floor(x[3])-1

def CombinationConstraint(x):
    return 2-floor(x[1])+floor(x[2])+floor(x[3])

#Initial guesses
n=5
x0=np.zeros(5)
x0[0]=1
x0[1]=2
x0[2]=2
x0[3]=1
x0[4]=3

# show initial objective
print('Initial Objective: ' + str(objective(x0)))

# optimize
b = (0.0,1.0)
pricebound = (1,3000)
bnds = (pricebound, b, b, b,b)
con1= {'type':'ineq','fun':PriceConstraint}
con2= {'type':'ineq','fun':GoldCoinConstraint}
con3= {'type':'ineq','fun':PointsConstraint}
con4= {'type':'ineq','fun':ProgressiveRebateConstraint}
con5= {'type':'ineq','fun':CombinationConstraint}

cons = ([con1, con2, con3, con4, con5])

solution = minimize(objective,x0,method='SLSQP',\
                    bounds=bnds,constraints=cons)

x = solution.x

# show final objective
print('Final Objective: ' + str(objective(x)))

# print solution
print('Solution')
print('x1 = ' + str(x[0]))
print('x2 = ' + str(x[1]))
print('x3 = ' + str(x[2]))
print('x4 = ' + str(x[3]))

Как видите, я установил ограничение, согласно которому количество маркетинговых схем не должно быть больше двух, используя функцию комбинацииconstrain. Как-то вроде не работает? Я получаю результат как 1 для x [1], x [2] и x [3].

Может кто-нибудь помочь мне, почему это не работает?

Также с другой стороны, существует ли что-то вроде теневой цены в нелинейной оптимизации. Я знаю, что он существует в линейном программировании, но не уверен в нелинейном?


person Himanshu Singh    schedule 28.09.2020    source источник


Ответы (1)


2-floor(x[1])+floor(x[2])+floor(x[3])

наверное должен прочитать

2-(floor(x[1])+floor(x[2])+floor(x[3]))

Это тебе не особо поможет. Когда вы запустите его, вы можете получить что-то вроде:

     fun: -976376.097853337
     jac: array([567.265625,   0.      ,   0.      ,   0.      ,   0.      ])
 message: 'Positive directional derivative for linesearch'
    nfev: 32
     nit: 7
    njev: 3
  status: 8
 success: False
       x: array([300.9,   1. ,   1. ,   1. ,   1. ])

Ваша floor функция делает проблему неразличимой. SLSQP любит только гладкие (т.е. дифференцируемые) задачи.

Я думаю, что ваша проблема на самом деле является проблемой смешанного целочисленного квадратичного программирования. Поэтому я бы посоветовал не решать эту проблему с помощью непрерывного решателя NLP, а лучше с помощью решателя MIQP. Таким образом, вам не понадобятся floor функции. К сожалению, scipy не содержит решателя MIQP.


В: есть ли что-то вроде теневой цены в нелинейной оптимизации?

A: да, для непрерывных задач большинство решателей NLP могут предоставить двойные или теневые цены (scipy-решатели не делают этого afaik). Двойные не доступны для дискретных задач.

person Erwin Kalvelagen    schedule 28.09.2020
comment
Спасибо, Эрвин. Нашел эту ссылку для всех, кто заходил на эту страницу, чтобы понять MIQP. stackoverflow.com/questions/54288030/ - person Himanshu Singh; 29.09.2020