代码

package com.dam.heuristic.util.paint;import com.dam.heuristic.ils.test.IlsApi;
import com.dam.heuristic.ts.test.TsApi;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;import java.io.File;
import java.io.FileInputStream;public class PaintTspResult extends Application {//存储每个城市对应的x,y坐标private double[][] cityPositionArr;//存储城市序列private int[] sequence;//当前的时间轴private Timeline nowTimeline;public static void main(String[] args) {launch(args);}@Overridepublic void start(Stage primaryStage) throws Exception {调用tsp求解算法double[][] distanceMatrix = this.getDistanceMatrix();TsApi TSApi = new TsApi(20, 100000, 100, distanceMatrix);this.sequence = TSApi.solve();画图try {BorderPane root = new BorderPane();root.setStyle("-fx-padding: 20;");Scene scene = new Scene(root, 1600, 900);double canvasWid = 1500;double canvasHei = 800;//根据画布大小缩放坐标值this.fixPosition(canvasWid - 50, canvasHei - 50);//画布和画笔HBox canvasHbox = new HBox();Canvas canvas = new Canvas();canvas.setWidth(canvasWid);canvas.setHeight(canvasHei);canvasHbox.setPrefWidth(canvasWid);canvasHbox.getChildren().add(canvas);canvasHbox.setAlignment(Pos.CENTER);canvasHbox.setStyle("-fx-spacing: 20;" +"-fx-background-color: #ecf1c3;");root.setTop(canvasHbox);GraphicsContext paintBrush = canvas.getGraphicsContext2D();//启动HBox hBox2 = new HBox();Button beginButton = new Button("启动 Tsp 路线可视化");hBox2.getChildren().add(beginButton);root.setBottom(hBox2);hBox2.setAlignment(Pos.CENTER);//启动仿真以及暂停仿真beginButton.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {nowTimeline.play();});//创建扫描线连接动画nowTimeline = new Timeline();createAnimation(paintBrush, 0.1);drawAllCircle(paintBrush);primaryStage.setScene(scene);primaryStage.show();} catch (Exception e) {e.printStackTrace();}}/*** 修正cityPositionArr的坐标,让画出来的点在画布内** @param width* @param height*/private void fixPosition(double width, double height) {double minX = Double.MAX_VALUE;double maxX = -Double.MAX_VALUE;double minY = Double.MAX_VALUE;double maxY = -Double.MAX_VALUE;for (int i = 0; i < this.cityPositionArr.length; i++) {minX = Math.min(minX, this.cityPositionArr[i][0]);maxX = Math.max(maxX, this.cityPositionArr[i][0]);minY = Math.min(minY, this.cityPositionArr[i][1]);maxY = Math.max(maxY, this.cityPositionArr[i][1]);}double multiple = Math.max((maxX - minX) / width, (maxY - minY) / height);for (int i = 0; i < this.cityPositionArr.length; i++) {this.cityPositionArr[i][0] = this.cityPositionArr[i][0] / multiple + 20;this.cityPositionArr[i][1] = this.cityPositionArr[i][1] / multiple + 20;}}/*** 用画笔在画布上画出所有的孔*/private void drawAllCircle(GraphicsContext paintBrush) {paintBrush.setStroke(Color.BLACK);for (int i = 0; i < this.sequence.length; i++) {drawCircle(paintBrush, this.sequence[i]);}}/*** 用画笔在画布上画出一个孔*/private void drawCircle(GraphicsContext paintBrush, int cityCode) {double x = this.cityPositionArr[cityCode][0];double y = this.cityPositionArr[cityCode][1];double radius = 2;// 圆的直径double diameter = radius * 2;paintBrush.strokeOval(x, y, diameter, diameter);}/*** 将原始的线转化成一条可以画出来的线*/private void drawLine(GraphicsContext paintBrush, int index) {int nextCityIndex = index + 1;nextCityIndex = nextCityIndex >= this.sequence.length ? 0 : nextCityIndex;
//        System.out.println(this.sequence[index]+">>"+this.sequence[nextCityIndex]);double startX = this.cityPositionArr[this.sequence[index]][0];double startY = this.cityPositionArr[this.sequence[index]][1];double endX = this.cityPositionArr[this.sequence[nextCityIndex]][0];double endY = this.cityPositionArr[this.sequence[nextCityIndex]][1];paintBrush.setStroke(Color.RED);paintBrush.strokeLine(startX, startY, endX, endY);}/*** 创建动画*/private void createAnimation(GraphicsContext paintBrush, double speed) {for (int i = 0; i < this.sequence.length; i++) {int finalI = i;KeyFrame keyFrame = new KeyFrame(Duration.seconds(finalI * speed), event -> drawLine(paintBrush, finalI));nowTimeline.getKeyFrames().add(keyFrame);}}/*** 读取数据** @return* @throws Exception*/public double[][] getDistanceMatrix() throws Exception {读取数据String data = read(new File("src/main/java/com/data/tsp/att48.txt"), "GBK");String[] cityDataArr = data.split("\n");//初始化数组//距离矩阵,可以直接获取任意两个编号城市的距离double[][] distanceMatrix = new double[cityDataArr.length][cityDataArr.length];this.cityPositionArr = new double[cityDataArr.length][2];for (int i = 0; i < cityDataArr.length; i++) {String[] city1Arr = cityDataArr[i].split(" ");this.cityPositionArr[i][0] = Double.valueOf(city1Arr[1]);this.cityPositionArr[i][1] = Double.valueOf(city1Arr[2]);int cityOne = Integer.valueOf(city1Arr[0]);for (int j = 0; j < i; j++) {String[] city2Arr = cityDataArr[j].split(" ");int cityTwo = Integer.valueOf(city2Arr[0]);if (cityOne == cityTwo) {distanceMatrix[cityOne - 1][cityTwo - 1] = 0;} else {distanceMatrix[cityOne - 1][cityTwo - 1] = getDistance(Double.valueOf(city1Arr[1]), Double.valueOf(city1Arr[2]), Double.valueOf(city2Arr[1]), Double.valueOf(city2Arr[2]));//对称赋值distanceMatrix[cityTwo - 1][cityOne - 1] = distanceMatrix[cityOne - 1][cityTwo - 1];}}}return distanceMatrix;}/*** 给定两个城市坐标,获取两个城市的直线距离** @param x1* @param y1* @param x2* @param y2* @return*/private double getDistance(double x1, double y1, double x2, double y2) {return Math.sqrt((Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2)) / 10);}private String read(File f, String charset) throws Exception {FileInputStream fstream = new FileInputStream(f);try {int fileSize = (int) f.length();if (fileSize > 1024 * 512) {throw new Exception("File too large to read! size=" + fileSize);}byte[] buffer = new byte[fileSize];fstream.read(buffer);return new String(buffer, charset);} finally {try {fstream.close();} catch (Exception e) {}}}
}

