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
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 }