简介:《Excel求解线性规划详解》是一份面向Excel初学者、经管类学生及需要处理生产计划、投资组合优化与资源分配问题的职场用户的操作型文档,重点讲解如何借助“规划求解”加载宏完成线性规划建模与求解。压缩包内仅含1个doc文件,约3.5MB,篇幅集中于功能认知、宏的加载与卸载、目标单元格和可变单元格设置、约束条件增删、求解参数解释及完整操作步骤,便于按章节查阅。已有291人学习,适合作为课堂例证或办公实战的速查材料。读者可从中掌握最大值、最小值与指定值目标的设置方法,理解整数、二进制等约束的应用边界,并熟悉最长运算时间、迭代次数、精度、收敛度、线性模型等选项的含义,从而减少建模试错,提升用Excel求解线性规划问题的效率。
1. 从「数据」选项卡里找不到规划求解说起:这套环境到底要装什么
上周帮一个做生产排程的开发者看表,他把 Excel 求解线性规划的模型发过来,说在自己机器上点「求解」能出结果,换到新装的笔记本上,「数据」选项卡翻了两遍也没见到「规划求解」。这不是文件坏了,是加载宏没装——规划求解从来不是 Excel 的默认组件,它挂在 Office 安装程序的「Excel 加载宏」下面,装 Office 时没勾,装完就没有。这套环境的门槛不在数学,在「装没装、勾没勾、勾上有没有被拦」这三件事。装不好最典型的后果是模型建得再漂亮也点不动求解,或者点了求解弹一句「找不到可行解」,其实只是约束写错了一格。下面按我自己复现的顺序走:先清点版本和文件,再勾加载项,然后逐个参数配到位,最后拿一个小模型验证跑通。
2. 装前清点:Excel 版本、位数与加载宏文件的落点
动手之前先花五分钟把环境摸清楚。规划求解这套东西表面上是 Excel 里多一个按钮,底下其实是「一个加载宏工作簿 + 一个计算引擎 DLL」的组合,版本不对、位数不对、文件没落盘,后面所有步骤都是白费。我见过太多人一上来就重装 Office,装完发现按钮还是没有,因为问题压根不在安装包上。
2.1 入口在哪:从「工具」菜单到「数据」选项卡的四次搬家
规划求解的入口位置随版本变过好几轮,照着老教程找新界面,十有八九会卡在第一步。早期版本(2003 及更早)在「工具」菜单里直接有「加载宏」,勾选之后「工具」菜单下多出「规划求解」;2007 把入口挪到了左上角的圆形 Office 按钮,路径是「Excel 选项」→「加载项」;2010 之后这个圆按钮被取消,改成「文件」→「选项」→「加载项」,一直沿用到现在;Mac 版则一直在「工具」菜单下的「Excel 加载项」里。
| Excel 版本 | 加载项入口 | 求解按钮位置 | 注意点 |
|---|---|---|---|
| 2003 及更早 | 工具 → 加载宏 | 工具 → 规划求解 | 无功能区,菜单直出 |
| 2007 | Office 按钮 → Excel 选项 → 加载项 | 数据选项卡 → 分析组 | 必须先点「转到」 |
| 2010–2019 | 文件 → 选项 → 加载项 | 数据选项卡 → 分析组 | 加载项名多为「规划求解加载项」 |
| 365 订阅版 | 文件 → 选项 → 加载项 | 数据选项卡 → 分析组 | 名称随语言包变化 |
| Mac 2016 及以后 | 工具 → Excel 加载项 | 数据选项卡 | 文件名同样以 SOLVER 开头 |
很多人反馈「按步骤点了但没有规划求解这一项」,问题往往出在「管理」下拉框还停在「COM 加载项」上。规划求解属于「Excel 加载项」,必须先把下拉框切过去,列表里才会出现它。这一步在 2007 的界面里对应的是先点「转到」,弹出「加载宏」对话框再勾选,顺序错了就看不到东西。
2.2 位数要对上:SOLVER.XLAM 与 SOLVER.DLL 是两套文件
规划求解在磁盘上是成对出现的:SOLVER.XLAM是加载宏工作簿,负责界面、参数对话框和结果报告;SOLVER.DLL才是真正跑单纯形法和分支定界的那颗引擎。这两份文件都分 32 位和 64 位,混用会直接报错或者加载后点求解没反应。
确认位数最简单的办法是「文件」→「账户」→「关于 Excel」,弹窗第一行会写明是 32 位还是 64 位;也可以在任务管理器里看 Excel 进程名后面有没有标注「(32 位)」。这一步很重要,因为如果你打算从别的机器拷贝文件过来救急,拷错位数是无效的,加载项列表里会显示名字但勾上之后功能区不出现按钮,属于典型的玄学故障。
2.3 默认安装漏勾了这一项,怎么补回来
Office 的默认安装策略只装常用组件,宏和加载项属于可选项,很多时候压根没释放到磁盘。补装不需要重下完整安装包,控制面板里找到已安装的 Office 条目,右键「更改」,选「添加或删除功能」,展开「Excel」子树,把「加载宏」下的「规划求解加载项」设成「从本机运行」,然后继续。整个过程只补释放缺的文件,几分钟就完事。
如果这一步弹出「找不到安装源」,说明本地缓存被清理过,需要指定安装介质或镜像里的源目录。我一般会先看一眼缓存目录还在不在,不在的话直接挂载原始镜像,比到处搜安装包省事。装完不要急着开 Excel,先做下一步的文件确认。
2.4 一条命令确认文件到没到位
图形界面点完不代表文件真落盘了,尤其是从旧版本升级上来的机器,注册表里残留的路径可能指向一个已经不存在的目录。用 PowerShell 扫一遍最直接:
# 在 64 位和 32 位程序目录下递归找规划求解相关文件 $roots = @($env:ProgramFiles, ${env:ProgramFiles(x86)}) | Where-Object { $_ -and (Test-Path $_) } Get-ChildItem -Path $roots -Filter "SOLVER.*" -Recurse -ErrorAction SilentlyContinue | Select-Object FullName, Length, LastWriteTime | Format-Table -AutoSize-Recurse会扫整个程序目录,机械硬盘上可能要等十几秒,想快一点可以把-Path收窄到 Office 的安装根目录。-ErrorAction SilentlyContinue用来跳过没有访问权限的文件夹,不加这个参数会刷一屏红色报错。输出里同时出现.XLAM和.DLL两个文件、且时间戳一致,才说明这份安装是完整的;只出现其中一个,或者时间戳差了几年,基本可以判定是升级残留,按 2.3 的步骤补装。
提示:程序目录默认只读,不要直接把 XLAM 拖进去替换,权限和签名校验都会让加载失败。需要放自定义加载宏时,用户级目录才是正确位置。
清点做完,环境具备继续装的条件了。接下来才是真正把按钮变出来。
3. 加载规划求解:从加载项对话框到功能区出现按钮
文件在磁盘上,只能说明具备加载条件,不等于已经注册到 Excel 里。加载这一步要做的是把SOLVER.XLAM登记进当前用户的加载项列表,让 Excel 启动时去加载它。这一章把图形界面、VBA 两条路都走一遍,再补上「勾了又消失」的三种拦截场景。
3.1 图形界面加载:四步里最容易漏的是「转到」
在 2010 及以后的版本里,完整路径是这样的:先点「文件」→「选项」→「加载项」,在窗口底部的「管理」下拉框里选中「Excel 加载项」,点旁边的「转到」,弹出「加载宏」对话框,在「可用加载宏」列表里勾上规划求解,最后确定。很多人卡在第三步,因为「加载项」页面里那个列表本身是只读的,看着有内容但勾不动,必须点「转到」进到真正的勾选对话框。
2007 的路径稍短:左上角 Office 按钮 →「Excel 选项」→「加载项」→「转到」→ 勾选 → 确定。注意 2007 的对话框里「规划求解加载项」和「数据分析加载项」经常挨在一起,顺手两个都勾了也正常,但要想清楚代价——每多一个加载项,Excel 冷启动就多一次工作簿解析,机械硬盘上体感能差出一两秒。
勾完确定后回到工作表,「数据」选项卡最右侧的「分析」组里应该出现「规划求解」按钮。如果按钮出现了但显示为灰色,通常是没有选中任何单元格,或者当前工作簿处于某种受保护视图,点一下普通单元格再试。
3.2 用 VBA 查状态:勾没勾、勾的是哪一份,一次看清
界面看不到细节的时候,VBA 编辑器是最好的黑匣子。按 Alt+F11 打开编辑器,插入一个模块,把下面这段粘进去运行:
Sub ListSolverAddin() ' 遍历当前 Excel 已注册的所有加载项,打印名称、加载状态和完整路径 Dim ai As AddIn For Each ai In Application.AddIns Debug.Print ai.Name & " | Installed=" & ai.Installed & " | " & ai.FullName Next ai End Sub输出会出现在「立即窗口」(Ctrl+G 调出)。Installed=True表示已加载,FullName会打出真实的文件路径。如果这一行指向一个不存在的旧目录,那基本就是升级残留导致加载失败的直接证据;如果列表里压根没有名字里带 Solver 或「规划求解」的项,说明注册表层面就没有登记,属于 2.3 没做干净。
确认之后需要自动勾上,可以再跑一段:
Sub EnableSolverAddin() ' 兼容中英文语言包,按名称关键字匹配后置为已加载 Dim ai As AddIn For Each ai In Application.AddIns If InStr(1, ai.Name, "Solver", vbTextCompare) > 0 _ Or InStr(1, ai.Name, "规划求解", vbTextCompare) > 0 Then ai.Installed = True Debug.Print "已加载: " & ai.FullName Exit Sub End If Next ai Debug.Print "未找到规划求解加载项,请检查安装是否包含该组件" End SubvbTextCompare让匹配忽略大小写,省得在英文版和中文版之间来回切换时改代码。Exit Sub是防止在极少数环境下匹配到多个条目造成重复加载。这段代码只改当前用户的加载状态,不写注册表,跑坏了最多是加载项列表多一条,删掉就行,算是比较安全的后悔药。
3.3 勾了又消失:禁用项目、宏安全、XLSTART 三处拦截
按钮出现一次、重启后又没了,是我被问得最多的一类问题。按顺序查这三个地方,基本能覆盖。
第一处是「禁用项目」。Excel 认为某个加载项导致过崩溃,会自动把它拉黑,界面上只留下一个空空的勾选框。路径是「文件」→「选项」→「加载项」,把底部「管理」下拉框切成「禁用项目」,点「转到」,看列表里有没有规划求解相关的条目,有就选中并点「启用」。这个列表不会主动提示你,属于典型的沉默故障。
第二处是宏安全设置。加载宏本质上是带 VBA 的工作簿,信任中心把宏全禁掉时,加载项能出现在列表里但加载即失败。调试阶段可以在「信任中心」→「宏设置」里临时放开,但别长期挂着「启用所有宏」;更稳的做法是把加载宏所在目录加进受信任位置,这样签名和策略都不受影响。
第三处是 XLSTART 目录。有些人为了图省事,把 XLAM 直接丢进启动目录,结果和加载项列表里的登记形成双份加载,要么报错,要么每次启动都弹「是否启用宏」。翻一下这个目录,多余的副本清掉,只保留正规加载项登记这一条路径就够了。
4. 参数配置:目标单元格、可变单元格与选项里的六个开关
按钮出来只是第一步,真正决定能不能解出正确结果的是参数怎么填。规划求解的参数对话框看起来字段不多,但每个框的语义都很严格:填错一个引用不报错,只是默默给出一个看起来像答案的东西。这一章按「三个必填框 → 约束写法 → 选项开关 → 模型保存」的顺序过一遍。
4.1 三个必填框的语义与常见填错法
「设置目标单元格」必须是一个包含公式的单元格,它对应线性规划里的目标函数。这里最常见的错误是填了一个常量单元格,界面不拦你,点求解后会直接报「目标单元格必须包含公式」。验证的办法是选中那个格子,编辑栏里应该以等号开头。
「最大值 / 最小值 / 值为」三选一。前两个是单目标优化的常规选择;「值为」用于求解达到指定数值的方案,比如在满足产能的前提下把成本压到某个具体数字,实际建模里用得不多。
「可变单元格」对应决策变量,可以是一个连续区域,也可以是多个不相邻区域用逗号分隔,数量上限是 200 个。这里要特别注意「推测」按钮的行为:它只会自动填充被目标公式直接引用的非公式单元格,一旦目标函数里用了SUMPRODUCT这种整区域引用,推测经常漏掉一部分变量,必须手动补。
| 字段 | 应该填什么 | 常见错法 |
|---|---|---|
| 设置目标单元格 | 含公式的单个单元格引用 | 填常量单元格,或填了公式但引用错行 |
| 最大值 / 最小值 / 值 | 按优化方向三选一 | 最小值问题选了最大值,结果发散 |
| 可变单元格 | 决策变量区域,逗号分隔不相邻区域 | 区域里混入了公式单元格 |
| 约束 | 左端引用 + 关系符 + 右端数值/引用 | 关系符方向写反,可行域变成空集 |
4.2 约束的五种关系符:Int 和 Bin 只能加在可变单元格上
约束的左端是单元格引用,中间是比较符,右端可以是数字、单元格引用,也可以是一个公式。<=、=、>=是常规的线性约束;Int和Bin是整数规划专用的,选中之后右端会自动变成「整数」或「二进制」,不需要你手动填值。
这条限制很容易被忽略:Int和Bin只对可变单元格生效。如果你把一个由公式算出来的中间单元格设成 Int,界面照样接受,但求解时会直接报「单元格引用位置无效」或者干脆忽略这条约束。整数规划的正确写法是先给变量加取值范围约束(比如>=0、<=1),再单独加一条Int,两步都做全才是 0-1 规划。
约束数量上也有一条隐线:勾选「采用线性模型」时,约束数量没有硬限制;纯非线性问题里,每个可变单元格除范围和整数限制外最多挂 100 条约束。约束堆得太密的时候,求解器会因为数值误差误判可行域为空,这时候要么拆分子问题,要么打开「自动按比例缩放」。
4.3 选项对话框:默认的 100 秒和 100 次在什么时候不够
点「选项」进入高级设置,这里才是真正影响收敛的地方。默认值对几十个变量的小模型足够,一旦变量上千或者带整数约束,就得手动调。
| 参数 | 默认值 / 取值范围 | 什么时候要动它 |
|---|---|---|
| 最长运算时间 | 默认 100 秒,上限 32767 秒 | 大规模整数规划经常卡在时间上,先加到 600 秒观察 |
| 迭代次数 | 默认 100,上限 32767 | 报「达到最大迭代次数」时翻倍,但先确认不是约束冲突 |
| 精度 | 0 到 1 之间的小数,位数越多越严 | 约束左右端量级很小(比如小于 1)时要收紧,否则容易误判 |
| 允许误差 | 百分比,仅对整数约束生效 | 求整数解太慢时放宽到 1%–5%,能显著加速但结果可能非最优 |
| 收敛度 | 0 到 1 之间的小数,仅对非线性生效 | 非线性问题反复「收敛到当前结果」时调小,代价是时间变长 |
| 采用线性模型 | 复选框 | 纯线性问题必须勾,能显著加速;勾了但报非线性说明模型里有乘积或除法 |
| 假定非负 | 复选框 | 勾上后未设下限的变量默认>=0,能省掉一批约束 |
| 自动按比例缩放 | 复选框 | 输入和输出量级相差几个数量级时必开,否则数值误差会吃掉可行解 |
「估计」「导数」「搜索」这三组属于非线性求解的算法选择,线性模型下基本不用碰。真遇到非线性收敛困难,先把「导数」从默认的向前差分改成中心差分,它计算量更大但对接近约束边界的模型更稳;「搜索」里的牛顿法迭代次数少、内存占用高,共轭法反过来,问题规模上千且内存吃紧时换共轭法更合适。
4.4 保存模型:把这套参数固化到单元格区域
参数调好一次不容易,下次还要重来就很烦。「选项」对话框里的「保存模型」能把当前的目标单元格、可变单元格、约束和选项一起写进工作表的某个区域。第一个模型会自动占用一个默认位置,之后每保存一次就要手动指定一个空白区域,通常选在模型表格下方的空白列,纵向排开。
装载的时候点「装入模型」,输入之前保存的那个区域引用即可。要注意的是模型区域里存的是引用文本,如果你后来插删了行导致单元格位置变化,装回来的约束会指向错误的位置。我的习惯是把模型区域放在独立的「参数」工作表里,主模型表只做计算,插删行不影响它。
5. 排查与避坑:六条踩过的记录,按现象、原因、解决走
这一章记录的是我在不同机器上真实遇到过的六种情况,按加载阶段和求解阶段分开。每条都按「看到什么、为什么、怎么办」写,方便对照自己的现场。
5.1 加载阶段的三条
第一条,加载项列表里根本没有「规划求解加载项」这一项。现象是「转到」之后弹出的小窗口里只有「分析工具库」之类的条目,翻到底也找不到规划求解。原因通常是装 Office 时压根没勾这个组件,磁盘上没有SOLVER.XLAM,注册表自然也不会登记。解决办法是回到控制面板做「添加或删除功能」补装,装完不用重启,重新打开 Excel 再走一遍加载流程就能看到。
第二条,勾上确定后按钮出现,重启 Excel 又消失。现象是每次开机都要重新勾一次,怀疑人生。原因多半是加载项被 Excel 判定为不稳定后拉进了「禁用项目」,或者加载项文件被安全软件隔离了。先去「管理」下拉框切到「禁用项目」看有没有残留,有就启用;再看一眼杀毒软件的隔离区,把文件恢复并加白名单。两个地方都干净之后还是会消失,才考虑重装组件。
第三条,提示 SOLVER.DLL 正在被另一个会话使用。这个报错很直白,原因是同一台机器上开了多个 Excel 实例,其中一个已经加载了求解引擎,而 DLL 同时只能被一个会话占用。把多余的后台 Excel 进程结束掉,或者干脆只保留一个窗口操作。判断有没有隐藏进程,任务管理器里看 Excel 条目数量比看窗口数量靠谱,有时候关掉窗口进程还挂着。
5.2 求解阶段的三条
第四条,报「规划求解找不到可行解」。先别怀疑算法,八成是约束互相打架。常见的写法错误包括:约束右端引用了一个空单元格(被当成 0)、关系符方向写反、整数约束和范围约束叠加后没有交集。排查方法是从约束列表里逐条临时取消勾选,二分定位是哪一条把可行域卡死了;也可以在「选项」里把精度放宽一档再试,量级很小的模型经常是被精度误判的。
第五条,勾了「采用线性模型」却提示模型不满足线性条件。原因很明确:目标函数或约束公式里存在乘积、除法、IF、取绝对值这类非线性运算。最容易中招的是用两个可变单元格相乘表示某种耦合关系,或者约束里用了SUMPRODUCT的变体。解决办法是先清除这个勾选框再求解,如果必须保持线性,就得改写模型,用辅助变量把乘积关系拆开。
第六条,整数规划跑出来带小数。现象是明明要整数解,结果里出现了 3.67 这种值。原因是没有在约束里加Int,只在脑子里「假设它是整数」不算数。还有一种是加了Int但求解达到迭代上限提前停止,这时结果对话框会提示未找到满足所有约束的解,需要增加迭代次数或放宽允许误差再跑。求解完成之后确认状态栏或者结果对话框里的完成信息,是判断结果能不能用的唯一依据。
6. 装完怎么验证:拿一个小型生产计划模型跑一遍全流程
装完不验证,等于没装。我习惯用一个小到可以手算的模型做冒烟测试,这样结果对不对一眼就能看出来。下面这张表是三种产品、两种资源的排产问题,目标是在资源上限内让总利润最大。
| 项目 | 产品 A | 产品 B | 产品 C | 资源上限 |
|---|---|---|---|---|
| 单位利润 | 60 | 40 | 50 | — |
| 单件工时消耗 | 2 | 1 | 3 | 180 |
| 单件原料消耗 | 1 | 2 | 1 | 120 |
| 决策变量(产量) | B4 | C4 | D4 | — |
把数据填进 B2:D3,产量初值在 B4:D4 全部填 0,目标单元格 B6 写入=SUMPRODUCT(B2:D2,B4:D4),资源占用用同样的写法算出两行合计。然后打开规划求解:目标单元格选$B$6,选「最大值」;可变单元格选$B$4:$D$4;加两条约束,工时合计小于等于 180、原料合计小于等于 120;选项里勾上「采用线性模型」和「假定非负」,其余保持默认;点求解。
验证看三件事。第一,结果对话框里应该出现「规划求解找到一解,可满足所有的约束及最优状况」,这句话是判断求解是否正常收尾的关键。第二,把求出的产量代回资源约束,至少有一条应该是紧的,也就是刚好等于上限,如果两条都离上限很远,多半是约束没生效。第三,在「报告」里选「运算结果报告」,生成的新工作表会列出可调单元格的初值和终值、约束的状态和松弛量,松弛量为 0 的那一行就是卡住最优解的关键资源,这个信息比结果本身有用。
这个模型规模小,正常情况下不到一秒就收敛。如果卡住不动,或者报「目标单元格中的数值不收敛」,先回去看目标公式是不是引用了可变单元格之外的区域——这是我自己翻车最多的地方,一次是SUMPRODUCT少选了一列,一次是可变单元格区域里混进了一个公式格,两次都不报错,只是结果离谱。
从那以后,我每装一台新机器、每换一个 Excel 版本,都会先跑一遍这个小模型,把「求解成功」那句话截图留着,再动真实的生产数据。装环境这件事,能复现的最小验证比任何配置清单都可靠。希望帮到你。
本文还有配套的精品资源,点击获取