测试

未经过算法优化的序列

  因为csdn上传的图片的大小会被限制为5M,所以降了分辨率和帧率才能导出这个图,看起来有点卡 /(ㄒoㄒ)/~~


经过算法优化的序列

Tsp遍历路径可视化【javaFx实现--详细注释】相关推荐

  1. 蚁群算法解决TSP问题(2#JAVA代码+详细注释+对比动态规划【JAVA】)

    第一部分:原理 TSP10cities.txt 1 2066 2333 2 935 1304 3 1270 200 4 1389 700 5 984 2810 6 2253 478 7 949 302 ...

  2. 数学建模常用算法:启发式优化算法合辑(内含多种智能优化算法,使用java实现算法、详细注释、并进行结果可视化)

    一.启发式算法介绍   启发式算法(heuristic algorithm)是相对于最优化算法提出的.一个问题的最优算法求得该问题每个实例的最优解.启发式算法可以这样定义:一个基于直观或经验构造的算法 ...

  3. CNN经典网络模型(二):AlexNet简介及代码实现(PyTorch超详细注释版)

    目录 一.开发背景 二.网络结构 三.模型特点 四.代码实现 1. model.py 2. train.py 3. predict.py 4. spilit_data.py 五.参考内容 一.开发背景 ...

  4. createsamples.cpp中生成vec文件的实现及详细注释、图解——人脸识别的尝试系列(三)

    在我们开始训练我们的Haar分类器之前,首先要对样本进行处理. 人脸识别的尝试系列(一)中:http://blog.csdn.net/u011583927/article/details/446274 ...

  5. CNN经典网络模型(四):GoogLeNet简介及代码实现(PyTorch超详细注释版)

    目录 一.开发背景 二.网络结构 三.模型特点 四.代码实现 1. model.py 2. train.py 3. predict.py 4. spilit_data.py 五.参考内容 一.开发背景 ...

  6. 手写YOLOv3|代码详细注释

    手写YOLOv3|代码详细注释 一. 数据预处理 一. Yolov3网络 一. Train 一. Detection 源代码:https://github.com/eriklindernoren/Py ...

  7. 【详细注释】1058 选择题 (20 分)

    立志用最少的代码做最高效的表达 PAT乙级最优题解-->传送门 批改多选题是比较麻烦的事情,本题就请你写个程序帮助老师批改多选题,并且指出哪道题错的人最多. 输入格式: 输入在第一行给出两个正整 ...

  8. ASCII码表 0-255完整版 附详细注释

    信息在计算机上是用二进制表示的,这种表示法让人理解就很困难.因此计算机上都配有输入和输出设备,这些设备的主要目的就是,以一种人类可阅读的形式将信息在这些设备上显示出来供人阅读理解.为保证人类和设备,设 ...

  9. Hybrid A*路径规划器的代码注释

    项目主页 https://github.com/teddyluo/hybrid-a-star-annotation 参考文献有: DOLGOV D, THRUN S, MONTEMERLO M, et ...

最新文章

  1. python os方法-Python os.lchflags() 方法
  2. JS 中迭代数组的三种方法
  3. 在Windows 7中的Windows Media Player 12中快速预览歌曲
  4. android 创建文件夹_Android 动画小记
  5. 【Liunx】Linux 简介
  6. 如何学习3D建模的学习之路,学习这些成为高手吧
  7. 2018-10-20
  8. pyqt5示例_木辛老师的编程课堂:Python和Qt第一讲之初识PyQt5
  9. javascript基础知识系列:DOM学习
  10. Docker安装宝塔没想到竟然如此之简单~
  11. [Java] 蓝桥杯 BASIC-6 基础练习 杨辉三角形
  12. 高仿维信安卓(读博客)
  13. Python金融大数据分析——第11章 统计学(2)投资组合优化 笔记
  14. 在VirtualBox Linux 7u2 中安装Oracle RAC 12.2.0.1.0
  15. 知识图谱从入门到应用——知识图谱推理:基础知识
  16. Spring——DI
  17. 根据具体地址计算经纬度
  18. 爬虫 + 自动化利器 selenium 之自学成才篇(二)
  19. go中mgo操作数据库的一些示例
  20. 爬虫基础之HTTP基本原理

热门文章

  1. win7 装系统踩坑之无法进入到u盘启动或无法进到BIOS
  2. 实现Echarts的世界中国地图以及下钻功能
  3. 【WPS绘图】-用PPT画Pt(111)晶面图
  4. ERP系统-应收分析客户账龄
  5. mysql 增删改查
  6. 大型三甲HIS源码,EMR系统
  7. 模拟登陆获取脉脉好友信息
  8. C语言编程 可以不会英语 但必须要懂以下英语单词
  9. 修改金蝶kis服务器的文件路径,金蝶kis改服务器地址
  10. mysql外码内码定义_中文编码杂谈(转) - CodeAxe的个人页面 - OSCHINA - 中文开源技术交流社区...