跳转到内容

GLPK/GMPL (MathProg)

来自维基教科书,开放的书籍,开放的世界

GNU MathProg 是一种高级语言,用于创建 数学规划 模型。 MathProg 专门针对 GLPK,但类似于 AMPL[1] 的一个子集。 MathProg 也可称为 GMPL(GNU 数学规划语言),这两个术语可以互换使用。

详细的示例可以在此页面下方专门的子页面中找到,按其问题域进行分组。 相反,此页面提供了一个概述并提供了一个简短的示例。

官方文档

[编辑 | 编辑源代码]

the official GLPK documentation filedoc/gmpl.pdf包含 MathProg 语言的完整参考。 因此,此处不会重复这些内容。 查看 获取 GLPK

Fourer、Gay 和 Kernighan(2002)

[编辑 | 编辑源代码]

来自这本关于 AMPL 建模语言的经典书籍(第二版)的章节现在可以下载: http://www.ampl.com/BOOK/download.html

作者 Robert Fourer writes(2012 年 8 月):"第 1-10 章也可以作为 GMPL(GNU MathProg)的介绍,尽管在细节上存在差异。"

简短示例

[编辑 | 编辑源代码]

以下 MathProg 示例实现线性约束优化模型

最大化
受制于

在此模型中,没有要求 为非负数。

# short example
var x1;
var x2;
maximize obj: 0.6 * x1 + 0.5 * x2;
s.t. c1: x1 + 2 * x2 <= 1;
s.t. c2: 3 * x1 + x2 <= 2;
solve;
display x1, x2;
end;

要使用 GLPK 解决此模型,请将上述文本保存为short.mod然后调用

$ glpsol --math short.mod

您应该获得 作为 GLPK 求解器终端输出的一部分。

同一模型使用 GLPK 库调用 进行编码(需要 C 编程)。 同样的问题显示在多个 问题格式 中。

官方 GLPK 示例

[编辑 | 编辑源代码]

theexamples官方 GLPK 发行版中的目录包含大约 60 个 MathProg(以及一些应用程序编程)示例

  • sample MathProg model (*.mod) files — with and without embedded data
  • sample MathProg data (*.dat) files — external data
  • sample database (*.dbf) files — table-based external data
  • sample data (*.csv) files — table-based external data

注意 下载 GLPK tarball 的说明

以下是作为官方 GLPK/MathProg 示例一部分的运输 MathProg LP 模型。 MathProg 模型包含三个(3)个组成部分,即:(1)模型,(2)数据和(3)报告(即后处理) - 可选。

# A TRANSPORTATION PROBLEM
#
# This problem finds a least cost shipping schedule that meets
# requirements at markets and supplies at factories.
#
#  References:
#              Dantzig G B, "Linear Programming and Extensions."
#              Princeton University Press, Princeton, New Jersey, 1963,
#              Chapter 3-3.

set I;
/* canning plants */

set J;
/* markets */

param a{i in I};
/* capacity of plant i in cases */

param b{j in J};
/* demand at market j in cases */

param d{i in I, j in J};
/* distance in thousands of miles */

param f;
/* freight in dollars per case per thousand miles */

param c{i in I, j in J} := f * d[i,j] / 1000;
/* transport cost in thousands of dollars per case */

var x{i in I, j in J} >= 0;
/* shipment quantities in cases */

minimize cost: sum{i in I, j in J} c[i,j] * x[i,j];
/* total transportation costs in thousands of dollars */

s.t. supply{i in I}: sum{j in J} x[i,j] <= a[i];
/* observe supply limit at plant i */

s.t. demand{j in J}: sum{i in I} x[i,j] >= b[j];
/* satisfy demand at market j */

solve;

# Report / Result Section (Optional)
printf '#################################\n';
printf 'Transportation Problem / LP Model Result\n';
printf '\n';
printf 'Minimum Cost = %.2f\n', cost;
printf '\n';

printf '\n';
printf 'Variables  (i.e. shipment quantities in cases ) \n';

printf 'Shipment quantities in cases\n';
printf 'Canning Plants  Markets   Solution (Cases) \n';
printf{i in I, j in J}:'%14s %10s %11s\n',i,j, x[i,j]; 
printf '\n';

