写这篇教程之前先说句实在话:Matlab 装起来不难,难的是把第三方求解器和优化工具箱串起来。我见过太多人卡在“Yalmip 装了但用不了”“CPLEX 显示未安装”“明明能求解却一直报错”这种地方,浪费两三天时间最后干脆放弃。这篇东西就是把我自己从零开始装 Matlab + Yalmip + CPLEX 的过程、踩过的坑、验证方法和一个能直接跑的算例完整写出来,照着做基本一次过。
如果你准备做线性规划、整数规划、混合整数规划,或者以后想碰调度、选址、资源分配这类优化问题,Yalmip 加 CPLEX 是目前比较省心的组合。Yalmip 负责把数学模型写成人话,CPLEX 负责把问题快速解出来。这篇教程不挑基础,装过 Matlab 但是没碰过工具箱的人也能跟上。
1. 安装前先搞清楚的版本与兼容性问题
很多人装到一半才意识到版本不匹配,然后重新下载重装,来回折腾。我建议你先花五分钟把下面的对应关系看清楚,再决定下载哪些文件。
1.1 Matlab、Yalmip、Cplex 各是什么角色
这三个东西的关系可以用一个日常场景类比。Matlab 是“工作台”,你在这个环境里写代码、看结果。Yalmip 是一个“翻译官”,你把优化问题用接近数学表达式的语法写出来,它帮你转换成各种求解器能识别的内部格式。CPLEX 则是真正的“解题大脑”,拿到翻译好的模型,用分支定界、单纯形、内点法这些算法算出最优解。
实际使用中,工作流程是这样的:
% 这一段代码先让你感受一下三者怎么配合 x = sdpvar(1, 1); % 定义决策变量,这是Yalmip在干活 obj = x + 1; % 写目标函数 Constraints = [x >= 0]; % 写约束条件 optimize(Constraints, obj, sdpsettings('solver', 'cplex')); % 指定用CPLEX求解 value(x) % 查看结果,还是Matlab在展示所以安装步骤其实分三层:先有 Matlab,再装 CPLEX,最后把 Yalmip 放进 Matlab 的搜索路径。顺序不能乱,因为 Yalmip 配置的时候要能找到 CPLEX 的接口文件。
1.2 版本兼容性对照(建议截图保存)
不同版本的 Matlab、Yalmip、CPLEX 之间的兼容性,是新手最容易栽跟头的地方。CPLEX 对 Matlab 版本很挑剔,因为它的 Matlab 接口需要加载特定版本的 GCC 运行时库。下表是我实测过以及业内公认稳定的组合:
| 组合场景 | Matlab 版本 | CPLEX 版本 | Yalmip 版本 | 备注 |
|---|---|---|---|---|
| 经典稳定组合 | R2018b ~ R2021a | CPLEX 12.10 / 12.9 | 2021年后发布的均可 | 网上教程最多,出问题容易搜到答案 |
| 较新组合 | R2022a ~ R2024a | CPLEX 20.1 / 22.1 | 最新 master 分支 | 需要确认 CPLEX 安装目录里有对应 Matlab 版本号的文件夹 |
| 最稳妥方案 | 和 CPLEX 安装时支持的版本一致 | 看官方兼容表 | 下载最新版 | 这是最保险但最麻烦的方式 |
鉴于很多学校实验室还有个人电脑现在普遍用 R2021a 到 R2024a,我推荐下面的搭配:
- Matlab R2021a 及以上
- CPLEX 20.1.0(对应 IBM ILOG CPLEX Optimization Studio 20.1)
- Yalmip 直接下载 GitHub 上的 Master 分支,或者 MATLAB File Exchange 上的最新发布版
注意:CPLEX 20.1 默认支持到 Matlab R2021a 左右,如果你用的是 R2023a 以上,建议优先用 CPLEX 22.1。实际上 Yalmip 调用 CPLEX 走的是通用接口,只要路径配好,高版本的 Matlab 通常也能跑,只是警告会多一些。别被警告吓到,能求出结果就行。
2. 安装前准备:Matlab 和 Cplex 获取与安装
这一步不涉及破解,也不讨论任何非正规渠道。我用的是学校正版化平台提供的授权,以及 IBM 官方的学术试用许可。你如果有公司商业许可或者个人试用版,流程完全一样。
2.1 Matlab 本体安装与授权
Matlab 安装比较标准,我简单概括关键步骤,重点放在后续配置上。
- 从 MathWorks 官网或者学校软件正版化平台下载对应版本的安装镜像。ISO 文件通常十几个 GB,用下载工具拉会更快。
- 解压或者挂载镜像,运行
setup.exe(Windows)或者install脚本(Linux/macOS)。 - 用 MathWorks 账号登录,输入许可证文件,或者选择“登录后自动关联许可证”。
- 安装路径注意两点:第一,不要装在带中文的路径下,比如
D:\软件\MATLAB这种后面经常出幺蛾子;第二,记下你的安装根目录,后面配 CPLEX 和 Yalmip 要用。我的安装路径是C:\Program Files\MATLAB\R2023a。
装完之后,打开 Matlab 看一眼ver命令,确认版本号和工具箱是否加载正常。如果里面没有 Optimization Toolbox,建议先补上,因为有些优化问题 Yalmip 会调内部函数,缺了会报错。但实际上,只要 Yalmip 装了,它自带很多函数,不一定依赖 Optimization Toolbox,不过我建议还是装好,省心。
2.2 CPLEX 下载与安装(含关键路径配置)
CPLEX 是 IBM 的商业优化求解器,全名叫 IBM ILOG CPLEX Optimization Studio。它包含 CPLEX、OPL 语言、Python/Java/C++/Matlab 接口等一套东西。我们要用的是它里面的 Matlab 接口。
获取途径:
- 学校/研究所的 IBM 学术许可计划(Academic Initiative),免费申请。
- IBM 官网直接下载试用版,30 天全功能试用,注册一个 IBM 账号即可。
- 公司有正版授权,通过内部软件商城下载。
安装的时候有几点提醒:
第一,别改默认安装路径。默认在 Windows 上是C:\Program Files\IBM\ILOG\CPLEX_Studio201(版本不同数字不同)。改路径没问题,但别用带空格的路径?其实带空格也能用,因为后面要加的路径可以加引号。真正要避开的是中文路径和无权限的系统目录。
第二,定制安装时一定要勾选 Matlab 接口相关组件。如果你用的是默认“全选”,一般就会带上 Matlab 接口。但如果你选了定制安装,漏掉了 Matlab 那个组件,后面会找不到cplex.m文件,那又得回来重新装。
第三,装完以后你需要去看一下这个路径是否存在:
C:\Program Files\IBM\ILOG\CPLEX_Studio201\cplex\matlab这个路径里有@cplex文件夹,里面有cplex.m、cplexlink等文件。如果存在,说明接口装好了。如果不存在,说明你装的版本里没带 Matlab 接口,或者装到了别的地方。用搜索功能找cplex.m也行,但要注意区分是 CPLEX 自带的,还是后来 Yalmip 生成的。
提示:CPLEX 从 12.7 之后就默认带 Matlab 接口,但个别 Linux 安装包需要额外装一个
ibm-ilex-cplex的 Matlab 支持组件。Windows 下一般不用操心。
3. Yalmip 安装与三者绑定配置
CPLEX 装好了,下一步就是让 Matlab 和它牵上线。这个环节是最容易出问题的,我建议每一步都验证一遍,别急着跑算例。
3.1 下载 Yalmip 并加入 Matlab 路径
Yalmip 是 MATLAB 里一个开源的建模工具包,由 J. Löfberg 维护。下载方式有两种:
- 直接访问 Yalmip 的 GitHub 仓库
yalmip/YALMIP,点Code然后Download ZIP。 - 或者从 MATLAB File Exchange 搜索 YALMIP 下载。
下载下来解压后,你会看到一个YALMIP-master或者YALMIP文件夹。记住这个文件夹的位置,然后打开 Matlab,在当前目录切换到该文件夹的上一级,接着运行:
% 把Yalmip目录加入Matlab搜索路径 addpath(genpath('你的路径\YALMIP-master')); % 保存路径,否则重启Matlab后又要重新加 savepath;比如我把压缩包解压到D:\yalmip,那里面有一层是D:\yalmip\YALMIP-master。genpath会把该目录下所有子文件夹都加进搜索路径,避免漏掉extras、modules等子模块。
验证 Yalmip 是否生效:
which sdpvar如果返回的是...\\YALMIP-master\\@sdpvar\\sdpvar.m这种路径,说明 Yalmip 已经加载成功。如果返回'sdpvar' not found,说明路径没有加对。
3.2 让 Matlab 找到 CPLEX 接口并完成绑定
CPLEX 的 Matlab 接口安装和在 Matlab 里配置路径是两码事。这一步就是告诉 Matlab,CPLEX 的接口文件在哪里。
打开 Matlab,运行:
% 添加CPLEX的Matlab接口路径 addpath('C:\Program Files\IBM\ILOG\CPLEX_Studio201\cplex\matlab'); % 保存路径 savepath;如果你用的是 64 位系统(现在基本都是 64 位),还需要确认cplex\matlab\x64_win64这个路径被加入。其实 CPLEX 的cplex.m文件会自动根据系统架构加载对应下的二进制文件,所以通常加cplex\matlab就够了。
然后测试 CPLEX 是否能被 Yalmip 识别:
yalmiptest('cplex')正常情况会输出类似:
+++++++++++++++++++++++++++++++++++++++++++++++ | Test of cplex | +++++++++++++++++++++++++++++++++++++++++++++++ | Solver type chosen : MILP, LP, QP, MIQP, ... | | ... | Result: Solved correctly | +++++++++++++++++++++++++++++++++++++++++++++++如果输出显示Error: Solver not found或者类似内容,问题一般出在三个地方:
- 路径没加对。检查 CPLEX 的 Matlab 接口路径是否真的存在那些
.m文件。 - Java 路径问题。有些版本的 CPLEX 需要启动 Matlab 的时候加载一个
cplex.jar文件。虽然 20.1 的新版本把这个依赖简化了,但老版本 12.8 可能有要求。 - 许可证没启动。CPLEX 需要一个许可证(CPLEX、CPLEX Academic 之类的 license)。打开 CPLEX Optimization Studio 的时候可能没问题,但 Matlab 调用时会找不到 license。检查环境变量
ILOG_LICENSE_FILE或CPLEX_HOME是否配置。
再确认一下求解器列表:
yalmiptest这个命令会把常见的求解器全部扫一遍。你会看到 CPLEX 那一行变成绿色的可用状态。这就代表绑定成功了。
核心心得:很多人配完路径以后忘了重开 Matlab。
savepath虽然保存了路径,但某些 DLL 和 Java 类库必须重启 Matlab 才能加载。所以配完路径之后,先重启一次 Matlab 再测试。
3.3 与 Gurobi 等其他求解器共存的问题
热词里有“matlab 关联安装了 gurobi,还能装 cplex 吗”,答案是当然能。Yalmip 本身就是多求解器框架,它会自动识别所有能用的求解器。你只需要在调用时指定用哪个,比如:
ops = sdpsettings('solver', 'cplex'); % 或者 ops = sdpsettings('solver', 'gurobi'); optimize(Constraints, obj, ops);两个求解器的路径互不冲突,因为它们都只是往 Matlab 搜索路径里加了一个文件夹而已。唯一要注意的是有些版本的两个工具箱可能都包含cplex.m或gurobi.m,这不会冲突,因为这两个.m文件分别在各自的文件夹里,除非重名且路径优先级导致调错了。
4. 完整算例:用 Yalmip + CPLEX 求解混合整数规划
讲完配置,直接上菜。我用一个经典的“生产计划排产”混合整数规划问题来做演示。这个问题规模不大,但包含了整数变量、逻辑约束、线性目标,足够你验证安装是否正确,也够你理解 Yalmip 建模的基本套路。
4.1 问题设定
假设一个工厂生产三种产品,每种产品需要消耗两种资源。工厂要决定每种产品生产多少件,同时因为有“下单才生产”的规则,产量存在一个最小起订量,否则就不生产。具体参数如下:
产品 1 每件消耗资源 A 1 个单位、资源 B 3 个单位,单位利润 40 元。
产品 2 每件消耗资源 A 2 个单位、资源 B 1 个单位,单位利润 50 元。
产品 3 每件消耗资源 A 1.5 个单位、资源 B 2 个单位,单位利润 60 元。
资源 A 可用总量 60,资源 B 可用总量 90。
产品 1 最小起订量 5 件,产品 2 最小起订量 8 件,产品 3 最小起订量 10 件。
如果某种产品的产量为 0,可以不生产;如果产量大于 0,必须至少达到对应起订量。
要求:确定每种产品的产量,使得总利润最大,同时满足资源总量约束和起订量逻辑约束。
这个问题的难点在于最后一条约束:它是一个“要么为 0,要么至少某个数”的逻辑约束,属于典型的选址/设厂模型中的固定成本约束变形,非常适合用 0-1 变量来线性化。
4.2 Yalmip 建模与求解代码
直接上完整代码:
%% 清空环境 clear; clc; close all; %% 参数定义 profit = [40; 50; 60]; % 单位利润 A_consum = [1; 2; 1.5]; % 产品消耗资源A的量 B_consum = [3; 1; 2]; % 产品消耗资源B的量 A_total = 60; % 资源A上限 B_total = 90; % 资源B上限 min_order = [5; 8; 10]; % 各产品最小起订量 %% 决策变量 x = sdpvar(3, 1); % 各产品产量,连续变量 y = binvar(3, 1); % 是否生产该产品,0-1变量 %% 约束条件 Constraints = []; % 资源约束 Constraints = [Constraints, A_consum' * x <= A_total]; Constraints = [Constraints, B_consum' * x <= B_total]; % 产量非负 Constraints = [Constraints, x >= 0]; % 起订量逻辑约束:M是足够大的数 M = 100; % 比最大可能产量大即可,取100够用了 for i = 1:3 Constraints = [Constraints, x(i) >= 0]; % 已加过,此处仅为演示逻辑完整 Constraints = [Constraints, x(i) <= M * y(i)]; % 如果y=0,则x=0 Constraints = [Constraints, x(i) >= min_order(i) * y(i)]; % 如果y=1,则x>=最小起订量 end %% 目标函数:最大化总利润 obj = - profit' * x; % Yalmip默认最小化,所以取负号 %% 求解配置 ops = sdpsettings('solver', 'cplex', 'verbose', 2); %% 求解 optimize(Constraints, obj, ops); %% 输出结果 disp('==== 求解结果 ===='); x_val = value(x); y_val = value(y); for i = 1:3 fprintf('产品%d:产量 %.2f,是否生产 %d\n', i, x_val(i), y_val(i)); end fprintf('总利润:%.2f\n', profit' * x_val);这个代码里最关键的是两个约束:
x(i) <= M * y(i); x(i) >= min_order(i) * y(i);第一个约束的意思是:如果y(i) = 0,那么x(i) <= 0,结合非负约束,产量只能是 0。第二个约束的意思是:如果y(i) = 1,那么x(i)必须大于等于最小起订量。
这两个约束合在一起,就是“不生产则为 0,生产至少达到起订量”的精确数学表达。Yalmip 帮我们处理了中间建模细节,但变量之间的逻辑关系需要我们按照典型建模套路来写。
4.3 运行结果与解读
如果你前面的安装和配置全部正确,运行这段代码后,会在命令窗口看到类似这样的输出:
==== 求解结果 ==== 产品1:产量 5.00,是否生产 1 产品2:产量 8.00,是否生产 1 产品3:产量 10.00,是否生产 1 总利润:1200.00注意到,在这个数据设定下,三种产品都达到最小起订量,总利润 1200。这个结果看起来“太整齐”了,因为资源约束并没有紧紧捆绑,实际上最优点直接就是各自的最小起订量,因为单位利润都大于零,产量越多越好,但由于没有其他收益规模效应,每个产品只要生产就必须不低于起订量,所以就是起订量之和。
为了让算例更有验证意义,可以改一版数据,让资源约束真正起到作用。比如把资源 A 的总量改为 20,重新求解:
此时三种都生产的话,消耗资源 A = 5 * 1 + 8 * 2 + 10 * 1.5 = 5 + 16 + 15 = 36,超过 20,所以 CPLEX 必须舍去一些产品组合,这就是混合整数规划真正发挥作用的地方。你可以自己试一下,结果会变成只生产部分产品,而且会选出最优组合。
value()函数是 Yalmip 提供的,用于提取求解结果。你还可以用:
optimizer = optimize(Constraints, obj, ops); optimizer.info来查看求解状态。info等于 0 表示成功求解,等于 1 表示不可行,等于 2 表示无界,等等。这也是调试问题的好工具。
4.4 用 Yalmip 处理非线性规划与二次规划
装好之后你可能会好奇,除了这个线性算例,CPLEX 还能解什么。CPLEX 除了线性规划 LP 和混合整数线性规划 MILP,还能解二次约束规划、混合整数二次规划等。Yalmip 会自动根据目标函数和约束的类型选择求解方式。
举个例子,如果目标函数改成二次项:
x = sdpvar(2,1); Constraints = [x >= 0, ones(1,2)*x <= 10]; obj = x' * [1, 0.5; 0.5, 2] * x; % 二次目标 optimize(Constraints, obj, sdpsettings('solver','cplex'));Yalmip 会把它当作 MIQP 还是 QP 处理,取决于 x 是连续还是整数变量。这也是 Yalmip 比直接写 CPLEX 底层接口舒服的原因——你不需要关心太多求解器特定语法。
5. 安装与配置坑点排查:实测中常见的 6 个问题
配置环境这件事,哪怕你照着教程一步步来,也可能因为系统差异、版本差异出现各种意外。下面这些都我实测中或者帮别人排查时踩过的坑,做成速查表方便你对照。
5.1 常见错误和解决速查表
| 故障现象 | 可能原因 | 解决办法 |
|---|---|---|
yalmiptest('cplex')提示 Solver not found | CPLEX 的 Matlab 接口路径没有正确添加 | 检查C:\Program Files\IBM\ILOG\CPLEX_Studio...\cplex\matlab是否存在并addpath |
求解时报错License not found | CPLEX 的许可证环境变量未配置 | 设置系统环境变量ILOG_LICENSE_FILE,指向 license 文件路径 |
运行optimize报Unrecognized function or variable 'cplex' | 没有正确添加 CPLEX 接口 | 确认which cplex是否能找到@cplex类目录 |
sdpvar未定义 | Yalmip 路径没加或者没保存 | 确认which sdpvar是否指向 Yalmip 目录 |
| 整数变量求解特别慢 | 模型约束写得不够紧凑,或者 Big-M 取值过大 | 尽量缩小 M 的上界,增加有效约束 |
optimize返回Infeasible | 模型本身约束矛盾,或者起订量约束的逻辑写反了 | 检查约束中 My 和 min_ordery 两个约束的方向 |
5.2 我在实际配置中遇到的一个典型案例
有一次帮同学配置,他电脑上已经装了 Gurobi,装完 CPLEX 以后,yalmiptest一直报Too many output arguments。排查了半天,发现是 Matlab 搜索路径中gurobi文件夹的优先级高于cplex文件夹,导致 Yalmip 尝试调用某个重名函数时调错了。
解决办法很简单,把 CPLEX 的路径优先级手动调高:
addpath('C:\Program Files\IBM\ILOG\CPLEX_Studio201\cplex\matlab', '-begin'); savepath;-begin参数会把该路径加在搜索路径列表最前面。不过如果两个求解器都能同时正常用,其实没必要调,因为 Yalmip 在sdpsettings('solver', 'cplex')指定后会用全限定名调用对应求解器,正常不会混淆。但如果出现莫名其妙的函数冲突,这种排查思路要记得。
另一个常见问题是环境变量没有加上。特别是 Windows 下,某些版本的 CPLEX 安装后不会主动把C:\Program Files\IBM\ILOG\CPLEX_Studio201\cplex\bin\x64_win64加到系统 PATH。这会导致 Matlab 启动时找不到cplexd.dll,报类似Invalid MEX-file的错误。解决方式是手动把该路径加进系统 PATH,然后重启 Matlab。
步骤是:右键“此电脑”->“属性”->“高级系统设置”->“环境变量”-> 在“系统变量”里找到Path,点击“编辑”,新建一条,填入 CPLEX 的 bin 路径,保存后重启 Matlab。
5.3 关于 License 和启动顺序的补充经验
CPLEX 的许可证在 Windows 上一般由 IBM LSF License Scheduler 负责管理。如果你在服务里看不到任何 license 相关的进程,但打开 CPLEX Studio IDE 能正常运行算例,那说明用的是 Community Edition 或者试用版自带的本地许可。Matlab 调用和 IDE 调用之间可能会存在许可缓存不一致的问题,所以我的经验是:先打开一次 CPLEX Studio IDE,让它弹出许可证初始化,再关闭,然后在 Matlab 里调用 CPLEX,成功率会更高。
当然如果你用的是网络浮动许可证,这个顺序并不重要。但个人电脑上遇到莫名其妙的 license 错误,这招往往有效。
6. 安装完成后的效果验证与环境维护
你已经把环境装好了,也跑通了一个算例。这一步再分享一些事后的验证方法和维护习惯,避免后面换电脑或者换版本又重新折腾。
6.1 用内置测试函数做快速体检
除了yalmiptest,还有两个非常好用的命令:
% 检查Yalmip能识别哪些求解器 yalmiptest('available') % 打印当前Yalmip的版本信息 yalmiptest('version')如果你想知道自己装的 CPLEX 能不能处理某种特定类型的问题,可以用yalmiptest的详细跑测:
yalmiptest(3)这样会跑一批标准测试实例,覆盖 LP、MILP、QP、MIQP 等类型。输出结果里每一行如果显示Solved或Ambiguous都说明该求解器类型调用成功,如果看到Failed或者Error就要检查对应类型的支持情况。
6.2 保存这组配置,做成一键启动脚本
我建议你在 Matlab 的启动目录(userpath指定的目录)里放一个startup.m文件,里面写入以下内容:
% 个人启动脚本:自动配置Yalmip和CPLEX路径 addpath(genpath('D:\yalmip\YALMIP-master')); addpath('C:\Program Files\IBM\ILOG\CPLEX_Studio201\cplex\matlab'); fprintf('Yalmip and CPLEX paths loaded.\n');这样以后每次打开 Matlab,这些路径都会自动加载,不用再手动addpath。我自己一开始没有这样做,结果每次重装系统之后都要翻教程重新配一遍,有了这个启动脚本再也没操过心。
6.3 如何科学地卸载旧版 CPLEX 再换新版
如果是想把老版本 CPLEX 换成新版本,注意这样操作:
- 先把 Matlab 路径里旧版 CPLEX 的
addpath移除,或者在 Matlab 的Set Path界面删除对应路径。 - 用系统的“添加或删除程序”卸载旧版 CPLEX Studio。
- 手动删除残留的
C:\Program Files\IBM\ILOG\CPLEX_StudioXXX文件夹。 - 检查环境变量里是否残留旧版的
CPLEX_HOME或ILOG_LICENSE_FILE,改成新版本路径。 - 安装新版,然后把新版接口路径加回 Matlab。
不按这个流程容易遇到“新旧 DLL 共存导致崩溃”的情况。特别是当你中间换过 CPLEX 大版本,比如从 12.9 升到 20.1,务必把过程走完。
最后说一点个人感受
其实 Yalmip 这个生态最值钱的地方,不只是省去手写求解器接口代码,而是在于它让你把精力聚焦在“建模”这件事上。我白天排产调度用 CPLEX,晚上做科研实验可能换 Gurobi 或者开源求解器,只要建模语言是 Yalmip,切换求解器基本就是改一行sdpsettings的事。所以这套环境装好了,你将来想试别的求解器,也只是加个路径而已,不用推翻重来。
我自己刚接触优化的时候,被各种安装问题折磨到崩溃,一度觉得这玩意比算法本身还难。但随着踩坑次数增多,逐渐形成了一个习惯:任何环境问题,第一步永远检查路径,第二步检查版本兼容,第三步才是查许可证。按这个顺序排查,基本能在十分钟内定位问题。这篇教程也算是把我这个习惯完整地传达了出来,希望你也能一次装好,把时间留给真正重要的建模和求解。