贴上代码,输入文件路径请自行修改 import java.io.*; import java.util.*;public class FindPath { private static int min = Integer.MAX_VALUE; private static List<Node> minPath;
public static void main(String[] args) throws IOException { Scanner in = new Scanner(new FileInputStream("D:\\input.txt"));
Point start = readPoint(in); in.nextLine(); Point end = readPoint(in); in.nextLine();
int num = in.nextInt();
Point[] points = new Point[num]; for (int i = 0; i < num; i++) { in.nextLine(); points[i] = readPoint(in); }
in.close();
List<Node> left = new ArrayList<>(); Node[] nodes = new Node[num]; for (int i = 0; i < num; i++) { nodes[i] = new Node(String.valueOf(i)); nodes[i].distanceToEnd = end.distanceTo(points[i]); nodes[i].distanceFromStart = start.distanceTo(points[i]);
for (int j = i - 1; j >= 0; j--) { int distance = points[i].distanceTo(points[j]); nodes[i].neighbor.put(nodes[j], distance); nodes[j].neighbor.put(nodes[i], distance); }
写了一个例子,比较乱,凑合着看。。
输入文件的格式为
第一行两个整数,用空格隔开,分别表示起点的X和Y坐标
第二行相似,表示终点的坐标
第三行一个整数,表示中间需要走到的节点个数N
接下来N行,每行表示一个节点的坐标,并且按顺序每个节点的编号为0,1,2,...
以LZ的图为例的输入文件
4 0
4 4
3
0 1
1 3
3 2
import java.io.*;
import java.util.*;public class FindPath {
private static int min = Integer.MAX_VALUE;
private static List<Node> minPath;
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(new FileInputStream("D:\\input.txt"));
Point start = readPoint(in);
in.nextLine();
Point end = readPoint(in);
in.nextLine();
int num = in.nextInt();
Point[] points = new Point[num];
for (int i = 0; i < num; i++) {
in.nextLine();
points[i] = readPoint(in);
}
in.close();
List<Node> left = new ArrayList<>();
Node[] nodes = new Node[num];
for (int i = 0; i < num; i++) {
nodes[i] = new Node(String.valueOf(i));
nodes[i].distanceToEnd = end.distanceTo(points[i]);
nodes[i].distanceFromStart = start.distanceTo(points[i]);
for (int j = i - 1; j >= 0; j--) {
int distance = points[i].distanceTo(points[j]);
nodes[i].neighbor.put(nodes[j], distance);
nodes[j].neighbor.put(nodes[i], distance);
}
left.add(nodes[i]);
}
search(new Path(), left);
System.out.println("Min: " + min);
System.out.print("Start->");
for (Node node : minPath) {
System.out.print(node.name + "->");
}
System.out.println("End");
}
private static Point readPoint(Scanner in) {
int x = in.nextInt(), y = in.nextInt();
return new Point(x, y);
}
private static void search(Path path, List<Node> left) {
if (left.size() == 0) {
int distance = path.getTotalDistance();
if (distance < min) {
min = distance;
minPath = path.getPath();
}
} else {
for (int i = left.size(); i > 0; i--) {
Node node = left.remove(0);
path.add(node);
search(path, left);
left.add(node);
path.removeLast();
}
}
}
private static class Path {
List<Node> path;
int distance;
public Path() {
this.path = new ArrayList<>();
this.distance = 0;
}
public void add(Node node) {
if (path.size() > 0) {
Node last = this.path.get(this.path.size() - 1);
this.distance += last.neighbor.get(node);
}
this.path.add(node);
}
public void removeLast() {
Node node = this.path.remove(this.path.size() - 1);
if (path.size() > 0) {
Node last = this.path.get(this.path.size() - 1);
this.distance -= last.neighbor.get(node);
}
}
public int getTotalDistance() {
Node last = this.path.get(this.path.size() - 1);
Node first = this.path.get(0);
return distance + last.distanceToEnd + first.distanceFromStart;
}
public List<Node> getPath() {
List<Node> copy = new ArrayList<Node>(this.path.size());
for (Node node : this.path) {
copy.add(node);
}
return copy;
}
}
private static class Point {
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int distanceTo(Point point) {
return Math.abs(this.x - point.x) + Math.abs(this.y - point.y);
}
}
private static class Node {
String name;
Map<Node, Integer> neighbor;
int distanceToEnd, distanceFromStart;
public Node(String name) {
this.name = name;
this.neighbor = new HashMap<>();
}
}
}
1. Prim算法视频http://v.qq.com/boke/page/n/0/f/n0127zg3qzf.html
2. Kruskal算法http://v.qq.com/boke/page/s/0/5/s0127bo19g5.html
经粗略测试,暂且可以
试问英语算法思路
因为我接下来想要稍稍改进一下,输出显示 start->0->1->2->end 的具体走法
万分感谢您的帮助
解决了困扰多日的问题
因为每个节点都要访问且最多访问一次(重复访问一个节点不可能是最优解),所以可以用一个List来记录还没访问到的节点,避免重复访问同一个节点深搜的思路大概是,在某个节点上,首先判断现在是不是所有节点都访问到了(59行,left.size() == 0),如果是,那么计算总路程,并且和当前最短路径对比,如果还有节点没访问过(left这个List里还有节点),那么依次访问没访问到的节点。如果你要输出坐标具体路径,起点和终点分别是start和end(都是我自己写的Point类,见112行),中间的节点坐标通过points[n]获取,n为节点编号(就是0,1,2,..这些)