You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在vast.ai云Bash环境运行Pulp时出现求解报错问题

整数规划求解报错(n>30时)修复方案

环境配置

已在vast.ai的Bash环境中完成以下安装:

sudo apt-get install software-properties-common
sudo apt-add-repository universe
sudo apt-get update
sudo apt-get install python3-pip
sudo pip install pulp
sudo apt-get install glpk-utils
sudo apt-get install coinor-cbc

问题现象

当参数n<25时,程序正常运行,可返回解或状态值-1(无解);但n>30时,执行报错,错误栈如下:

Traceback (most recent call last):
  File "Test.py", line 58, in <module>
    Problem.solve()
  File "/usr/local/lib/python3.6/dist-packages/pulp/pulp.py", line 1913, in solve
    status = solver.actualSolve(self, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/pulp/apis/coin_api.py", line 137, in actualSolve
    return self.solve_CBC(lp, **kwargs)
  File "/usr/local/lib/python3.6/dist-packages/pulp/apis/coin_api.py", line 208, in solve_CBC
    + self.path
pulp.apis.core.PulpSolverError: Pulp: Error while trying to execute, use msg=True for more details/usr/local/lib/python3.6/dist-packages/pulp/solverdir/cbc/linux/64/cbc

核心代码

from pulp import LpVariable, LpInteger, LpProblem, LpMaximize, lpSum

n = int(input())
m = int(input())
r = 3 * m - 2

# Vertices
Triple = []
for i in range(n):
    for j in range(n):
        for k in range(n):
            Triple.append((i,j,k))

# Variables
Variable = LpVariable.dicts("Variables",[triple for triple in Triple],0,1,LpInteger)

# Objective
Problem = LpProblem("Problem",LpMaximize)
Problem += Variable[(0,0,0)]

# Constraints
# 1
Exclusion = []
for i in range(n):
    for j in range(n):
        for k in range(n - 1):
            for l in range(k + 1,n):
                Exclusion.append(((i,j,k),(i,j,l)))
                Exclusion.append(((i,k,j),(i,l,j)))
                Exclusion.append(((k,i,j),(l,i,j)))

for exclusion in Exclusion:
    s = exclusion[0]
    t = exclusion[1]
    Problem += Variable[s] + Variable[t] <= 1

# 2
for i in range(n):
    Problem += lpSum([Variable[(i,j,k)]] for j in range(n) for k in range(n)) == m
    Problem += lpSum([Variable[(j,i,k)]] for j in range(n) for k in range(n)) == m
    Problem += lpSum([Variable[(j,k,i)]] for j in range(n) for k in range(n)) == m

# 3
for i in range(n):
    for j in range(n):
        for k in range(n):
            Ones = [triple for triple in Triple if triple[0] == i or triple[1] == j or triple[2] == k]
            Problem += lpSum([Variable[(triple)]] for triple in Ones) >= r
    
# Result
Problem.solve()

s = Problem.status

if s == 1:
    Triangle = []
    for triple in Triple:
        if Variable[triple].value() == 1:
            Triangle.append(triple)
    print(Triangle)
else:
    print(s)

修复方案

1. 启用详细日志定位具体错误

修改求解代码,添加msg=True参数获取CBC求解器的详细输出,明确错误原因(如内存不足、求解器路径异常等):

Problem.solve(msg=True)

2. 优化问题规模,减少冗余计算

  • 约束1优化:当前Exclusion列表存在大量重复约束,可通过集合去重减少约束数量:
    Exclusion = set()
    for i in range(n):
        for j in range(n):
            for k in range(n - 1):
                for l in range(k + 1,n):
                    Exclusion.add(((i,j,k),(i,j,l)))
                    Exclusion.add(((i,k,j),(i,l,j)))
                    Exclusion.add(((k,i,j),(l,i,j)))
    Exclusion = list(Exclusion)
    
  • 约束3优化:使用容斥原理替代遍历所有Triple,避免生成庞大的Ones集合,节省内存:
    for i in range(n):
        for j in range(n):
            for k in range(n):
                # 容斥原理计算:行i + 列j + 层k - 行i列j交集 - 行i层k交集 - 列j层k交集 + 行i列j层k交集
                row_i = lpSum(Variable[(i, x, y)] for x in range(n) for y in range(n))
                col_j = lpSum(Variable[(x, j, y)] for x in range(n) for y in range(n))
                layer_k = lpSum(Variable[(x, y, k)] for x in range(n) for y in range(n))
                row_col = lpSum(Variable[(i, j, y)] for y in range(n))
                row_layer = lpSum(Variable[(i, x, k)] for x in range(n))
                col_layer = lpSum(Variable[(x, j, k)] for x in range(n))
                triple_intersect = Variable[(i,j,k)]
                Problem += row_i + col_j + layer_k - row_col - row_layer - col_layer + triple_intersect >= r
    

3. 调整求解器参数或切换求解器

  • 配置CBC求解器参数:设置时间限制、允许路径等参数,避免无限制占用资源:
    from pulp import CBC_CMD
    solver = CBC_CMD(maxSeconds=300, msg=True, allowPaths=True)
    Problem.solve(solver)
    
  • 切换到GLPK求解器:若CBC因内存问题崩溃,可尝试使用GLPK求解器:
    from pulp import GLPK
    Problem.solve(GLPK(msg=True))
    

4. 检查系统资源

在vast.ai实例中执行free -h查看内存使用情况,当n>30时,变量数为n³(n=30时达27000个),约束量更是呈指数级增长,若内存不足,需升级实例的内存配置。

内容的提问来源于stack exchange,提问作者Bertrand Haskell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:43:14