期
第
8
第
2009
卷 第
期
年
1
1
1
月
软 件 导 刊
Software Guide
Vol.8 No.1
Jan. 2009
高级语言与
lingo
混合编程解决复杂规划问题
吴兴远
莫小宝
,
,
李 佳
武汉大学 动力与机械系
(
湖北 武汉
,
430072)
摘 要
:Lingo
使其在解决多级规划
关键词
中图分类号
混合编程
:
,
、
规划
:TP312
语言由于其程序简单直观
在运筹学
工业优化等方面得到了广泛应用
但是
Lingo
的循环控制语言少
,
、
循环规划等问题时比较麻烦
,
于是介绍了用高级语言
(C++)
。
Lingo
软件解决这类问题
。
。
调用
,Lingo
文献标识码
:A
文章编号
:1672-7800(2009)01-0073-02
引言
0
。
、
,
、
、
整数规划
matlab、mathmatical
提出的单纯形法和对偶单纯形法
在工程设计
线性规划等问题
Dantzig
件集成了这些算法比如
语法比较复杂不易掌握
规划等的专业软件
非
科学实验中经常遇到线性规划
解决这类问题广泛使用的方法为美国数学家
现已有很多数学软
等
但是这类软件
非线性
并且
等 高 级 语 言 交 互 的 接
Lingo
口
这样
可以非常方便的在高级语言程序中进行多次或者循环地进行
而且计算
规划
出的结果可以返回到程序中用于后续计算
作为一款解决线性规划
、
因为程序简单直观得到广泛应用
提供 了 与
通过动态链接库文件嵌入到
提高了程序的运行效率
C、C++、JAVA、FORTRAN
大大减少了人工干预
C、C++、JAVA
等程序中
。Lingo
,
,
。
,
,
。
,
,
。
函数关闭这个
文件
。
Log
这样
Lingo
与
C++之间的接
ogFileLng
口环境就建立好了
。
1.2 Lingo
与
C++之间数据传递
。
Lingo
函数与
传递是由
程序中的
@POINTER (n)
数据传递正确与否是影响程序计算结果的重要因素
数据
C++程序中的
LSsetPointerLng (pLSenvLingo pL,double* pdPointer,int* pn-
函数中的第一参
指
指该函
这样可以
PointersNow)
数指的是第一步中创建的
的是
数是第几次被调用
保证数据正确地传给相对应的变量
第二个参数
而
中的
C++程序要传递给
与
句柄
的数据
函数共同完成的
。LSsetPointerLng
@POINTER(n)
pnPointersNow
pdPointer
相对应
Lingo
Lingo
n
,
,
,
,
LSsetPointerLng
pdPointer
函 数 将
这样
Lingo
/
/ (C++
就可以利用内存的数据进行计算
程序中代码
。
)
的 内 存 地 址 传 给
语句如下
Lingo,
:
。
接口实现
nError = LSsetPointerLng ( pLINGO, dProfit, &nPointer-
1 C++与
与
Lingo
等 高 级 语 言 接 口 的 主要 思 想 是
Lingo
提 供 一 个 动 态链接 库 文 件
VC、FORTRAN
(DLL),
的 命 令 脚 本 语 言
Lingo
与高级语言之间进行数据传递以及各种操作
(command script),
:
使 得 高 级 语 言可 以 直
这 样 就 可 以
下面简
。
Lingo
接 运 行
在
单介绍一下
Lingo
Lingo
建立
Lingo
添 加 头 文 件
与
与
C++混合编程的方法
C++的连接
“lingd90.h”,
。
1.1
,
工程中
文件中
。
的 对 象
,
#include“lingd90.h”
并且用
下面就可以进入代码的编写
调 用
函 数
动 态 链 接 库 文 件
到
语 句将 其 写 入 所 包 含 头 的
“Lingd90.lib”
首先要创建一个
Lingo
,
若 调 用 成 功 则 返 回 一 个
pLSenvLINGO
LScreateEnvLng()
,
之 后 就 要 调 用
类 型 的
句 柄
文件用于保存计算结果
Lingo
。
函数创建一个
FileLng()
log
对结果的分析如灵敏度分析
,
在计算完后必须调用
。
LSopenLog-
以及
lingo
LScloseL-
sNow);
! (lingo
程序中的代码
)
profit = @pointer(1);
C++中的
运行后将会把
变量
计 算 结 果 也 同 样 由 这 两个 函 数 进 行 传 递
数据传递给
dProfit
。
lingo
profit
传 递 给
@POINTER (n)
LSsetPointerLng
的语句必须写成这种形式
@POINTER(n)
:
/
/ (C++
程序中代码
)
函 数
,
程序中的
这 时 由
,
不 过 这 时
nError =LSsetPointerLng (pLINGO,&dObjective,&nPointer-
sNow);
! (lingo
程序中的代码
)
@pointer(4)=rObj;
这 样 就 可 以 将
lingo
运 算 结 果
传 递 给
C ++程 序 中 的
robj
作者简介
:
吴兴远
男
湖北武汉人
武汉大学本科生
(1987-),
研究方向为能源动力系统及其自动化
,
,
科生
,
研究方向为能源动力系统及其自动化
,
莫小宝
;
(1987~),
男
,
湖北武汉人
,
武汉大学本
李佳
;
(1988-),
女
,
湖北武汉人
,
武汉大学本科生
,
研究方向为自动化
。
74-
-
软 件 导 刊
年
2009
。
变量
dObjective
类型的数据即
据必须是
以可以直接进行数组的传递
double
型的
double
,
必须注意的是
型的数据
另外两者之间传递的其实都是指针
可以运算的都是双精度
C++中传递给
的数
所
Lingo
所以
Lingo
,
,
。
1.3
lingo
C++中的控制脚本语言控制
由
在完 成 了 建 立 链 接 和 数据传 递 后 下 一 步 就 要 开 始 运 算
的 动 态 链 接 库 文 件 提 供 了
C++语言控制
LSexecuteScriptLng (pLingo,
这个函数用于
的运行
的计算
Lingo
其中
lingo
的句柄
cScript)
指的是
字符串就是控制
以根据程序要实现的功能来编写
,cScript
Lingo
Lingo
是字符串首地址
运算的控制脚本语言
。
pLingo
。
该地址中存的
,
控制脚本程序可
一个简单的例子如
,
“SET E-
其 中
CHOIN 1 \n TAKE SIMPLE.LNG \n GO \n QUIT \n”
(i));
@for(computers(i):produce(i)<=limit(i));
@sum(computers(i):labor(i)*produce(i))<=160;
data:
@pointer (4) =rObj;@pointer (5) =@status ();@pointer (6) =
,
produce;
Enddata
end
主要代码
C++
:
for(i=0;i<5;i++)
{
.
.
.
pLINGO = LScreateEnvLng();
nError = LSopenLogFileLng(pLINGO,"LINGO.log");
SET ECHOIN 1
是导入并运行
设 置 显 示 方 式
文件
Simple.LNG
与
到此
Lingo
C++之间的接口问题已解决
,
方法解决一个线性规划的问题
,TAKE Simple.LNG \n GO \n
,QUIT \n
为退出
。
下面利用这种
if ( nError) goto ErrorExit;
/
/ @POINTER(1)
。
nError = LSsetPointerLng
(
pLINGO,
dProfit,
计算实例
2
某公司生产两种型号的电脑分别为标准型和改进型
台
型每天至多可以生产
100
,
个工时
台标准型电脑耗费
工厂一天可用总工时不超过
得利润如下表
单位
1
(
¥)
改进型每天至多
一台改进型为
标准
。
生产一
并且该
每台型号的电脑在每天可获
台
120
。
个工时
2
,
,
160。
表
1
每台型号电脑日利润
星期一
星期二
星期三
星期四
星期五
标准型
改进型
a
b
100
201
95
195
96
203
100
202
102
205
&nPointersNow);
if ( nError) goto ErrorExit;
.
.
.
/
/ @POINTER(6)
nError = LSsetPointerLng ( pLINGO, dProduce,
&nPointersNow);
if ( nError) goto ErrorExit;
strcpy (cScript,"SET ECHOIN 1 \n TAKE SIMPLE.
LNG \n GO\n QUIT \n");
nError =LSexecuteScriptLng (pLINGO,cScript); /
/ Run
the script
if ( nError) goto ErrorExit;
LScloseLogFileLng( pLINGO); /
/ Close the log file
求这星期每天应生产两种型号各多少台使得每天的利润
.
.
.
Z
最大
(
假设当天生产当天就出售完
)
台
设生产标准型
对于每一天
,
改进型
台
y
,
x
}
/
省略代码位置
} /
)
结果为
:
由于篇幅原因这里只列出部分
C++代码
(.
.
.
为
maxz=az+by
x≤100
y≤120
∈
∈
∈
∈
∈
∈
∈
∈
∈
∈
∈
∈
∈
x+2y≤160
正整数
整数规划
)
x,y∈z(
由于每天的利润不一样所以用一个
分别求得每天的最优生产量
,
程序
,
Lingo
:
星期一
星期二
星期三
星期四
星期五
台
台
)
)
40
60
40
60
100
30
40
60
100
30
(
($)
16060
15680
15270
16300
16320
标准型
改进型
(
总利润
循环语句进行
次
5
for
所得结果与实际结果相符合
可见由
解决多级规划与循环规划问题是很方便的
。
混合编程
lingo
C++与
。
model:sets:
参考文献
:
computers / standard,turbo / : profit,limit,labor,produce;
Endsets
data:
profit=@pointer (1); limit=@pointer (2);labor=@pointer
(3);
enddata
[rObj] max =@sum (computers (i):profit (i) * produce
[1]
谢 金 星
薛 毅
.
,
优 化 建 模 与
LINDO / LINGO
软 件
[M].
北 京
清 华
:
大学出版社
,2005.
[2]
钱颂迪
顾基发
,
.
运筹学
[M].
北京
:
清华大学出版社
,1982.
责任编辑
陈晓锋
:
)
(