C调用Matlab线性规划DLL二次开发封装DLL

一、Matlab线性规划函数

调用形式:

[X,FVAL,EXITFLAG,OUTPUT,LAMBDA] = linprog( F,A,B,Aeg,Beq,LB,UB)%目标函数为最小值

[X,FVAL,EXITFLAG,OUTPUT,LAMBDA] = linprog(-F,A,B,Aeg,Beq,LB,UB)%目标函数为最大值

输入变量

F 为目标函数中的价值系数向量

A 为不等式约束系数矩阵(注意默认不等式方向为小于等于,若为大于等于,需要将其取相反数)

B 为不等式右端常数向量(注意默认不等式方向为小于等于,若为大于等于,需要将其取相反数)

Aeq 为等式约束系数矩阵

Beq 为等式右端常数向量

LB 为决策变量下界向量 

UB为决策变量上界向量

在调用时,输入参数不存在时,可以将其输入用 [] 空矩阵表示。

输出变量

X 为最优解

FVAL 为最优目标值

EXITFLAG 为运行结束标志,当等于1时,表示程序收敛于解 X;当等于0时,表示程序运行次数到达最大;当小于0时,说明情况较多

OUTPUT 为程序迭代次数

LAMBDA 为解X相关的Largrange乘子和影子价格

参考连接:https://www.cnblogs.com/gshang/p/11486534.html

 

二、C调用Matlab的DLL说明

1、初始化

程序调用DLL前,先初始化mclInitializeApplication(NULL,0);结束时mclTerminateApplication()。

程序调用dll中的函数前,必须先调用XXXInitialize()这个函数,XXX指的是函数名称。程序结束时,要调用XXXTerminate()。其用于加载和卸载需要用到的dll。

例:

 1 mclInitializeApplication(NULL,0);
 2 
 3 XXXInitialize();
 4 
 5 //matlab的dll函数应用代码;
 6 
 7 //mlxXxx(int nlhs, mxArray *plhs[], intnrhs, mxArray *prhs[]);
 8 
 9 XXXTerminate();
10 
11 mclTerminateApplication();

2、mxArray

mxArrayMatlab C函数库的结构体

声明:mxArray *a;

销毁:mxDestroyArray (a);

变量传递:mxArray *dest_ptr =mxCreateDoubleMatrix(rows,cols, mxREAL);

变量赋值:memcpy(dest_ptr,source_ptr,MAX_SIZE);

补充说明:mwArray

mwArrayMatlab C++函数库中对mxArray的包装类。

用的时候mxArray要使用指针,而mwArray直接当类对象使

声明:mwArray a;

销毁:mwArray类的析构函数自动销毁对象。

变量赋值:

mwArray in1(3, 3, mxDOUBLE_CLASS, mxREAL);

mwArray in2(3, 3, mxDOUBLE_CLASS, mxREAL);

in1.SetData(data, 9);

in2.SetData(data, 9);

3、matlab的Dll函数含义

mlxXxx(int nlhs, mxArray *plhs[], intnrhs, mxArray *prhs[])

nlhs代表输出参数个数,plhs[]里面存放的是输出参数的指针,nrhs代表输入参数个数,prhs[]中存放的是输入参数的指针。

mlfXXX(int nargout,mxArray** y,mxArray *)

第一个参数表示输出参数的个数,第二个参数就是输出参数,后面依次是输入参数。

 

三、Matlab线性规划函数制作DLL源码:

文件名:matLinprog.m

function f = matLinprog(F,A,B,Aeq,Beq,LB)
f =linprog(F,A,B,Aeq,Beq,LB); 

制作的DLL库名称为matLinprog.dll

四、C调用演示源码

