目录
?
1 绪论
1.1 Cplex简介
1.1.1 基本界面介绍
1.1.2 处理流程介绍
1.2 OPL语言
1.2.1 OPL的主要关键字
1.2.2 数据文件
1.3 如何调用Cplex
1.3.1 使用AMPL脚本语言调用
1.3.2 IBM CPLEX Studio IDE
1.3.3 Cplex with Concert Technology
2 官方gas示例演示
2.1 导入示例
2.2 gas示例解析
2.2.1 示例的通俗语言描述
2.2.2 数据文件与模型文件
2.2.3 结果展示
2.3 数据和模型同文件形式
2.4 带#与否的数据文件
- Cplex是IBM公司开发的一个优化工具引擎,可以用其求解线性规划、二次规划、整数规划等问题;能够快速解决一些行业难题。
- 自带IBM ILOG Cplex Optimization Studio既能使用自带语言进行编程,也提供了众多流行语言的接口,具有广泛的应用前景
1.1.1 基本界面介绍
1.1.2 处理流程介绍
当我们面对一个问题时,先从给定的数据建立科学的数学模型,然后使用Cplex进行问题求解,输出我们想要的结果。
OPL语言是ILOG的优化语言,可以用来编制模型文件和数据文件。
包含的文件类型及作用:
- 项目文件:组织模型和数据的文件,并提供一种方便的方法来维护相关文件和运行选择之间的关系
- 模型文件:声明数据项目,但是不需要提供数据的初始化工作
- 数据文件:包含了在模型中声明的数据初始化
- 设置文件:当你决定一个或多个数学规划和其他的缺省值,该文件保存用户定义的值
- 运行配置:为了运行的目的而根据项目进行的设置;在一个项目中,可以根据自己的需要定义多个运行配置
模型文件包含以下四个部分:数据、决策变量、目标函数、约束条件;这也是数学建模的四个必备要素。
1.2.1 OPL的主要关键字
数据类型 | 语法规则 | 代码示例 |
string | {string} 变量名 = {"字符串1", "字符串2","字符串3",...}; | {string} Products = {"gas", "chloride"}; {string} Components = {"nitrogen", "hydrogen", "chloride"}; |
float | 用来定义浮点数据类型,也就是小数 float 变量名[对应字符串数组变量名] = [数值1, 数值2, ...]; | //浮点数 float var = 3.13; //数组 float Profit[Products] = [30,40]; //二维数组 float Demands[Products][Components] = [[1,3,0],[1,4,0]]; |
int | 用来定义整型数据类型,也就是整数 int 变量名[对应关键字数组数组变量名] = [数值1, 数值2, ...]; | //整型 int Fixed = 10; |
range | 一段连续的整型数据 range 变量名 = startInterge..endInterge | //Range类型 range Rows = 1..10; int n=10; range rows = (n+1)..2*(n+1); |
dvar | 定义决策变量 dvar 数据类型函数 变量名; 数据类型函数后可跟正负号来表示决策变量正负 | dvar float+ Gas; dvar float+ Chloride; dvar float+ Production[Products]; |
Maximize Minimize | maximize或minimize 目标函数的表达式; | maximize 40 * Gas + 50 * Chloride; maximize sum(p in Products) Profit[p] * Production[p]; |
subject to | subject to{ 约束1名称:约束1; ... 约束n名称:约束n; } | subject to{ ctMaxTotal: Gas + Chloride <= 50; ctMaxTotal2: 3 * Gas + 4 * Chloride <= 180; ctMaxChloride: Chloride <= 40; } |
1.2.2 数据文件
- 以dat为后缀的文件
- 数据文件与模型文件相对应
- 模型文件中的...在数据文件中应该使用具体的数据
- 若数据类型为字符串类型,各数据之间使用空格或逗号隔开
- 数值型,各数据以逗号或空格隔开;如果不加#数据必须有变量名,否则数据必须是有序的。
示例代码:
?
1.3.1 使用AMPL脚本语言调用
参考文档
1.3.2 IBM CPLEX Studio IDE
下载完成后的官方示例路径:你的路径\opl\examples\opl
示例运行方式在下文介绍
1.3.3 Cplex with Concert Technology
直接以编程语言的API建立模型并求解,此处可参见我之前的博客文章
运筹优化学习09:一个示例带你入门如何使用C++、C#、Java、Python、Matlab调用Cplex
导入之后,可以看到的文件结构如下:
2.2.1 示例的通俗语言描述
- 生产汽和氯化物两种产品,每种产品包含氮氢氯三种组分;
- 生产天然气需要氮氢氯组分数为1、3、0;生成氯化物需要氮氢氯组分数为1、4、1;
- 生产天然气和氯化物可以获得收益分别为30和40
- 库存中包含这三种组分的数量为50、180和40
- 求生产天然气和氯化物的最大化收益
2.2.2 数据文件与模型文件
数据文件(gas.dat) |
Products = { "gas" "chloride" }; Components = { "nitrogen" "hydrogen" "chlorine" }; Demand = [ [1 3 0] [1 4 1] ]; Profit = [30 40]; Stock = [50 180 40]; |
模型文件(gas.mod) |
{string} Products = ...; {string} Components = ...; float Demand[Products][Components] = ...; float Profit[Products] = ...; float Stock[Components] = ...; dvar float+ Production[Products]; maximize ? sum( p in Products )? ? ? Profit[p] * Production[p]; subject to { ? forall( c in Components ) ? ? ct: ? ? ? sum( p in Products )? ? ? ? ? Demand[p][c] * Production[p] <= Stock[c]; } |
2.2.3 结果展示
约束展开:
?
示例还提供了一个将数据在mod文件中直接进行赋值的模型文件,详情如下:
{string} Products = { "gas", "chloride" }; {string} Components = { "nitrogen", "hydrogen", "chlorine" }; float Demand[Products][Components] = [ [1, 3, 0], [1, 4, 1] ]; float Profit[Products] = [30, 40]; float Stock[Components] = [50, 180, 40]; dvar float+ Production[Products]; maximize ? sum( p in Products )? ? ? Profit[p] * Production[p]; subject to { ? forall( c in Components ) ? ? ct: ? ? ? sum( p in Products )? ? ? ? ? Demand[p][c] * Production[p] <= Stock[c]; } |
运行结果与之前的一致
gas.dat | gasn.dat |
Products = { "gas" "chloride" }; Components = { "nitrogen" "hydrogen" "chlorine" }; Demand = [ [1 3 0] [1 4 1] ]; Profit = [30 40]; Stock = [50 180 40]; | Products = { "gas", "chloride" }; Components = { "nitrogen", "hydrogen", "chlorine" }; Profit = #["gas":30, "chloride":40]#; Stock = #["nitrogen":50, "hydrogen":180, "chlorine":40]#; Demand = #[ ? ? ? ? ? ? "gas": ? ? ?#[ "hydrogen":3 "nitrogen":1 ?"chlorine":0 ]#, ? ? ? ? ? ? "chloride": #[ "nitrogen":1 "hydrogen":4 "chlorine":1 ]# ? ? ? ? ? ]#; |
gasn.dat的数据是带#的,因此其中的数据顺序是可以随意指定的,只要带上正确的变量名即可。
上述的gasn.dat文件我们对数据顺序进行了调整,变化如下图所示:
然后,将gas.mod拷贝一份,重命名为gasn.mod,使用默认配置运行;可以看到左下角的数据仍然是正确的数据。
更多精彩,欢迎关注个人公众账号