【CPLEX教程03】java调用cplex求解一个TSP问题模型

00 前言

前面我们已经搭建好cplex的java环境了,相信大家已经跃跃欲试,想动手写几个模型了。今天就来拿一个TSP的问题模型来给大家演示一下吧~

CPLEX系列教程可以关注我们的公众号哦!获取更多精彩消息!

01 TSP建模

关于TSP建模,就不多解释了。以及什么是TSP问题,也不要问我了。直接贴一个现成的模型出来吧。

02 程序框架

整个程序框架如图,app下是调用cplex的主要package。


其中:

  • App.java:程序入口,cplex调用建模求解过程。
  • ConstraintFactory.java:控制子环约束的。
  • FileManager.java:读取instance数据的。

package graph定义了一些变量,在求解过程中需要用到。input是算例,包含100-9000个城市。

03 求解过程

求解过程可以分为以下几步进行:

  1. 定义一个模型
IloCplex model = new IloCplex();
  1. 定义决策变量,boolVar可以返回一个01的bool类型决策变量。
// define variables
IloIntVar[][] x = new IloIntVar[data.size()][data.size()];
for (int i = 0; i < x.length; i++) {
    for (int j = 0; j < x.length; j++) {
        x[i][j] = model.boolVar("X[" + i + ", " + j + "]");
    }
}
  1. 添加约束7-1,addTerm将1*x[i][j]添加进表达式r里面,最终r的取值是里面所有的元素之和,也就是\(1*x[i][1]+1*x[i][2]+...+1*x[i][n]\)。
// one has only a city to go, and should
for (int i = 0; i < x.length; i++) {
    IloLinearIntExpr r = model.linearIntExpr();
    for (int j = 0; j < x.length; j++) {
//                      if (i == j)
//                          continue;
        r.addTerm(1, x[i][j]);
    }
    model.addEq(r, 1);
}
  1. 添加约束7-2,原理同上一条。
// one can only arrive to one city at a time, and should
for (int j = 0; j < x.length; j++) {
    IloLinearIntExpr r = model.linearIntExpr();
    for (int i = 0; i < x.length; i++) {
//                      if (i == j)
//                          continue;
        r.addTerm(1, x[i][j]);
    }
    model.addEq(r, 1);
}
  1. 添加约束7-3,子环约束处理有点复杂,但这个不是本文重点,读者自行理解。
// add cycle restrictions
for (Stack<Edge> stack : stacks) {
//                  stack.forEach((edge) -> System.out.println(edge.getFrom() + "->" + edge.getTo()));
    constraintFactory.cycleRestrictions(model, x, stack);
}
  1. 添加目标函数,z的表达式同上。
// one should complete the tour within the smallest distance possible
IloLinearNumExpr z = model.linearNumExpr();
for (int i = 0; i < x.length; i++) {
    for (int j = 0; j < x.length; j++) {
        if (i == j)
            continue;
        z.addTerm(distance[i][j], x[i][j]);
    }
}
  1. 确定目标是最小化目标
model.addMinimize(z);
  1. 开始求解
if (model.solve()) {

    // get tour
    for (int i = 0; i < x.length; i++) {
        for (int j = 0; j < x.length; j++) {
            if (model.getValue(x[i][j]) >= 0.5) {
                tour.add(new Edge(i, j));
            }
        }
    }

    // repaint tour
} else {
    System.err.println("Boi, u sick!");
    System.exit(1);
}

注意,一次求解不一定能求得最优解,小编跑了一个早上都跑不出来,还是100个节点的。model.getValue(x[i][j]) >= 0.5这个判断只是把求解过程中一些较好的边给添加进去而已。最优解是要满足所有约束的。

04 运行说明

代码下载请关注我们的公众号哦!后台回复【CPTSP】不包括【】即可下载。

代码来源GitHub,小编去掉了部分代码。期待后期进一步精简和修改,大家下载下来后用eclipse导入,设置好cplex环境以后。在App.java里面,右键Run As->Run configurations...:

找到App,在Arguments窗口,找到Program arguments:

输入参数说明:
--instancePath+空格+算例文件的路径,注意用英文双引号括起来。
--maximumRead+空格+数字,表示算例大小,也就是多少个城市,文件名可以直接看出。

然后就可以愉快的run了。

附上运行结果:

大家可以在while(count<1)这个条件里面更改迭代次数,以便能获取更好的解。

原文地址:https://www.cnblogs.com/dengfaheng/p/11162150.html

时间: 2024-10-08 02:39:56

【CPLEX教程03】java调用cplex求解一个TSP问题模型的相关文章

使用java调用python训练出的pmml模型

作为一个2,3年没有用过java的数据挖掘工程师,突然要用java来调用pmml模型,真的好烦啊. 在网上找了一段代码,自己试了1个礼拜才运行成功,记录下自己的过程,以后可以随时用,如果能帮到大家就更好了. 从安装软件说起,嫌麻烦的就别看了. 一.下载工具(俗话说得好,预先善其事必先利其器!哈哈) 我刚开始安装的是eclipse,但有诸多麻烦不能解决,就用了IDEA,和Pycharm一个公司发行的. 首先进入官网: http://www.jetbrains.com/products.html#l

