Pyomo优化投资/收入

2024-06-02 08:58:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Pyomo的新手,我正试图根据预算优化投资。
我有一个总预算,我想找到在不同媒体上分摊预算的最佳方法。
例如:总预算=5000-->;电视=3000,电影院=500,收音机=1500

我正在努力将预算与相应的收入“挂钩”。 这些媒体有不同的回报曲线(在达到一定预算之前最好投资于特定媒体,然后投资于其他媒体)。
不同媒体的收入通过如下函数返回:tv_1k_revenue = calculate_revenue(budget=1000, media="tv")
假设我唯一的限制是简化问题的总预算(我认为我可以管理其他限制)

以下是我目前的代码:

model = pyo.ConcreteModel(doc="Optimization model")

# Declaration of possible budgets
model.S1 = Set(initialize=[*df.TV_Budget.values])
model.tv_budget = Var(model.S1, initialize=0.0)
model.S2 = Set(initialize=[*df.Cinema_Budget.values])
model.cinema_budget = Var(model.S2, initialize=0.0)
model.S3 = Set(initialize=[*df.Radio_Budget.values])
model.radio_budget = Var(model.S3, initialize=0.0)

# Objective function
def func_objective(model):
    objective_expr = sum(model.tv_revenue +
                         model.cinema_revenue +
                         model.radio_revenue)
return objective_expr

model.objective = pyo.Objective(rule=func_objective, sense=pyo.maximize)

因此,我的问题是,我如何申报model.tv_收入、model.cinema_收入、model.radio_收入,以便优化电视、电影和广播预算,使电视、电影和广播产生的总收入最大化? 现在,我为每个媒体创建了一个带有预算和收入列的数据框,但最好的方法应该是使用我的calculate_revenue函数,并在每个媒体预算上设置bounds=(min_budget, max_budget)

谢谢你的帮助


Tags: dfmodelvartv媒体电视budgetvalues
2条回答

非常感谢@AirSquid
就是这样。
把熊猫扔到我的箱子里确实很有意义。
此外,是的,我的收入函数是非线性的。
我可以试着做一个线性近似,看看我能不能做到。 我打算将我的目标函数声明为:

def func_objective(model):
    objective_expr = sum([calculate_revenue(model.budget[media], media=media) for media in model.medias])
return objective_expr
model.objective = pyo.Objective(rule=func_objective, sense=pyo.maximize)

你知道我为什么不能这样申报吗

根据您提供的服务和您有限的经验,以下是我的建议

您似乎有预算和收入,而且这些预算和收入似乎是按媒体类型编制的。现在还不清楚你在索引方面做了什么。因此,我预计会出现以下情况:

model.medias = pyo.Set(initialize=['radio', 'tv', ... ])

model.budget = pyo.Var(model.medias, domain=pyo.NonNegativeReals)
...

pandas扔出窗外。这是一个很棒的pkg,但对建立模型没有多大帮助。尝试使用python字典保存常量&;参数。(如果这令人困惑,请参阅我的其他一些示例)

我敢打赌,你最终会遇到的问题是,你的收入函数可能是非线性的。正当我先从一个简单的线性近似开始,看看你能否使模型工作,然后考虑要么分段线性近似,要么使用某种非线性求解器。p>

=================== 编辑/补充信息

关于obj函数,不能只填充对返回值的非线性函数的引用。目标需要是一个有效的pyomo表达式(线性或非线性),由模型元素组成。我会从这样的事情开始

# media mix

import pyomo.environ as pyo

# data for linear approximations of form revenue = c1 * budget + c0

#           media      c0  c1
consts = {  'radio' : (4,  0.6),
            'tv'    : (12, 0.45)}

# a bunch of other parameters....??  limits, minimums, etc.


### MODEL

m = pyo.ConcreteModel('media mix')

### SETS
m.medias = pyo.Set(initialize=consts.keys())


### VARIABLES
m.budget = pyo.Var(m.medias, domain=pyo.NonNegativeReals)


### OBJ
m.obj = pyo.Objective(expr=sum(consts[media][1]*m.budget[media] + consts[media][0] for media in m.medias), 
                sense=pyo.maximize)

m.pprint()

产量:

1 Set Declarations
    medias : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :    2 : {'radio', 'tv'}

1 Var Declarations
    budget : Size=2, Index=medias
        Key   : Lower : Value : Upper : Fixed : Stale : Domain
        radio :     0 :  None :  None : False :  True : NonNegativeReals
           tv :     0 :  None :  None : False :  True : NonNegativeReals

1 Objective Declarations
    obj : Size=1, Index=None, Active=True
        Key  : Active : Sense    : Expression
        None :   True : maximize : 0.6*budget[radio] + 4 + 0.45*budget[tv] + 12

3 Declarations: medias budget obj

相关问题 更多 >