I have a function in python which looks like this:
import numpy as np
def fun(Gp,Ra,Mr,Pot,Sp,Mc,Keep):
if(Keep==True):
return(Pot*np.tanh((Gp+Ra+Mr+ Mc)*Sp ))
Assuming the following data:
import pandas as pd
dt_org = pd.DataFrame({"RA": [0.5, 0.8, 0.9],
"MR": [0.97, 0.95, 0.99],
"POT": [0.25, 0.12, 0.05],
"SP": [0.25, 0.12, 0.15],
"MC": [50, 75, 100],
"COUNTRY": ["GB", "IR", "GR"]
})
I have in total 100 GP and i want to allocate all of them properly
in order to maximize the objective_function:
under the restriction that all the 3 elements are positive
According to this post the scipy.optimize would be the way to go, but i am confused in order how to write the problem down
Update: my try
from scipy.optimize import minimize
y = {'A': {'RA': 0.5, 'MR': 0.97, 'POT': 0.25, 'SP': 0.25, 'MC': MC_1, 'keep': True},
'B': {'RA': 0.8, 'MR': 0.95, 'POT': 0.12, 'SP': 0.12, 'MC': MC_2, 'keep': True},
'C': {'RA': 0.9, 'MR': 0.99, 'POT': 0.05, 'SP': 0.15, 'MC': MC_3, 'keep': True}}
def objective_function(x):
return(
-(fun(x[0], Ra=y['A']['RA'], Mr=y['A']['MR'],
Pot=y['A']['POT'], Sp=y['A']['SP'],
Mc=y['A']['MC'], Keep=y['A']['keep']) +
fun(x[1], Ra=y['B']['RA'], Mr=y['B']['MR'],
Pot=y['B']['POT'], Sp=y['B']['SP'],
Mc=y['B']['MC'], Keep=y['B']['keep']) +
fun(x[2], Ra=y['C']['RA'], Mr=y['C']['MR'],
Pot=y['C']['POT'], Sp=y['C']['SP'],
Mc=y['C']['MC'], Keep=y['C']['keep']))
)
cons = ({'type': 'ineq', 'fun': lambda x: x[0] + x[1] + x[2] - 100})
bnds = ((0, None), (0, None), (0, None))
minimize(objective_function, x0=[1,1,1], args=y, method='SLSQP', bounds=bnds,
constraints=cons)
The problem now is that i get the error ValueError: Objective function must return a scalar, whereas the output of the fun function is a scalar
UPDATE 2 (after @Cleb comment) So now i changed the function in:
def objective_function(x,y):
temp = -(fun(x[0], Ra=y['A']['RA'], Mr=y['A']['MR'],
Pot=y['A']['POT'], Sp=y['A']['SP'],
Mc=y['A']['MC'], Keep=y['A']['keep']) +
fun(x[1], Ra=y['B']['RA'], Mr=y['B']['MR'],
Pot=y['B']['POT'], Sp=y['B']['SP'],
Mc=y['B']['MC'], Keep=y['B']['keep']) +
fun(x[2], Ra=y['C']['RA'], Mr=y['C']['MR'],
Pot=y['C']['POT'], Sp=y['C']['SP'],
Mc=y['C']['MC'], Keep=y['C']['keep']))
print("GP for the 1st: " + str(x[0]))
print("GP for the 2nd: " + str(x[1]))
print("GP for the 3rd: " + str(x[2]))
return(temp)
cons = ({'type': 'ineq', 'fun': lambda x: x[0] + x[1] + x[2] - 100})
bnds = ((0, None), (0, None), (0, None))
Now there are 2 problems:
1. the values of x[0],x[1],x[2] are really close to each other
- the sum of
x[0],x[1],x[2]is over 100
objective_function, you only passxbut noty; infunyou only pass parameters but nox(this function seems to be independent of x, that seems funky). And I also agree with sascha: an actual question would help to help you :)argsargument in theminimizefunction. The problem now is that i get the errorValueError: Objective function must return a scalar, whereas the output of thefunfunction is a scalar