人工智能 -- 模拟退火算法解决TSP问题(JAVA版)

计算由广州市出发走遍省内所有市的最短距离。

模拟退火算法:由两规则三函数组成。

两规则指:外层循环结束规则、内层循环结束规则。

三函数指:温度更新函数(控制温度的变化)、状态产生函数(用于产生邻结点)、状态接收函数(用于判断邻结点是否应该被接受)

本代码中退火算法介绍:

        外层循环结束规则为:温度小于某个指定的最低温度

        内层循环结束规则为:温度步长小于指定值,即每一个温度执行的状态选择次数

        状态产生函数为:bulider_neighbor(Node node),根据传入的结点,返回该结点的邻结点ArrayList集合,然后在该集合中随机选取一个结点neighbor,作为新的结点

        状态接收函数:接受条件为 neighbor的距离代价value 小于 当前结点(cur_node)的距离代价value或者根据e^-(neighbor.value-cur_node.value)/T (T指当前温度值 Temperature) 计算出一个概率值 P ,若P大于Random[0,1]之间的数,则接受,将新结点neighbor作为当前节点。若不满足上述两个条件,则拒绝接受。

        温度更新函数:此处偷懒,选择最简单的Temperature=Temperatrue*a;a的值为小于1的小数即可,保证Temperature的值下降。

package com.AI.Experiment4;

import java.util.ArrayList;
import java.util.Random;

/**
 * 模拟退火算法,解决TSP(旅行商)问题
 */

class Node {
    public int[] sol;  //存放路径
    public int value;  //存放该路径的距离代价

    public Node(int num){
        sol=new int[num];
        value=Integer.MAX_VALUE;
    }
}

public class SA {
    private int[][] Dist;   //距离矩阵
    private float Temperature;//初始温度
    private int City_num;   //城市数目
    private Node cur_node;  //初始化结点
    private Node best_neighbor; //最优邻结点
    private float a;        //降温系数

    /**
     * 传入初始化参数:
     *      1.距离矩阵
     *      2.初始温度
     * @param dist
     * @param temperature
     */
    public SA(int[][] dist, int temperature,float a) {
        Dist = dist;
        Temperature = temperature;
        this.a=a;
        City_num=dist.length;

    }

    /**
     * 将node2的内容复制到node1中
     * @param node1
     * @param node2
     */
    public void CopyNode(Node node1,Node node2){
        for(int i=0;i0.005){
            int step=0; //温度步长,内层循环,每一个温度执行200次计算
            while(step<1000){
                //随机获取当前结点的邻结点
                ArrayList neighbors = builder_neighbors(cur_node);//获取当前结点的邻居结点的集合
                int index= random.nextInt(neighbors.size());   //随机邻结点在集合中的下标

                Node neighbor=neighbors.get(index); //获取随机邻结点

                //判断随机邻结点的距离代价和当前结点的距离代价
                if(neighbor.valuerandom.nextDouble()){
                        CopyNode(cur_node,neighbor);
                    }
                }

                step++;
            }

            Temperature=Temperature*a;
        }

        return best_neighbor;
    }

    /**
     * 生成传入结点的邻结点集合
     * @param node
     * @return
     */
    public ArrayList builder_neighbors(Node node){
        ArrayList neighbors=new ArrayList<>();
        Node neighbor;//临时变量存放邻居结点
        int temp;   //临时变量存放城市编号
        for(int i=1;i

*注:广东省各市距离矩阵为21*21 ,数据量相对较大,若想得到最优解,需要提高初始温度或温度步长

人工智能 -- 模拟退火算法解决TSP问题(JAVA版)_第1张图片

         此解不一定正确,若要得到正确答案,可以多次运行记录下最低解。若计算机性能允许可以将初始温度和温度步长大幅度提高,保证每次都能输出最优解。(本人电脑辣鸡...)

广东省各市间距离(矩阵):

        https://blog.csdn.net/weixin_53068616/article/details/121049943?spm=1001.2014.3001.5501https://blog.csdn.net/weixin_53068616/article/details/121049943?spm=1001.2014.3001.5501icon-default.png?t=L9C2https://blog.csdn.net/weixin_53068616/article/details/121049943?spm=1001.2014.3001.5501

若算法有不足或对算法有不理解的地方,欢迎评论!

你可能感兴趣的:(人工智能,模拟退火算法,java)