LINGO调用VC编写的函数动态库实验
2012-08-31 22:50
176 查看
Visual C++编写函数,然后用动态库的形式输出该函数供LINGO调用.
某公司生产A,B和C三种产品,售价分别是12元、7元和6元.生产每件A产品需要1小时技术服务、10小时直接劳动、3千克材料;生产每件B产品需要2小时技术服务、4小时直接劳动、2千克材料;生产每件C产品需要1小时技术服务、5小时直接劳动、1千克材料.现在最多能提供100小时技术服务、700小时直接劳动、 400千克材料.生产成本是非线性函数,如下表.要求建立一个总利润最大的数学模型.
设生产产品Ax1件,生产产品Bx2件生产产品Cx3 件.问题的难点是产品的成本是一个分段函数,难以用线性函数表达,因此可采用动态库编写一个专门的函数来计算成本.
设产品A每件的成本为a元,产品B每件的成本为b元,产品C每件的成本为c元。a、b、c随 x1,x2,x3而改变
目标函数为:
maxZ=12x1+7x2+6x3-(ax1+bx2+cx3);
a、b、c为分段函数。
由于目标函数是非线性的,且难以用一个式子表达,因此采用自己编写库函数的方式来实现。这里介绍@USER函数。该函数允许用户自己编写函数,该函数允许用户自己编写函数,该函数应当用C或FORTRAN语言编写,返回值为用户计算的结果.
@USER函数包含两个参数:第一个用于指定参数的个数,第二个用于指定参数向量(类似于C语言中的main(argc,argv)的编写格式).在LINGO中调用USER时则直接指定对应的参数(类似C语言中的main(argc,argv)的执行格式). 该函数采用动态库编写.这里的例子采用VC编写动态库.注意动态库中该函数名固定为MYUSER,在LINGO中调用时则固定外部函数名为USER.
过程如下,
启动VC,新建动态链接库项目,选择空的dll工程,也即默认选项。
![](http://img.my.csdn.net/uploads/201208/31/1346421890_2418.jpg)
Project->Add to Project->New.选择Files页面,C++ SourceFile,输入文件名比如CB。
![](http://img.my.csdn.net/uploads/201208/31/1346422093_9635.jpg)
CB.cpp内容
程序中MYUSER函数的第一个整型变量NumArgs代表输入变量的个数。
第二个输入为向量x,也就是外部输入的变量。
第三个变量dResult用于返回最后的计算结果。
用LINGO调用时只需输入各变量就行了,函数自动返回C++程序计算的结果dResult。(是不是说只能有一个返回值???而不是返回结果向量??)
Lingo模型
结果
Local optimal solution found.
Objective value: 263.0000
Objective bound: 263.0000
Infeasibilities: 0.5000000E-06
Extended solver steps: 2
Total solver iterations: 7231
Variable Value Reduced Cost
X1 41.00000 -4.500000
X2 1.000000 0.000000
X3 57.00000 -0.5000001
Row Slack or Surplus Dual Price
1 263.0000 1.000000
2 0.000000 0.5000000
3 1.000002 0.000000
4 218.0000 0.000000
某公司生产A,B和C三种产品,售价分别是12元、7元和6元.生产每件A产品需要1小时技术服务、10小时直接劳动、3千克材料;生产每件B产品需要2小时技术服务、4小时直接劳动、2千克材料;生产每件C产品需要1小时技术服务、5小时直接劳动、1千克材料.现在最多能提供100小时技术服务、700小时直接劳动、 400千克材料.生产成本是非线性函数,如下表.要求建立一个总利润最大的数学模型.
产品A (件) | 成本 (元/件) | 产品B (件) | 成本 (元/件) | 产品C (件) | 成本 (元/件) |
0~40 41~100 101~ 150 150以上 | 10 9 8 7 | 0~50 51~100 100以上 | 6 4 3 | 0~100 100以上 | 5 4 |
设产品A每件的成本为a元,产品B每件的成本为b元,产品C每件的成本为c元。a、b、c随 x1,x2,x3而改变
目标函数为:
maxZ=12x1+7x2+6x3-(ax1+bx2+cx3);
a、b、c为分段函数。
由于目标函数是非线性的,且难以用一个式子表达,因此采用自己编写库函数的方式来实现。这里介绍@USER函数。该函数允许用户自己编写函数,该函数允许用户自己编写函数,该函数应当用C或FORTRAN语言编写,返回值为用户计算的结果.
@USER函数包含两个参数:第一个用于指定参数的个数,第二个用于指定参数向量(类似于C语言中的main(argc,argv)的编写格式).在LINGO中调用USER时则直接指定对应的参数(类似C语言中的main(argc,argv)的执行格式). 该函数采用动态库编写.这里的例子采用VC编写动态库.注意动态库中该函数名固定为MYUSER,在LINGO中调用时则固定外部函数名为USER.
过程如下,
启动VC,新建动态链接库项目,选择空的dll工程,也即默认选项。
![](http://img.my.csdn.net/uploads/201208/31/1346421890_2418.jpg)
Project->Add to Project->New.选择Files页面,C++ SourceFile,输入文件名比如CB。
![](http://img.my.csdn.net/uploads/201208/31/1346422093_9635.jpg)
CB.cpp内容
程序中MYUSER函数的第一个整型变量NumArgs代表输入变量的个数。
第二个输入为向量x,也就是外部输入的变量。
第三个变量dResult用于返回最后的计算结果。
用LINGO调用时只需输入各变量就行了,函数自动返回C++程序计算的结果dResult。(是不是说只能有一个返回值???而不是返回结果向量??)
#include <WINDOWS.H> #include <string.h> #include <stdio.h> #include <STDLIB.H> #include <MATH.H> #define N 3 #define DllExport extern "C" _declspec(dllexport)//导出函数 //该函数计算成本 DllExport void MYUSER(int* NumArgs,double *x,double *dResult) { double sum; if (*NumArgs<N) { MessageBox(NULL,"输入变量不足","输入错误",MB_OK); *dResult=-1; exit(0); } sum=0; //产品A的成本计算 if (x[0]>=0 && x[0]<=40) { sum+=10*x[0]; } else if (x[0]>=41 && x[0]<=100)//原书错误为x[1] { sum+=9*x[0]; } else if (x[0]>=101 && x[0]<=150) { sum+=8*x[0]; } else sum+=7*x[0]; //产品B的成本计算 if (x[1]>=0 && x[1]<=50) { sum+=6*x[1]; } else if (x[1]>=51 && x[1]<=100) { sum+=4*x[1]; } else { sum+=3*x[1]; } //产品C的成本计算 if (x[2]>=0 && x[2]<=100) { sum+=5*x[2]; } else { sum+=4*x[2]; } *dResult=sum;//返回成本总值 }按F7运行后生成动态库CALC.DLL,将其拷贝到LINGO目录下,并将文件改名为MYUSER.DLL。启动LINGO就可以通过外部函数@USER调用动态库中自己编写的函数。
Lingo模型
!采用动态库编写自己的函数; MODEL: max=12*x1+7*x2+6*x3-@USER(x1,x2,x3);!目标函数; x1+2*x2+x3<=100;!技术服务的约束; 10*x1+4*x2+5*x3<=700;!直接劳动的约束; 3*x1+2*x2+x3<=400;!材料的约束; @GIN(x1); @GIN(x2); @GIN(x3); END
结果
Local optimal solution found.
Objective value: 263.0000
Objective bound: 263.0000
Infeasibilities: 0.5000000E-06
Extended solver steps: 2
Total solver iterations: 7231
Variable Value Reduced Cost
X1 41.00000 -4.500000
X2 1.000000 0.000000
X3 57.00000 -0.5000001
Row Slack or Surplus Dual Price
1 263.0000 1.000000
2 0.000000 0.5000000
3 1.000002 0.000000
4 218.0000 0.000000
相关文章推荐
- 【PB】powerbuilder调用VC编写的动态链接库
- 编写一个函数,此函数使用动态存储分配来产生一个字符串的副本。例如函数为strclone,则调用p=strclone(str),将会为一个新的字符串分配和str占内存大小相同的一个字符串,并将字符串st
- VC++中调用MATLAB *.m函数编译后的动态链接库
- DELPHI调用VC编写的DLL 函数参数为LPTSTR
- DLL DEF文件编写方法 VC++ 调用、调试DLL的方法 显式(静态)调用、隐式(动态)调用
- 利用VC调用动态链接库中的函数
- 如何在VC中汇编,调用Nasm编写的函数
- 利用VC调用动态链接库中的函数
- 如何在VC中汇编,调用Nasm编写的函数
- PB调用VC编写的动态链接库
- 利用VC调用动态链接库中的函数
- 如何在VC中汇编,调用Nasm编写的函数
- 利用VC调用动态链接库中的函数
- VC++编写DLL导出函数及其调用方法
- 利用VC调用动态链接库中的函数
- 利用VC调用动态链接库中的函数
- [随便说说]关于函数的显式调用和隐式调用(动态调用)--VC++
- C++ builder调用vc编写的动态链接库的方法
- 编写一个函数,从标准输入读取一列整数,把这些值存储于一个动态分配的数组中并返回这个数组。函数通过观察EOF判断输入列表是否结束。数组的第一个数是数组包含的值的个数,他的后面就是这些整数值。
- VC++中的函数调用(CALLBACK WINAPI PASCAL 等)