目前,我正在Python Gekko建立经济模型:
m = GEKKO()
m.time = np.arange(0, 200, 1)
#define the variables
consumption = m.Var()
tax = m.Var()
disposable_income = m.Var()
(...)
#define the parameters
government_spending = m.Param(value=20)
interest_rate = m.Param(value=0.05)
tax_rate = m.Param(value=0.2)
(...)
#define lagged values of bond_price and bond_holding
m.delay (bond_price, bond_price_previous, steps=1)
m.delay (bond_holding, bond_holding_previous, steps=1)
#define the equations of the model
m.Equation(money_holding == wealth - bill_holding_household - bond_value)
m.Equation(money_demand == expected_wealth - bill_holding_household - bond_value)
m.Equation(bill_holding_central_bank == bill_supply - bill_holding_household)
m.Equation(bill_supply.dt() == (government_spending + coupon_rate * bill_supply + bond_holding) - (tax + coupon_rate * bill_holding_central_bank) - bond_price * bond_holding.dt())
m.Equation(money_supply.dt() == bill_holding_central_bank.dt())
(...)
m.Equation(coupon_rate == interest_rate)
m.Equation(bond_return == 1 / bond_price)
m.options.IMODE=4
m.solve(disp=True, DIAGLEVEL=2)
上面的模型由Gekko成功解决。自由度(DOF)= 0,解决方案是预期的。
m.Equation(bond_price.dt() == bond_price_increase_step * decision_increase_bond_price)
m.Equation(decision_increase_bond_price == m.if2(target_proportion - ceiling_target_proportion, 0, 1))
m.Equation(target_proportion == bond_value / (bond_value + bill_holding_household))
使BOND_PRICE增加。这三个方程式的问题是,通过引入IF2,DOF现在大于0。确切地说,DOF现在为398,是2倍199,是M.Time定义的系统中时间段的数量。这可能意味着系统中的变量比方程数多两个变量。
这种正DOF并不是由于我没有定义某些变量。我也非常有信心DOF是由IF2引起的,因为从我的实验中,删除和添加IF2会减少并增加我的DOF。 我对我的情况有一些疑问:
为什么IF2添加两个额外的变量?原因是否适用于Gekko中的其他逻辑功能(最大,最低,IF3等)?
可以在Gekko中实现此类二进制开关,以确保dof = 0?the是完整的代码:(该模型应在没有三个新方程及其关联的变量和参数的情况下运行)
from gekko import GEKKO
m = GEKKO()
m.time = np.arange(0, 200, 1)
consumption = m.Var()
tax = m.Var()
disposable_income = m.Var()
money_holding = m.Var()
money_demand = m.Var()
money_supply = m.Var()
income = m.Var()
bill_holding_household = m.Var()
wealth = m.Var()
coupon_rate = m.Var()
bill_supply = m.Var()
bill_holding_central_bank = m.Var()
expected_disposable_income = m.Var()
expected_wealth = m.Var()
bond_holding = m.Var()
bond_return = m.Var()
bond_value = m.Var()
bond_price_previous = m.Var()
bond_holding_previous = m.Var()
capital_gain = m.Var()
bond_price = m.Var(value=10)
decision_increase_bond_price = m.Var()
target_proportion = m.Var()
government_spending = m.Param(value=20)
interest_rate = m.Param(value=0.05)
tax_rate = m.Param(value=0.2)
marginal_propensity_to_consume_income = m.Param(value=0.6)
marginal_propensity_to_consume_wealth = m.Param(value=0.4)
expected_disposable_income_adjustment_speed = m.Param(value=0.5)
expected_wealth_adjustment_speed = m.Param(value=0.5)
portion_household_expect_increased_return = m.Param(value=0.1)
bond_price_increase_step = m.Param(value=0.01)
ceiling_target_proportion = m.Param(value=0.505)
floor_target_proportion = m.Param(value=0.495)
lambda20 = m.Param(value=0.35)
lambda22 = m.Param(value=1)
lambda23 = m.Param(value=1)
lambda24 = m.Param(value=0.03)
lambda30 = m.Param(value=0.3)
lambda32 = m.Param(value=1)
lambda33 = m.Param(value=1)
lambda34 = m.Param(value=0.03)
m.delay (bond_price, bond_price_previous, steps=1)
m.delay (bond_holding, bond_holding_previous, steps=1)
m.Equation(money_holding == wealth - bill_holding_household - bond_value)
m.Equation(money_demand == expected_wealth - bill_holding_household - bond_value)
m.Equation(bill_holding_central_bank == bill_supply - bill_holding_household)
m.Equation(bill_supply.dt() == (government_spending + coupon_rate * bill_supply + bond_holding) - (tax + coupon_rate * bill_holding_central_bank) - bond_price * bond_holding.dt())
m.Equation(money_supply.dt() == bill_holding_central_bank.dt())
m.Equation(wealth.dt() == disposable_income - consumption + capital_gain)
m.Equation(expected_disposable_income.dt() == expected_disposable_income_adjustment_speed * (disposable_income - expected_disposable_income))
m.Equation(expected_wealth.dt() == expected_wealth_adjustment_speed * (wealth - expected_wealth) + expected_disposable_income - consumption)
m.Equation(capital_gain == bond_holding_previous * (bond_price - bond_price_previous))
m.Equation(consumption == marginal_propensity_to_consume_income * expected_disposable_income + marginal_propensity_to_consume_wealth * wealth)
m.Equation(disposable_income == income + coupon_rate * bill_holding_household + bond_holding - tax)
m.Equation(income == consumption + government_spending)
m.Equation(tax == tax_rate * (income + coupon_rate * bill_holding_household + bond_holding))
m.Equation(bill_holding_household == expected_wealth * (lambda20 + lambda22 * coupon_rate + lambda23 * bond_return + lambda24 * (expected_disposable_income/expected_wealth)))
m.Equation(bond_value == expected_wealth * (lambda30 + lambda32 * coupon_rate + lambda33 * bond_return + lambda34 * (expected_disposable_income/expected_wealth)))
m.Equation(bond_holding == bond_value / bond_price)
m.Equation(coupon_rate == interest_rate)
m.Equation(bond_return == 1 / bond_price)
m.Equation(bond_price.dt() == bond_price_increase_step * (decision_increase_bond_price))
m.Equation(decision_increase_bond_price == m.if2(target_proportion - ceiling_target_proportion, 0, 1))
m.Equation(target_proportion == bond_value / (bond_value + bill_holding_household))
m.options.IMODE=4
m.solve(disp=True)
decision_increase_bond_price * (ceiling_target_proportion - target_proportion) <= 0
介绍逻辑条件(例如
if2
或
if3
中)需要开关Imode至
6(动态优化)。这是因为逻辑条件引入了需要解决优化技术的其他变量和约束。
函数是使用互补性约束的IF-ELSE语句。它引入了其他内部变量和方程式,以确保可不同的性能。同样适用于其他逻辑函数,例如
gekko
,
if2(condition, value_if_condition<0, value_if_condition>0)
,
max2
,max3
和min2
。
min3
由complementarity限制组成,可以通过非线性编程(NLP)求解器来解决。
if3
使用二进制变量,需要一个混合式求解器,并且更可靠但计算昂贵。 正确实现此二进制开关: 旋转到Imode =6
if2
if3
而不是
m.options.IMODE = 6
,因为if3
明确引入了二进制变量,并在开关条件下强制执行没有鞍点的开关,该切换点与if2
if3
deSign优化课程中可用的有关互补性约束和二进制变量形式的辅助详细信息。