9个变量,6个不等式,5个等式的线性规划。

  1 #include "matLinprog.h"
  2 #pragma comment( lib, "matLinprog.lib" )
  3 #pragma comment( lib, "mclmcrrt.lib" )
  4 double F[9] = { -1,-1,-1,-1,0,0,0,0,0 };//目标函数,方向得到最大值
  5 double kB[6] = {5316,4252.8,31896,43200,7442.4,400 };
  6 double kBeq[5] = { 0 };
  7 double kLB[9]  = { 0 };
  8 double kX[9] = { 0 };
  9 //!!!下面这个是重点,二维数组系数行列与matlab是转置关系。
 10 double kA[9][6] = { { 5.57, 77.155,      0,      0,     0, 0 },
 11                     { 5.57,      0,      0,      0, 35.78, 1 },
 12                     { 5.57,      0, 471.33, 157.11,     0, 0 },
 13                     { 5.57, 77.155,    180,     60,     0, 0 }, 
 14                     {    0,      0,    240,    360,     0, 0 },
 15                     {    0,      0,      0,      0,     0, 0 },
 16                     {    0, 77.155,      0,      0,     0, 0 },
 17                     {    0,      0, 471.33, 157.11,     0, 0 },
 18                     {    0,      0,      0,      0,     0, 1 } };
 19 double kAeq[9][5] = { { -1,  0, 0, 0, 0 },
 20                       {  0,  0, 0, 0, 0 }, 
 21                       {  0, -1, 0, 0, 0 }, 
 22                       {  0,  0, 0, 0, 1 }, 
 23                       {  1, -1, 0, 0, 0 }, 
 24                       { -1,  0, 0, 0, 0 }, 
 25                       { -1,  0, 1, 0, 0 }, 
 26                       {  0, -1, 0, 1, 0 }, 
 27                       {  0,  1, 0, 0, 0 }};
 28 
 29 //Matlab矩阵打印显示
 30 void display(const mxArray *in)
 31 {
 32     int i = 0;
 33     int j = 0;
 34     int r = 0;
 35     int c = 0;
 36     double *data;
 37     r = mxGetM(in);//得到输入in的行数
 38     c = mxGetN(in);//得到输入in的列数
 39     data = mxGetPr(in);//得到输入in的实部
 40     for (i = 0; i < r; i++)
 41     {
 42         for (j = 0; j < c; j++)
 43         {
 44             printf("%f\t", data[j*r + i]);
 45         }
 46         printf("\n\n");
 47     }
 48     printf("\n");
 49 }
 50 
 51 //double数组打印显示
 52 void displayDouble(double *in, int r, int c)
 53 {
 54     int i = 0;
 55     int j = 0;
 56     for (i = 0; i < r; i++)
 57     {
 58         for (j = 0; j < c; j++)
 59         {
 60             printf("%f\t", *(in + i*c + j));
 61         }
 62         printf("\n\n");
 63     }
 64     printf("\n");
 65 }
 66 
 67 int start_MCR_matLinprog(void)
 68 {
 69     // Set up the application state for the MATLAB Runtime instance created in the application.
 70     if (!mclInitializeApplication(NULL, 0))
 71     {
 72         printf("I could not initialize the application properly");
 73         return -1;
 74     }
 75     printf("I initialize the application properly\n");
 76 
 77     if (!matLinprogInitialize())
 78     {
 79         printf("Could not  initialize matLinprogInitialize!");
 80         return -1;
 81     }
 82     printf("I initialize matLinprogInitialize!\n");
 83     return 0;
 84 }
 85 
 86 void end_MCR_matLinprog(void)
 87 {
 88     matLinprogTerminate();// terminate the lib
 89     mclTerminateApplication();// terminate MCR 
 90 }
 91 
 92 int linprogCalc(double *x)
 93 {
 94     set_varAssign(kB, kA, kAeq, T, N, K);
 95     mxArray *mxF = mxCreateDoubleMatrix(9, 1, mxREAL);
 96     mxArray *mxA = mxCreateDoubleMatrix(6, 9, mxREAL);
 97     mxArray *mxB = mxCreateDoubleMatrix(6, 1, mxREAL);
 98     mxArray *mxAeq = mxCreateDoubleMatrix(5, 9, mxREAL);
 99     mxArray *mxBeq = mxCreateDoubleMatrix(5, 1, mxREAL);
100     mxArray *mxLB = mxCreateDoubleMatrix(9, 1, mxREAL);
101     mxArray *mxX = mxCreateDoubleMatrix(9, 1, mxREAL);
102     mxArray *prhs[6] = { mxF, mxA, mxB, mxAeq, mxBeq, mxLB };//输入
103     mxArray *plhs[1];
104 
105     memcpy(mxGetPr(mxF), (void*)F, sizeof(double)* 9 * 1);
106     memcpy(mxGetPr(mxA), (void*)kA, sizeof(double)* 6 * 9);
107     memcpy(mxGetPr(mxB), (void*)kB, sizeof(double)* 6 * 1);
108     memcpy(mxGetPr(mxAeq), (void*)kAeq, sizeof(double)* 5 * 9);
109     memcpy(mxGetPr(mxBeq), (void*)kBeq, sizeof(double)* 5 * 1);
110     memcpy(mxGetPr(mxLB), (void*)kLB, sizeof(double)* 9 * 1);
111     //display(mxA);//调试时显示用
112     //MatLinprog(1, &mxX, mxF,mxA, mxB, mxAeq, mxBeq, mxLB);C库的另一种调用方法
113     mlxMatLinprog(1, plhs, 6, prhs);//线性规划计算
114     mxX = plhs[0];
115     memcpy(x, mxGetPr(mxX), sizeof(double)* 9 * 1);
116     displayDouble(x, 1, 9);//打印显示
117     //退出时执行的命令
118     //释放内存
119     mxDestroyArray(mxF);
120     mxDestroyArray(mxA);
121     mxDestroyArray(mxB);
122     mxDestroyArray(mxAeq);
123     mxDestroyArray(mxBeq);
124     mxDestroyArray(mxLB);
125     mxDestroyArray(mxX);
126 
127     return 0;
128 }
129 extern __declspec(dllexport)
130 int initAndLinprogCalc(double *x)
131 {
132     start_MCR_matLinprog();
133     linprogCalc(x);
134     end_MCR_matLinprog();
135     return 0;
136 }

 工程建立参考https://www.cnblogs.com/chunleixin/p/MatlabDll.html

C调用Matlab线性规划DLL二次开发封装DLL

上一篇:网页添加优酷视频


下一篇:css span提示框 练习(不能用div)