如何通过Python向CPLEX OPL模型多场景输入并存储求解结果?
解决CPLEX OPL内存访问违规问题并实现多场景批量求解
一、修复OPL约束的内存访问错误
你遇到的Windows fatal exception: access violation是因为约束中的遍历逻辑错误:damage_Nodes是tuple damage_Node类型的集合,每个元素包含scenario和value(受损节点集合),直接用n作为StatusLine的节点索引会导致类型不匹配,触发内存访问异常。
修正后的OPL约束代码:
forall (rc in Repaircrew){ // 遍历每个场景的受损节点元组 forall (dn in damage_Nodes){ // 遍历当前场景下的每一个受损节点 forall (n in dn.value){ forall (s in Slot:s<=N_T-1){ StatusLine[rc][n][s] <= StatusLine[rc][n][s+1]; } } } }
二、多场景批量求解的Python实现
以下代码可批量处理5个场景,自动输入各场景受损节点集,并将结果统一存储:
from doopl.factory import create_opl_model # 定义5个场景的受损节点数据,格式为(场景编号, 受损节点集合) scenarios_damage_nodes = [ (1, {8, 9, 12, 16, 19, 23, 24, 27, 30}), (2, {5, 7, 10, 14, 20}), (3, {3, 6, 11, 15, 18, 22}), (4, {1, 2, 4, 13, 17, 21, 25}), (5, {26, 28, 29, 31, 32}) ] model_path = "C:/Users/VGFD/opl/MEG_Case3/MEG_Case3.mod" # 存储所有场景的求解结果 all_scenario_results = {} for scenario_id, damage_nodes in scenarios_damage_nodes: print(f"处理场景 {scenario_id}...") with create_opl_model(model=model_path) as opl: # 输入当前场景的受损节点数据,匹配OPL的tuple定义格式 opl.set_input("damage_Nodes", [(scenario_id, damage_nodes)]) opl.run() # 获取当前场景的求解结果 decision_vars = opl.get_decision_variables() objective_value = opl.get_objective_value() # 将结果存入字典,按场景编号索引 all_scenario_results[scenario_id] = { "decision_variables": decision_vars, "objective_value": objective_value } print(f"场景 {scenario_id} 完成,目标值: {objective_value}") # 示例:输出所有场景的目标值 print("\n所有场景求解结果汇总:") for scenario_id, result in all_scenario_results.items(): print(f"场景 {scenario_id} 目标值: {result['objective_value']}")
关键说明
- 每个场景通过
with上下文管理器单独创建OPL模型实例,自动释放资源,避免内存泄漏 - 结果存储在
all_scenario_results字典中,可根据需求进一步导出到文件或做后续分析 - 确保OPL模型中
StatusLine变量的维度为[Repaircrew][节点编号][Slot],与修正后的约束逻辑匹配
内容的提问来源于stack exchange,提问作者Vikas Gautam
相关产品推荐
相关产品推荐

