如何在Gekko中强制优化解包含向量特定元素
问题描述
需要从长度为n的向量中选出最多p条记录的最优组合,同时强制要求向量中由holiday_labor_day_flag标记的劳动节元素必须被纳入解集。当前用二进制向量x7标记元素是否被选中,已通过simu_total_volume构建目标函数最大化总收益,且有约束sum(x7)<=p限制选中数量,但无法实现强制纳入特定元素的要求。
解决方案
核心是直接对标记选中状态的二进制变量x7添加约束,无需额外引入x8变量。具体步骤如下:
定位劳动节元素的索引
从el_cppg['holiday_labor_day_flag']中找到值为1的元素对应的唯一索引:labor_day_idx = el_cppg[el_cppg['holiday_labor_day_flag'] == 1].index[0]添加强制选中约束
直接约束对应索引的x7变量必须为1,确保该元素被纳入解集:m.Equation(x7[labor_day_idx] == 1)调整选中数量约束(可选)
- 若需求是恰好选p条记录,将原约束改为:
m.Equation(sum(x7) == p) - 若需求是最多选p条记录且必须包含劳动节元素,保留原
sum(x7)<=p即可,此时剩余最多可选中p-1条其他元素。
- 若需求是恰好选p条记录,将原约束改为:
修改后的完整代码片段
# 获取劳动节元素的索引 labor_day_idx = el_cppg[el_cppg['holiday_labor_day_flag'] == 1].index[0] simu_total_volume = [m.Intermediate(( (m.max2(0,base_volume[i]*(m.exp(total_vol_fedi[i])-1)) * x3[i] + m.max2(0,base_volume[i]*(m.exp(total_vol_feao[i])-1)) * x4[i] + m.max2(0,base_volume[i]*(m.exp(total_vol_diso[i])-1)) * x5[i] + m.max2(0,base_volume[i]*(m.exp(total_vol_tpro[i])-1)) * x6[i]) + base_volume[i]) * x7[i]) for i in range(n)] # 强制劳动节对应的元素必须被选中 m.Equation(x7[labor_day_idx] == 1) # 限制选中记录数量(最多p条,若需恰好p条则改为sum(x7)==p) m.Equation(sum(x7) <= p) m.Maximize(m.sum(simu_total_volume)) m.options.SOLVER=1 try: m.solve(disp = True) except: continue
说明
原代码中labor_day相关变量和约束可直接删除,无需额外变量标记劳动节元素,直接操作x7即可实现强制选中逻辑。
内容的提问来源于stack exchange,提问作者datadude558
相关产品推荐
相关产品推荐

