美文网首页
Java如何连接MATLAB,实现函数调用

Java如何连接MATLAB,实现函数调用

作者: 程序员网址导航 | 来源:发表于2020-05-04 12:37 被阅读0次

    前言

    最近帮大四的弟弟解决了一个毕设的难题,课题内容大概是这样的:“Matlab利用调度算法实现一个车间零部件生产调度任务,最后MTALB会生成一个调用结果甘特图。现在需要通过Java web应用配置程序的入参,以及通过Java自动化操作Matlab进行传参,以及在web端可视化matlab的执行结果。”

    之前没有没有做过类似Java操作MATLAB的经验,在实现的过程中遇到好多坑:“java连接不上matlab?”,“JDK版本、Matlab版本有关系吗?”,“如何传递矩阵?”,“结果拿不到?”……

    在国内几乎0资料背景下,查阅了不少国外文档、Matlab相关源码,费了很大劲最终才解决,所以记录下,希望可以帮助到有同样问题的同学。

    效果

    1. java web应用启动过程自动拉起MATLAB程序
    image.png
    1. 通过web应用连接调用matlab程序,最后执行结果(图片+文字)实现可视化。


      image.png

    具体实现核心步骤

    环境准备

    安装JDK(建议1.8)、安装MATLAB

    IDEA(开发工具,可更换为其他的)
    MySQL(如果需要数据存储、肯定是需要一个RDMS)

    驱动包

    matlab-control.jar
    通过matlab-control实现Java和Matlab混合编程的方法,并将该方法应用于过程控制仿真实验系统的研究和开发。

    下载地址:https://www.mvnjar.com/org.n52.matlab/matlab-control/5.0.0/detail.html

    下载后需要倒入你的java应用中(导入方法有疑问的话,找度娘吧)

    准备matlab程序

    main.m demo程序

    # 定义一个main函数,它有一个T入参和一个out返回值
    function [out] = main(T)
    
    具体实现根据你的需要编写……
    
    

    java程序

    
    import org.n52.matlab.control.*;
    import org.n52.matlab.control.extensions.MatlabNumericArray;
    import org.n52.matlab.control.extensions.MatlabTypeConverter;
    import org.springframework.util.ResourceUtils;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    
    /****
     * 模拟java连接matlab
     * @Author http://wwww.relaxheart.cn  王琦
     */
    public class MatlabTest {
    
        /***
         * 指定matlab程序所处的位置,注意是文件夹形式
         */
        private static final String matlabFile = "C:\\Users\\Administrator\\Desktop\\matlab";
        /***
         * matlab启动程序的路径,因为后续通过这个路径来拉起matlab应用程序
         */
        private static final String matlabExe = "G:\\MATLAB\\R2018a\\bin\\matlab.exe";
    
        public static void main(String[] args) throws MatlabConnectionException, MatlabInvocationException, FileNotFoundException {
            File file = null;
            try {
                System.out.println(">>>>>>>>>>>>>>>>>>>>> Mtalab文件获取开始...");
                file = ResourceUtils.getFile(matlabFile);
            } catch (FileNotFoundException e) {
                System.out.println("Mtalab文件获取失败!");
            }
            System.out.println(">>>>>>>>>>>>>>>>>>>>> Mtalab文件获取成功!");
            System.out.println(">>>>>>>>>>>>>>>>>>>>> Mtalab建立连接...");
            MatlabProxyFactoryOptions options = new MatlabProxyFactoryOptions.Builder()
                    .setProxyTimeout(300000L)
                    .setMatlabStartingDirectory(file)
                    .setHidden(false)
                    .setMatlabLocation(matlabExe)
                    .build();
            System.out.println(">>>>>>>>>>>>>>>>>>>>> 开始拉起MATLAB程序...");
            // 通过matlab代理工厂,创建matlab代理,后续通过代理操作matlab
            MatlabProxyFactory factory = new MatlabProxyFactory(options);
            MatlabProxy proxy = factory.getProxy();
            System.out.println(">>>>>>>>>>>>>>>>>>>>> MATLAB连接成功!");
    
            System.out.println(">>>>>>>>>>>>>>>>>>>>> JAVA 调用 MATLAB 程序...");
            // 构造矩阵入参
            double[][] in = createMockInputDataArray();
            // 注意传递二维以上数组型入参,需要同MatlabNumericArray包装后传递,否则会报错
            MatlabNumericArray input = new MatlabNumericArray(in, null);
            MatlabTypeConverter converter = new MatlabTypeConverter(proxy);
            converter.setNumericArray("in", input);
            // 调用matlab程序
            proxy.eval("[out]=main(in,path)");
            // 获取返回值
            double[][] out = converter.getNumericArray("out").getRealArray2D();
            System.out.println(">>>>>>>>>>>>>>>>>>>>> java invoke matlab success");
            // 断开连接
            proxy.exit();
        }
    
        /***
         * 构造一个输入参数
         * @return
         */
        private static double[][] createMockInputDataArray() {
            String p = "1   1   2   3   6   3;" +
                    "1  2   2   8   16  1; " +
                    "1  3   2   9   18  2; " +
                    "1  4   2   2   4   4;" +
                    " 1 5   2   3   6   6;" +
                    " 1 6   2   2   4   5; " +
                    "2  1   3   6   18  2; " +
                    "2  2   3   8   24  3; " +
                    "2  3   3   2   6   6; ";
            String[] p1 = p.split(";");
            double[][] input = new double[p1.length][6];
            for (int i = 0; i < p1.length; i++) {
                String[] num = p1[i].split("\t");
                input[i][0] = Integer.parseInt(num[0].trim());
                input[i][1] = Integer.parseInt(num[1].trim());
                input[i][2] = Integer.parseInt(num[2].trim());
                input[i][3] = Integer.parseInt(num[3].trim());
                input[i][4] = Integer.parseInt(num[4].trim());
                input[i][5] = Integer.parseInt(num[5].trim());
            }
            return input;
        }
    }
    
    

    --- 上面是一个Java连接matlab示例,那Javaweb应用具体如何连接 ---

    我的web应用选用的spring boot框架,在上面的基础上我需要做一些调整。我不希望每次调用都需要拉起一个matlab。

    spring boot application.xml

    #matlab 文件路径
    matlab.file.path=C:\\Users\\Administrator\\Desktop\\matlab
    #matlab 启动程序 路径
    matlab.exe.path=G:\\MATLAB\\R2018a\\bin\\matlab.exe
    

    MatlabConfiguration.java 创建一个matlabProxy bean

    import com.digitization.util.DateUtil;
    import org.n52.matlab.control.MatlabConnectionException;
    import org.n52.matlab.control.MatlabProxy;
    import org.n52.matlab.control.MatlabProxyFactory;
    import org.n52.matlab.control.MatlabProxyFactoryOptions;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.util.ResourceUtils;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    
    /****
     * @Author http://wwww.relaxheart.cn  王琦
     */
    @Configuration
    public class MatlabConfiguration {
    
        @Value("${matlab.file.path}")
        private String matlabFilePath;
        @Value("${matlab.exe.path}")
        private String matlabExePath;
    
        @Bean(name = "matlabProxy")
        public MatlabProxy createFactory() throws MatlabConnectionException {
            File file = null;
            try {
                System.out.println(DateUtil.getDateStr()+" -------------------------> MATLAB文件获取开始...");
                file = ResourceUtils.getFile(matlabFilePath);
            } catch (FileNotFoundException e) {
                System.out.println(DateUtil.getDateStr()+" -------------------------> MATLAB文件获取失败!");
            }
            System.out.println(DateUtil.getDateStr()+" -------------------------> MATLAB文件获取成功!");
            System.out.println(DateUtil.getDateStr()+" -------------------------> JAVA与MATLAB开始建立连接...");
            MatlabProxyFactoryOptions options = new MatlabProxyFactoryOptions.Builder()
                    .setProxyTimeout(300000L)
                    .setMatlabStartingDirectory(file)
                    .setHidden(false)
                    .setMatlabLocation(matlabExePath)
                    .build();
            System.out.println(DateUtil.getDateStr()+" -------------------------> 开始拉起MATLAB应用程序...");
            MatlabProxyFactory factory = new MatlabProxyFactory(options);
            MatlabProxy proxy = factory.getProxy();
            System.out.println(DateUtil.getDateStr()+" -------------------------> MATLAB应用程序已经启动!");
            System.out.println(DateUtil.getDateStr()+" -------------------------> JAVA与MATLAB开始建立连接成功!");
            return proxy;
        }
    }
    
    

    在再具体需要的时候只需要注入这个matlabProxy bean即可

    /****
     * @Author http://wwww.relaxheart.cn  王琦
     */
    @Service
    public class MatlabService {
    
        @Autowired
        private MatlabProxy matlabProxy;
    
        public void task() {
                ……略
                // 调用Matlab程序
                matlabProxy.eval("[out]=main(in)");
                 ……略
         }
    

    完结!!!

    原文:JAVA如何连接MATLAB,实现函数调用

    最后欢迎浏览我的个人兴趣分享网站: http://www.wangqi94.com

    相关文章

      网友评论

          本文标题:Java如何连接MATLAB,实现函数调用

          本文链接:https://www.haomeiwen.com/subject/lvmeghtx.html