代码 | 用ALNS框架求解一个TSP问题 - 代码详解

写在前面 前面好多篇文章,我们总算是把整个ALNS的代码框架给大家说明白了.不知道大家对整个框架了解了没有.不过打铁要趁热,心急了要吃热豆腐.今天就来实战一下,教大家怎么用ALNS的代码框架,求解一个老生常谈的TSP问题,so,get ready? 01 文件说明 整个项目由多个文件组成,为了大家更好了解各个文件的内容以及他们之间的关系,小编特地做了一份表格说明. 类名或文件名 说明 main 主文件 TSPSolution Solution的定义和各种相关操作 TSP_LS LocalSear

机器学习——Java调用sklearn生成好的Logistic模型进行鸢尾花的预测

机器学习是python语言的长处,而Java在web开发方面更具有优势,如何通过java来调用python中训练好的模型进行在线的预测呢?在java语言中去调用python构建好的模型主要有三种方法: 1.在Java语言中,通过python的解释器执行python代码,简单来说就是在java中通过python解释器对象,传入写好的python代码,进行执行,这样的方式运行的效率非常低,而且存在很多python包无法使用的情况,只适合做简单的python代码的运行,并不推荐使用. 2.通过PMML

零基础大数据入门教程:Java调用阿里云短信通道服务

这里我们使用SpringBoot 来调用阿里通信的服务. 阿里通信,双11.收到短信,日发送达6亿条.保障力度非常高. 使用的步骤: 1.1. 第一步:需要开通账户 1.2. 第二步:阅读接口文档 1.2.1. 秘钥管理 1.2.2. 短信签名 1.2.3. 短信模板 1.3. SDK 这个由阿里云提供. 编译与打包. 打包到本地仓库,或者公司局域网内的私服地址. Maven打包 1.4. 第三步:创建SpringBoot工程,导入依赖 <!-- sms单独打包 --> <depende

Java调用WebService 接口 实例

这里给大家介绍一下,Java调用webservice的一个实例的过程. 本项目不能运行,因为接口地址不可用. 这里只是给大家介绍一个过程,同时留作自己的笔记.如果要学习,可以参照别人的实例.比较好. ①选择项目根目录的src ,右键,new --> webservice client 然后输入地址: http://172.18.100.52:456/hello?wsdl 必须要加wsdl结尾,这样才是一个webservice的接口. finlish.这时候刷新项目.可以看到项目下/src/com

android开发教程(4)— jni编程之采用 javah 从java调用C++

用Java调用C/C++代码 当无法用 Java 语言编写整个应用程序时,JNI 允许您使用本机代码.在下列典型情况下,您可能决定使用本机代码: 希望用更低级.更快的编程语言去实现对时间有严格要求的代码. 希望从 Java 程序访问旧代码或代码库. 需要标准 Java 类库中不支持的依赖于平台的特性. 须知:SWIG和javah的区别(强烈推荐) 我看了网上的关于 jni编程 的教程很多,但不尽相同,刚开始会犯迷糊.我想笔者往往忽略了一个关键点,那就是采用了什么方式决定了步骤的流程.有两种生成

java接口调用——webservice就是一个RPC而已

很多新手一听到接口就蒙逼,不知道接口是什么!其实接口就是RPC,通过远程访问别的程序提供的方法,然后获得该方法执行的接口,而不需要在本地执行该方法.就是本地方法调用的升级版而已,我明天会上一篇如何通过socket实现rpc,以及服务的注册和动态上下线.这里先上一篇RPC的实现者一webservice,便于后面理解源码执行过程,框架就是在原理的基础上提供更加便捷的使用而已,协议就是基于TCP或UDP之上,服务者和调用者之间约定消息按照什么样的格式发送以及解析罢了.协议没什么高深莫测的. 原文和作者

Java调用cmd命令 打开一个站点

使用Java程序打开一个站点 近期做了个东西使用SWT技术在一个client程序 须要升级时在提示升级 点击窗口上的一个连接 打开下载网页 花费了我非常长时间 用到了把它记录下来  怕是忘记,须要时能够直接来用到.         try { //不是在Java程序中运行而是在操作系统中运行             Runtime.getRuntime().exec("cmd /c start http://blog.csdn.net/blogluoqi/"); //Runtime.g

Alex 的 Hadoop 菜鸟教程: 第11课 Hive的Java调用

声明 本文基于Centos 6.x + CDH 5.x 说到Hive就一定要说到写程序的时候怎么调用Hive.以下我通过一个例子说明如果通过java来调用hive查询数据 数据准备 建立一个文本文件叫 a.txt,内容是 1,terry 2,alex 3,jimmy 4,mike 5,kate 并上传到hive服务器的  /data/ 目录下 JDBC调用方法 加载Driver 加载driver (只说hive2的jdbc) Class.forName("org.apache.hive.jdbc