您的位置:首页 > 编程语言 > Go语言

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千克材料.生产成本是非线性函数,如下表.要求建立一个总利润最大的数学模型.

产品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
设生产产品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工程,也即默认选项。



Project->Add to Project->New.选择Files页面,C++ SourceFile,输入文件名比如CB。



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

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  产品 fortran user 语言 c dll