package day7; /** * Write by Bloomberg * 0500051545 * 0128054984 * 0029041651 * 6874014654 * 3213013584 * 1651050001 * 6549010406 * 1546040500 * 5198010511 * 6545000891 */ import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; public class Dijkstra { private int[][] map; // 地图结构保存 private int[][] edges; // 邻接矩阵 private int[] prev; // 前驱节点标号 private boolean[] s; // S集合中存放到起点已经算出最短路径的点 private int[] dist; // dist[i]表示起点到第i个节点的最短路径 private int PoiNum; // 点的个数 private Map<Integer, Poi> indexPoiMap; // 标号和点的对应关系 private Map<Poi, Integer> PoiIndexMap; // 点和标号的对应关系 private int v0; // 起点标号 private Poi startPoi; // 起点 private Poi endPoi; // 终点 private Map<Poi, Poi> PoiPoiMap; // 保存点和权重的映射关系 private List<Poi> allPois; // 保存所有点 private int maxX; // x坐标的最大值 private int maxY; // y坐标的最大值 public static void main(String[] args) throws IOException { String filename = "C:\\Users\\Administrator\\Desktop\\test.txt"; ArrayList out = tes01.out(filename); ArrayList<char[]> chars = format1(out); int[][] map = format2(chars); // for (int i = 0; i < map.length; i++) { // for (int j = 0; j < map.length; j++) { // System.out.print(map[i][j] + " "); // } // System.out.println(); // } Poi startPoi = new Poi(0, 0); // 起点 Poi endPoi = new Poi(9, 9); // 终点 // int[][] map = DijkstraReader(filename); // System.out.println(map); Dijkstra dijkstra = new Dijkstra(map, startPoi, endPoi); int sum = dijkstra.printShortestPath(map); sum = sum + map[0][0]; System.out.println(sum); // int q=0; // for (int i = 0; i < path.size(); i++) { System.out.print(path.get(i)+""); // q+=path.get(i); // } // System.out.println(q); // Iterator<Integer> iterator = path.iterator(); // while (iterator.hasNext()){ // System.out.println(iterator.next());} } public static int[][] format2(ArrayList<char[]> out1) { int[][] formap = new int[out1.size()][out1.size()]; for (int i = 0; i < out1.size(); i++) { for (int j = 0; j < out1.size(); j++) { char[] charsouti = out1.get(i); String s = String.valueOf(charsouti[j]); int parseInt = Integer.parseInt(s); formap[i][j] = parseInt; } } return formap; } public static ArrayList<char[]> format1(ArrayList<String> out) { ArrayList<char[]> charList = new ArrayList<>(); for (int i = 0; i < out.size(); i++) { char[] chars = out.get(i).toCharArray(); charList.add(chars); } return charList; } public static ArrayList out(String filename) throws IOException { try { FileInputStream fin = new FileInputStream(filename); InputStreamReader reader = new InputStreamReader(fin); BufferedReader buffReader = new BufferedReader(reader); String m; StringBuilder sb = new StringBuilder(); ArrayList<String> arrayList = new ArrayList<>(); int[][] formtemp = null; int[] filecon = null; while ((m = buffReader.readLine()) != null) { arrayList.add(m); } return arrayList; } catch (IOException e) { e.printStackTrace(); } return null; } // public static int[][] DijkstraReader(String filename) { // // int[] filecon = null; // String m = ""; // int[][] formtemp = null; // BufferedReader file = null; // try { // file = new BufferedReader(new FileReader(filename)); // int x = file.readLine().length(); // while ((m = file.readLine()) != null) { // // if (!m.equals("")) { // int j = 0; // for (int i = 0; i <x; i++) { // while ((m.substring(0, 1)) != null) { // String s0 = m.substring(0, 1); // int anInt = Integer.parseInt(s0); // String s1 = new StringBuffer(m).delete(0, 1).toString(); // m = s1; // filecon[j++] = anInt; // } // int j1 = 0; // formtemp[i][j1++] = filecon[j1++]; // } // } // } // file.close(); // } catch (IOException e) { // e.printStackTrace(); // } // // return formtemp; // } public Dijkstra(int map[][], Poi startPoi, Poi endPoi) { this.maxX = map.length; this.maxY = map[0].length; this.PoiNum = maxX * maxY; this.map = map; this.startPoi = startPoi; this.endPoi = endPoi; init(); dijkstra(); } /** * 打印指定起点到终点的最短路径 */ public int printShortestPath(int[][] map) { int sum = printDijkstra(PoiIndexMap.get(endPoi), map); return sum; } /** * 初始化dijkstra */ private void init() { // 初始化所有变量 edges = new int[PoiNum][PoiNum]; prev = new int[PoiNum]; s = new boolean[PoiNum]; dist = new int[PoiNum]; indexPoiMap = new HashMap<>(); PoiIndexMap = new HashMap<>(); PoiPoiMap = new HashMap<>(); allPois = new ArrayList<>(); // 将map二维数组中的所有点转换成自己的结构 int count = 0; for (int x = 0; x < maxX; ++x) { for (int y = 0; y < maxY; ++y) { indexPoiMap.put(count, new Poi(x, y)); PoiIndexMap.put(new Poi(x, y), count); count++; allPois.add(new Poi(x, y)); PoiPoiMap.put(new Poi(x, y), new Poi(x, y, map[x][y])); } } // 初始化邻接矩阵 for (int i = 0; i < PoiNum; ++i) { for (int j = 0; j < PoiNum; ++j) { if (i == j) { edges[i][j] = 0; } else { edges[i][j] = 9999; } } } // 根据map上的权重初始化edges,当然这种算法是没有单独加起点的权重的 for (Poi Poi : allPois) { for (Poi aroPoi : getaroPois(Poi)) { edges[PoiIndexMap.get(Poi)][PoiIndexMap.get(aroPoi)] = aroPoi.getValue(); } } v0 = PoiIndexMap.get(startPoi); for (int i = 0; i < PoiNum; ++i) { dist[i] = edges[v0][i]; if (dist[i] == 9999) { // 如果从0点(起点)到i点最短路径是9999,即不可达 // 则i节点的前驱节点不存在 prev[i] = -1; } else { // 初始化i节点的前驱节点为起点,因为这个时候有最短路径的都是与起点直接相连的点 prev[i] = v0; } } dist[v0] = 0; s[v0] = true; } /** * dijkstra核心算法 */ private void dijkstra() { for (int i = 1; i < PoiNum; ++i) { // 此时有PoiNum - 1个点在U集合中,需要循环PoiNum - 1次 int minDist = 9999; int u = v0; for (int j = 1; j < PoiNum; ++j) { // 在U集合中,找到到起点最短距离的点 if (!s[j] && dist[j] < minDist) { // 不在S集合,就是在U集合 u = j; minDist = dist[j]; } } s[u] = true; // 将这个点放入S集合 for (int j = 1; j < PoiNum; ++j) { // 以当前刚从U集合放入S集合的点u为基础,循环其可以到达的点 if (!s[j] && edges[u][j] < 9999) { if (dist[u] + edges[u][j] < dist[j]) { dist[j] = dist[u] + edges[u][j]; prev[j] = u; } } } } } // ArrayList<Integer> tep = new ArrayList<Integer>(); int sum = 0; private int printDijkstra(int endPoiIndex, int[][] map) { if (endPoiIndex == v0) { System.out.println(indexPoiMap.get(v0) + ","); // return null; } else { printDijkstra(prev[endPoiIndex], map); System.out.println(indexPoiMap.get(endPoiIndex) + "," + map[indexPoiMap.get(endPoiIndex).getX()][indexPoiMap.get(endPoiIndex).getY()]); sum += map[indexPoiMap.get(endPoiIndex).getX()][indexPoiMap.get(endPoiIndex).getY()]; // tep.add(s); } return sum; } private List<Poi> getaroPois(Poi Poi) { List<Poi> aroPois = new ArrayList<>(); int x = Poi.getX(); int y = Poi.getY(); aroPois.add(PoiPoiMap.get(new Poi(x - 1, y))); aroPois.add(PoiPoiMap.get(new Poi(x, y + 1))); aroPois.add(PoiPoiMap.get(new Poi(x + 1, y))); aroPois.add(PoiPoiMap.get(new Poi(x, y - 1))); aroPois.removeAll(Collections.singleton(null)); // 剔除不在地图范围内的null点 return aroPois; } public static class Poi { private int x; private int y; private int value; public Poi(int x, int y) { this.x = x; this.y = y; } public Poi(int x, int y, int value) { this.x = x; this.y = y; this.value = value; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } @Override public String toString() { return "{" + "x=" + x + ", y=" + y + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Poi Poi = (Poi) o; if (x != Poi.x) return false; return y == Poi.y; } @Override public int hashCode() { int result = x; result = 31 * result + y; return result; } } }
图论 :二维矩阵最小路径
最新推荐文章于 2022-12-20 17:58:35 发布