c#与matlab混合编程解决线性规划,非线性规划(二次规划)等问题

网上已经有很多类似方法,上一篇是Lingo,本篇是matlab,两个软件在解决最优解方面各有优势。
matlab软件中自带许多函数:
1:非线性规划:
[x,fval]=fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,);
fun: 目标函数
x0:最优解的初始值
A,B: 线性约束不等式 A * x <= b;
Aeq,Beq: 线性约束等式 Aeq * x = Beq;
lb: 自变量下届
ub: 自变量上界
nonlcon:非线性约束函数

2:线性规划:
[x,fval]= linprog(f,A,b,Aeq,beq,lb,ub,x0)

3:二次规划:
[S,y] =quadprog(H,f,A,B,Aeq,beq,lb,ub,x0)

本片着重讲解C#调用matlab解决二次规划问题
所用目标函数和约束条件还是上一篇的例子
目标函数:
min=(x1-80)^2 + (x2-10)^2 + (x3-10)^2
约束条件:
-x1 * 0.216 -x2 * 0.392 +x3 * 2.120 = y1;
-x1 * 0.0020-x2 * 0.176 + x3 * 0.336 =y2;
-x1 * (1-0.0943)* 0.282 -x2 (1-0.0833) 0.462 + x3 * (1-0.087)* 0.296 = y3;
1< x1,x2,x3<99;
-0.5<y1,y2,y3<0.5;
x1+x2+x3 =100;

首先看看matlab如何解决:
其中H = diag([2,2,2]);比较难理解可以参考此博主的这篇文章:
https://blog.csdn.net/jbb0523/article/details/50598641
在这里插入图片描述接下来展示C#项目调用matlab的方法
首先在matlab写好文件
在这里插入图片描述其次在matlab命令行中输入deploytool,有如下选择
在这里插入图片描述选择Library Compiler, 1:.Net Assembly 2:选择刚保存好的.m文件 3:点击Package
在这里插入图片描述

做完上述操作后,在bin目录下可以看到myquadprog文件目录,找到里面的dll,放到项目中引用
在这里插入图片描述
如下图所示,添加myquadprog.dll ,之前也做过fmincom,linprog的测试了,所以会有这两个引用。

在这里插入图片描述接下来项目编写脚本

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using myLinprog;
using myfmincom;
using myquadprog;
using MathWorks.MATLAB.NET.Arrays; 

namespace XianXingGuiHua
{
    class Program
    {
        static void Main(string[] args)
        {
            //MWArray Hs = (MWNumericArray)new double[3, 3];
            //Hs[1] = 2;   测试,将界面的值依次赋予
            //Hs[2] = 0;
            //Hs[3] = 0;
            //Hs[4] = 0;
            //Hs[5] = 2;
            //Hs[6] = 0;
            //Hs[7] = 0;
            //Hs[8] = 0;
            //Hs[9] = 2; 


            MWArray H = (MWNumericArray)new double[,] { { 2, 0, 0 }, { 0, 2,0 }, { 0, 0, 2 } };
            MWArray ff = (MWNumericArray)new double[] { -140, -20, -40 };
            MWArray AA = (MWNumericArray)new double[,] { { -0.216, -0.392, 2.120 }, 
                                                         { 0.216, 0.392, -2.120 },
                                                         { -0.02,-0.176,0.336 },
                                                         { 0.02,0.176,-0.336 },
                                                         { -(1-0.0943)*0.282,-(1-0.0833)*0.462,(1-0.087)*2.698 },
                                                         {(1-0.0943)*0.282,(1-0.0833)*0.462,-(1-0.087)*2.698 }
                                                       };
            MWArray bb = (MWNumericArray)new double[] { 0.5, 0.5, 0.5, 0.5, 0.5, 0.5 };
            MWArray Aeqq = (MWNumericArray)new double[] { 1, 1, 1 };
            MWArray Beqq = (MWNumericArray)new double[] { 100 };
            MWArray lbb = (MWNumericArray)new double[] { 0, 0, 0 };
            MWArray ubb = (MWNumericArray)new double[] { };
            MWArray x00 = (MWNumericArray)new double[] { 1, 1, 1,1 };
            MWArray[] agrsInn = new MWArray[] { (MWNumericArray)H, (MWNumericArray)ff, (MWNumericArray)AA, (MWNumericArray)bb, (MWNumericArray)Aeqq, (MWNumericArray)Beqq, (MWNumericArray)lbb, (MWNumericArray)ubb, (MWNumericArray)x00 };//输入参数            


            MWArray[] agrsOutt = new MWArray[2]; //输出存放的数组

            myquadprog.Class1 mf = new myquadprog.Class1(); //二次规划
            mf.myquadprog(2, ref agrsOutt, agrsInn);  


            Console.WriteLine("x最优值为 : \t");


            int c1 = int.Parse(Double.Parse(agrsOutt[0][1].ToString()).ToString("#0."));
            int c2 = int.Parse(Double.Parse(agrsOutt[0][2].ToString()).ToString("#0."));
            int c3 = int.Parse(Double.Parse(agrsOutt[0][3].ToString()).ToString("#0."));

            Console.WriteLine(agrsOutt[0][1] + "----" + agrsOutt[0][2] + "----" + agrsOutt[0][3]);

            Console.WriteLine("得到的y值为 : \t" + agrsOutt[1]);
            Console.ReadKey();
    
        }
    }
}



运行结果如下:
在这里插入图片描述
最后成功解决,但是有一个小问题,就是限定整数的问题,在线性规划上,matlab有intprog函数解决,但是像此例子,非线性规划,还是比较特殊的二次规划,就没办法解决最优解是整数的问题了,所以这时候只能用lingo解决了,大家如果对matlab精深,有更好的方法欢迎讨论,共同研究一下。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值