python - DoCplex 中的 Bass 模型:如何在约束中分配变量
问题描述
我正在尝试构建一个基于 Bass 模型的优化程序(见下文):
- 决策变量:p、m、q
- 问题:最小 RMSE
- 约束:
- Ft = (p + q(C(t-1)/m)(m - C(t-1))
- Et = Ft - St
其中 C(t) 是累计销售额,St 是实际销售额,Ft 是 t 期的预测销售额,Et 是误差项。
我似乎无法弄清楚如何编写将这些值分配给新变量的约束(并且不一定使用比较运算符)......
目前,我创建了一个 Bass_F 函数来执行上面的等式 Ft,以及一个计算 rmse 的 rmse 函数。我还编写了以下代码(我的实际销售额是变量 y,其中有 4 条记录):
import docplex.mp.model as cpx
opt_model = cpx.Model(name="Bass")
opt_model.continuous_var(name = "p")
opt_model.continuous_var(name = "q")
opt_model.continuous_var(name = "m")
F = [None]*4
E = [None]*4
opt_model.add_constraint_(F[0] = p*m)
opt_model.add_constraint_(E[0] = F[0] - y[0])
for i in range(1,len(F)):
opt_model.add_constraints_(F[i] = Bass_F(F[i-1], p, q, m))
opt_model.add_constraints_(E[i] = F[i] - y[i])
显然这给了我一个错误,即:
opt_model.add_constraint_(F[0] = p*m) ^
SyntaxError: keyword can't be an expression
任何人都可以帮忙吗?提前致谢!
解决方案
您不能像定义宏或类似的那样“定义”变量。你可以做的是:
opt_model.add_constraint_(F[0] == p*m)
opt_model.add_constraint_(E[0] == F[0] - y[0])
for i in range(1,len(F)):
opt_model.add_constraints_(F[i] == Bass_F(F[i-1], p, q, m))
opt_model.add_constraints_(E[i] == F[i] - y[i])
例如,这强制F[0]
与 相同p * m
。求解器引擎将在必要时F[0]
替换。p * m
您还可以在模型之外创建此类定义。也就是说,您可以这样做:
F = []
F.append(p * m)
在此之后,F[0]
是一个表达式,您可以在想要引用时使用p * m
。所以你的代码可以写成(替换M
为适当的限制)
F = [None] * M
E = [None] * M
F[0] = p * m
E[0] = F[0] - y[0]
for i in range(1, M):
F[i] = Bass_F(F[i - 1], p, q, m)
E[i] = F[i] - y[i]
有了它,您可以使用F[i]
andE[i]
作为相应表达式的“快捷方式”。
不过,据我所知,您的模型存在问题。你定义
Ft = (p + q(C(t-1)/m)(m - C(t-1))
这需要除以决策变量m
。不支持除以决策变量。你把两边都乘以m
摆脱它。但是,由此产生的约束可能是非凸的。这也不支持。您可能必须将此约束线性化。
推荐阅读
- rust - 有没有办法将数组传递给 glium 中的着色器?
- android - Android P - NetworkSecurityPolicy.isCleartextTrafficPermitted false 当 network-security-config base-config cleartextTrafficPermitted true
- angular - 未找到未定义的组件工厂。您是否将其添加到 @NgModule.entryComponents
- java - 杰克逊忽略嵌套属性
- c# - C# 异步处理 N 个事件
- r - ggplot2 - 如果为负,则反转调色板
- yaml - YAML中波浪字符〜的目的是什么?
- graphql - 使用 npm 运行 postgraphile
- android - Visual Studio 中的 Android 模拟器:连接到 Internet 时的连接不安全
- php - 如何在 laravel nova 中使用用户名而不是电子邮件登录?