如何在求解过程中调试大多数错误

在这里,我将列出多年来使用 PuLP 解决问题和帮助他人解决问题时的主要问题和建议。可以通过 PR 添加更多答案。

提供反馈和寻求帮助

寻求帮助或报告问题的两种方式是:

  1. PuLP Github 讨论页面: https://github.com/coin-or/pulp/discussions

  2. Stack Overflow pulp 标签: https://stackoverflow.com/questions/tagged/pulp

当然,这些网站上已经存在的提问/问题(及其答案/解决方案)通常包含足够的信息来解决或理解该问题。因此,仔细查看旧的提问和问题是强烈推荐的。

在寻求帮助时,需要考虑几件事情,其中一些是任何项目共有的,而另一些则是 PuLP 特有的。一般性的建议(尽管非常重要):

  1. 始终提交一个最小可复现的示例(如何操作请见此处)。

  2. 查看 这个视频 了解如何提问。虽然针对的是另一种编程语言,但信息和建议都非常好。

现在,具体到 PuLP:

  1. msg=1 参数传递给求解器,即 prob.solve(PULP_CBC_CMD(msg=1))。这将为您提供有关错误的更多信息。在寻求帮助时分享这些信息。

  2. 如果可能,请分享模型的导出版本。查看 这里 了解如何导出模型。

  3. 或者,分享你的模型的 mps 版本。要生成一个,使用 writeMPS()

其他也有用的信息:

  1. pulp 的版本。

  2. 你是如何安装 pulp 的(通过 pypi,还是从 github)。

  3. 使用了什么操作系统。

  4. 正在使用的求解器版本(例如,CPLEX 12.8)。

尝试执行 cbc.exe 时出错

完整的错误信息通常类似于 pulp.solvers.PulpSolverError: Pulp: 在尝试执行 PATH_TO_CBC/cbc.exe 时出错

默认的求解器是CBC,通过命令行运行。

  1. 首先,将 msg=1 参数传递给求解器,以获取更多信息。

  2. 检查数字的精度。如果你有非常大的数字(精度很高),这通常会导致求解器出现问题。例如,永远不要在你的问题中使用 100000000000 这样的参数。特别是如果你还有一个 1200.09123642123 这样的参数。如果你不需要小数,在建模时将你的值四舍五入。

  3. 重复的变量/约束。如果你有在*所有*约束和目标函数中具有相同系数的变量,这是一个问题。同样,如果你有两个约束具有完全相同的变量和系数。

  4. 内存问题。有时你的电脑会内存不足。检查是否是这种情况。

  5. python32 vs python64。有时你使用的是32位版本的python,即使你的电脑是64位的。如果可能的话,尽量使用64位版本,因为它能处理更多的内存。

  6. 使用 PuLP 生成 mps 文件 并像这样直接传递给 cbc.exe 可执行文件。

  7. Anaconda/ conda/ jupyter notebooks 见下文。

cbc.exe mpsfile.mps

然后看看你会得到什么信息。

  1. 最后,有时你可能想用更新的 CBC 版本来尝试 PuLP。为此,下载 CBC 二进制文件并将路径传递给 PuLP。

不可行问题

  1. 添加松弛变量。如 这个SO帖子 所述。

  2. 去掉约束条件,看看问题是否变得可行。

  3. 生成 lp 文件 writeLP() 用于问题,并使用文本编辑器打开它以查看约束是否正确构建。

  4. 检查求解器日志以获取有关涉及的约束或变量的额外信息。日志可以通过传递 msg= 作为参数查看,或在某些情况下通过 logPath 参数导出。

Jupyter 笔记本 / Anaconda / conda 问题

默认求解器(CBC)出现了几个无法工作的问题,错误如下:

pulp.solvers.PulpSolverError: Pulp: 在尝试执行 PATH_TO_CBC/cbc.exe 时发生错误

Pulp: 尝试执行时出错,使用 msg=True 获取更多详情

这可能是由以下因素的组合造成的:

  • 不支持通过 conda / anaconda 安装 PuLP,因此可能会带来自身的问题。请按照文档中的说明安装 pulp。

  • 显然,Jupyter笔记本有时会在没有访问PuLP安装文件夹权限的用户会话中运行。这使得无法访问默认的求解器二进制文件。要解决这个问题,尝试在用户目录中安装pulp,或者在启动jupyter笔记本时给予足够的权限。

这些情况的例子中,有些是固定的: