一、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
mxArray是Matlab C函数库的结构体
声明:mxArray *a;
销毁:mxDestroyArray (a);
变量传递:mxArray *dest_ptr =mxCreateDoubleMatrix(rows,cols, mxREAL);
变量赋值:memcpy(dest_ptr,source_ptr,MAX_SIZE);
补充说明:mwArray
mwArray是Matlab 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 }