1. 程式人生 > 其它 >C呼叫Matlab線性規劃DLL二次開發封裝DLL

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