Python中MemoryError: None含义解析及冲突检测运行差异原因咨询
问题描述
我的Python项目调用docplex并使用lazy constraints,直接运行时几秒后显示“Integer infeasible”;但使用冲突检测代码时,运行约90分钟后报错“MemoryError: None”。想了解两个问题:
- 该错误中的“None”代表什么,是否为内存不足导致;
- 为什么冲突检测代码会使模型表现不同,不会快速返回“Integer infeasible”。
冲突检测代码
refiner = ConflictRefiner() res = refiner.refine_conflict(model) res.display()
报错信息
--> lazy constraint callback called: #16 Traceback (most recent call last): File "C:\Users\zane\test\cplex_for_ARP.py", line 322, in solve_arc_routing res = refiner.refine_conflict(model) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\docplex\mp\conflict_refiner.py", line 428, in refine_conflict results = self._refine_conflict_local(mdl, context, preferences, groups) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\docplex\mp\conflict_refiner.py", line 471, in _refine_conflict_local return self_engine.refine_conflict(mdl, preferences, groups, parameters) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\docplex\mp\cplex_engine.py", line 2296, in refine_conflict cpx.conflict.refine(*cplex_def_grs) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\cplex_internal_subinterfaces.py", line 8761, in refine grppref, grpbeg, grpind, grptype) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\cplex_internal_procedural.py", line 2298, in refineconflictext check_status(env, status) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\cplex_internal_procedural.py", line 238, in __call__ _handle_cb_error(env, callback_exception) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\cplex_internal_procedural.py", line 210, in _handle_cb_error raise cberror MemoryError: None
解答
1. MemoryError: None的含义与原因
这里的None是CPLEX底层错误处理时未返回具体错误信息的占位值,本质就是内存不足。冲突检测过程中,CPLEX需要分析大量约束组合(包括lazy constraints的动态生成逻辑),内存占用远高于常规求解:
- 常规求解时,CPLEX快速判断整数不可行后就终止;
- 冲突检测需要遍历、验证各种约束子集,尝试找出最小冲突集,这个过程会生成大量中间数据,最终耗尽系统内存触发
MemoryError。
2. 冲突检测不快速返回Integer infeasible的原因
常规求解和冲突检测的核心逻辑完全不同:
- 常规求解:CPLEX求解整数规划时,先求解松弛问题,再通过分支定界、lazy约束回调逐步添加约束,一旦发现当前分支下无可行整数解,就快速返回“Integer infeasible”,无需遍历所有约束组合,找到不可行证据即停止。
- 冲突检测:
ConflictRefiner.refine_conflict的目标是找出最小的约束子集,使得该子集本身导致模型不可行,而非仅判断整体不可行。它需要:- 触发lazy约束回调生成所有相关约束;
- 反复构建子模型、验证子模型可行性;
- 逐步排除不参与冲突的约束。
整个过程的计算量和数据量远大于常规求解,因此不会像常规求解那样快速终止,反而会持续运行直到耗尽内存或完成分析。
内容的提问来源于stack exchange,提问作者Zane
相关产品推荐
相关产品推荐

