我在python中有一个函数,如下所示:
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 ))
假设以下数据:
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"]
})
我总共 100 GP
我希望正确分配所有
为了最大化objective_function
:
在所有 3个元素正面
的限制下根据this帖子,scipy.optimize
将是要走的路,但我很困惑,以便如何解决问题
更新:我的尝试
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)
现在的问题是我收到错误ValueError: Objective function must return a scalar
,而fun
函数的输出是标量
更新2(在@Cleb评论之后) 所以现在我改变了函数:
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))
现在有两个问题:
1. x[0],x[1],x[2]
的值非常接近
x[0],x[1],x[2]
的总和超过100 答案 0 :(得分:1)
关于您的目标函数存在一个普遍问题,它解释了为什么您获得的值彼此非常接近;它将在下面讨论。
如果我们首先看一下技术方面,以下情况对我来说很好:
'use strict';
process.env.DEBUG = 'actions-on-google:*';
const ActionsSdkApp = require('actions-on-google').ActionsSdkApp;
const functions = require('firebase-functions');
const NO_INPUTS = [
'Padon me, I didn\'t hear that.',
'If you\'re still there, would you please say that again.',
'We can stop here. Good luck with your shopping.'
];
const SHOPPING_INTENT = 'SHOPPING';
exports.shopStrollers = functions.https.onRequest((request, response) => {
const app = new ActionsSdkApp({request, response});
function handleMainInput(app) {
console.log('mainIntent is invoked!');
console.log("The input is %s", app.getRawInput());
console.log("It seems that %s is never invoked!", app.StandardIntents.TEXT)
let inputPrompt = app.buildInputPrompt(true, '<speak>Hi! <break time="1"/> ' +
'I can help with finding strollers. How old is your baby?</speak>', NO_INPUTS);
app.ask(inputPrompt);
}
function handleTextInput(app) {
console.log('TEXT is invoked!');
console.log("The input is %s", app.getRawInput());
console.log("Finally TEXT HANDLER got invoked")
if (app.getRawInput() === 'bye') {
app.tell('Hope you found the service helpful and best of luck with your shopping, please come back again, goodbye!');
} else {
let inputPrompt = app.buildInputPrompt(true, '<speak>Here is a list of top' +
' <say-as interpret-as="ordinal">10</say-as>strollers' +
', say next for the next batch</speak>', NO_INPUTS);
app.ask(inputPrompt);
}
}
let actionMap = new Map();
actionMap.set(SHOPPING_INTENT, handleTextInput);
actionMap.set(app.StandardIntents.MAIN, handleMainInput);
actionMap.set(app.StandardIntents.TEXT, handleTextInput);
app.handleRequest(actionMap);
});
这将打印
import numpy as np
from scipy.optimize import minimize
def func(Gp, Ra, Mr, Pot, Sp, Mc, Keep):
if Keep:
return Pot * np.tanh((Gp + Ra + Mr + Mc) * Sp)
def objective_function(x, y):
temp = -(func(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']) +
func(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']) +
func(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']))
return temp
y = {'A': {'RA': 0.5, 'MR': 0.97, 'POT': 0.25, 'SP': 0.25, 'MC': 50., 'keep': True},
'B': {'RA': 0.8, 'MR': 0.95, 'POT': 0.12, 'SP': 0.12, 'MC': 75., 'keep': True},
'C': {'RA': 0.9, 'MR': 0.99, 'POT': 0.05, 'SP': 0.15, 'MC': 100., 'keep': True}}
cons = ({'type': 'ineq', 'fun': lambda x: x[0] + x[1] + x[2] - 100.})
bnds = ((0., None), (0., None), (0., None))
print(minimize(objective_function, x0=np.array([1., 1., 1.]), args=y, method='SLSQP', bounds=bnds, constraints=cons))
如您所见, fun: -0.4199999999991943
jac: array([ 0., 0., 0.])
message: 'Optimization terminated successfully.'
nfev: 6
nit: 1
njev: 1
status: 0
success: True
x: array([ 33.33333333, 33.33333333, 33.33333333])
很好地总结为x
。
如果您现在将100
更改为例如
bnds
然后结果将是
bnds = ((40., 50), (0., None), (0., None))
再次,满足约束。
人们还可以看到目标值是相同的。这似乎是由于 fun: -0.419999999998207
jac: array([ 0., 0., 0.])
message: 'Optimization terminated successfully.'
nfev: 6
nit: 1
njev: 1
status: 0
success: True
x: array([ 40., 30., 30.])
和Mc
非常大,因此Gp
将始终只返回np.tanh
。这意味着您始终只会在1.0
中为Pot
中的所有三个词典返回值func
。如果总结三个相应的值
y
确实得到了由优化确定的值0.25 + 0.12 + 0.05
。