printf 'Constraints\n';
printf '\n';
printf 'Observe supply limit at plant i\n';
printf 'Canning Plants Solution Sign  Required\n';
for {i in I} {
 printf '%14s %10.2f <= %.3f\n', i, sum {j in J} x[i,j], a[i];
   }

printf '\n';
printf 'Satisfy demand at market j\n';
printf 'Market Solution Sign  Required\n';
for {j in J} {
 printf '%5s %10.2f >= %.3f\n', j, sum {i in I} x[i,j], b[j];
   }

data;

set I := Seattle San-Diego;

set J := New-York Chicago Topeka;

param a := Seattle     350
           San-Diego   600;

param b := New-York    325
           Chicago     300
           Topeka      275;

param d :              New-York   Chicago   Topeka :=
           Seattle     2.5        1.7       1.8
           San-Diego   2.5        1.8       1.4  ;

param f := 90;

end;

此页面上可以看到有关各种输入和输出(例如 csv、excel 和数据库(即 access (mdb) 和 SQlite))的示例 [| 10 个你可能想要使用 GLPK 的理由..]

超大型模型

[编辑 | 编辑源代码]

某些类型的超大型 MathProg 模型可能需要很长时间才能解析,可能需要数小时。 例如,一个大型模型可能包含 50 万个图边。 GLPK MathProg 翻译器是非优化的——这意味着它无法在 解析过程 中识别可行的快捷方式。 不过,在某些情况下,可以重新构建 MathProg 模型以解决特定的瓶颈,但建模者首先需要了解解析机制。 在 2011 年 5 月的 thread 中,GLPK 作者 Andrew Makhorin 建议

"MathProg 翻译器并非旨在(按设计)处理超大型模型。 在这种情况下,最好使用 GLPK API 或使用专门的程序或脚本生成模型数据,例如以 GLPK LP 格式。"(语法已更正)

也就是说,如果 MathProg 翻译器完成,则生成的模型将令人满意。 此外,MathProg 翻译器通常不受内存限制,因此在夜间运行解析作业可能会提供一种可接受的策略。

模型翻译缓慢

[编辑 | 编辑源代码]

模型已成功重构,解析时间缩短了两个数量级(从约 15 小时缩短到 9 分钟)。开源的 OSeMOSYS 能源模型参加了联合国竞赛,并取得了这一成果。[2] 速度提升涉及用包含元组的集合上的扁平遍历替换嵌套集合遍历。由于原始集合语义中存在近乎一对一的关联,因此这种修改后的方法成为可能。此外,其他集合遍历被完全替换为使用属性。结论是,应尽可能避免嵌套集合迭代,因为这些迭代会极大地扩展要处理的模型空间的维度和大小。此外,在设计和实现模型时,请仔细考虑 MathProg 翻译器将如何构建你的问题实例。

故障排除

[edit | edit source]

如果在 MathProg 模型中遇到问题,可以通过指定 GLPSOL 选项进行进一步调查--nopresol禁用 LP 预求解器,以及--output filename.out将最终解写入文本文件。

如果收到消息 "PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION",则在解文件中查找违反其边界的变量。这应该可以让你确定哪些约束是矛盾的,以及哪些调整可能导致可行的系统。

背景资料

[edit | edit source]

Tommi Sottinen 关于 运筹学 和 GPLSOL 的课程笔记 [3] 为 MathProg 编程提供了极佳的入门介绍。

参考文献

[edit | edit source]
  1. Fourer, Robert; Gay, David M.; Kernighan, Brian W. (2002). AMPL: a Modelling Language for Mathematical Programming (2 ed.). Duxbury. ISBN 0-534-38809-4.
  2. 联合国 (2017 年 1 月 31 日). "法兰克福研究院博士生通过改进建模工具赢得 '人人享有可持续能源挑战',旨在促进普遍电力接入 — EN/318-ENV/DEV/1773". 新闻稿. https://www.un.org/press/en/2017/en318.doc.htm. 检索于 2017-02-16. 
  3. Sottinen, Tommi (2009). 使用 GNU 线性规划工具包进行运筹学. ORMS1020 课程笔记. 芬兰瓦萨大学数学与统计系. http://lipas.uwasa.fi/~tsottine/lecture_notes/or.pdf. 
华夏公益教科书