贪心算法解决TSP问题java

111 阅读1分钟

记录自己的一个作业

解决思路:

  1. 用Vertex表示每个城市结点,Edge储存边的两个结点和权值,城市图用二维坐标表示,权值用其欧式距离表示
  2. 循环生成所有的边并加入ArrayList中储存起来,通过Edge实现Comparable接口实现边长从低到高排序
  3. 通过不断循环这个List取出当前路径最后结点能走的最短边生成路径

代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TSP {
    Vertex[] vertices;

    public List<Edge> getData() {
        ArrayList<Edge> list = new ArrayList<>();
        vertices = new Vertex[5];
        vertices[0] = new Vertex(1, 0, 'a');
        vertices[1] = new Vertex(4, 0, 'b');
        vertices[2] = new Vertex(2, 2, 'c');
        vertices[3] = new Vertex(1, 3, 'd');
        vertices[4] = new Vertex(3, 4, 'e');
        for (int i = 0; i < vertices.length; i++) {
            for (int j = i + 1; j < vertices.length; j++) {
                list.add(new Edge(vertices[i].value, vertices[j].value, weight(vertices[i], vertices[j])));
            }
        }
        return list;
    }

    public static double weight(Vertex a, Vertex b) {
        return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
    }

    // 采用贪心算法
    public String  getRoute(List<Edge> list) {
        StringBuffer route = new StringBuffer();
        Edge e = list.get(0);
        route.append(e.start);
        route.append(e.end);
        Double distance = e.getWeight();
        list.remove(e);
        while (route.length() != vertices.length) {
            for (Edge edge : list) {
                if (route.charAt(route.length() - 1) == edge.start && route.indexOf(edge.end + "") == -1) {
                    route.append(edge.end);
                    distance += edge.getWeight();
                    list.remove(edge);
                    break;
                } else if (route.charAt(route.length() - 1) == edge.end && route.indexOf(edge.start + "") == -1) {
                    route.append(edge.start);
                    distance += edge.getWeight();
                    list.remove(edge);
                    break;
                }
            }
        }
        distance += weight(vertices[getPos(route.charAt(0))], vertices[getPos(route.charAt(route.length() - 1))]);
        route.append(route.charAt(0));

        System.out.println("距离为" + distance);
        return route.toString();
    }

    public static int getPos(char v) {
        return v - 97;
    }

    public static void main(String[] args) {
        TSP t = new TSP();
        List<Edge> d = t.getData();
        Collections.sort(d);
        for (Edge edge : d) {
            System.out.print(edge.getLine());
            System.out.println(edge.getWeight());
        }
        System.out.println("路径为" + t.getRoute(d));


    }
}

class Edge implements Comparable<Edge> {
    char start;
    char end;
    private double weight;

    public Edge(char start, char end, double weight) {
        this.start = start;
        this.end = end;
        this.weight = weight;
    }

    public String getLine() {
        return start + "--" + end;
    }

    public double getWeight() {
        return weight;
    }

    @Override
    public int compareTo(Edge o) {
        return new Double(this.weight).compareTo(new Double(o.weight));
    }
}

class Vertex{
    int x;
    int y;
    char value; // 编号

    public Vertex(int x, int y, char value) {
        this.x = x;
        this.y = y;
        this.value = value;
    }
}

写的不是很好只是实现了功能,并没有做太多优化