Solución 2 de la ruta más corta de Graph

Solución 2 de la ruta más corta de Graph

El algoritmo de Dijkstra adopta una estrategia codiciosa. Declara una matriz dis para almacenar la distancia más corta desde el punto de origen a cada vértice y un conjunto de vértices que han encontrado la ruta más corta: T.
Inicialmente, se asigna el peso de la ruta del origen s Es 0 (dis [s] = 0). Si hay una arista (s, m) que se puede alcanzar directamente para el vértice s, establezca dis [m] en w (s, m)
y establezca la longitud de la ruta de todos los demás vértices (que s no puede alcanzar directamente) en infinito. Inicialmente, el conjunto T solo tiene vértices s.
Luego, seleccione el valor mínimo de la matriz dis, luego el valor es la ruta más corta desde el punto de origen s hasta el vértice correspondiente al valor, y agregue este punto a T, OK, en este momento se completa un vértice,
y luego necesitamos mirar el nuevo Si los vértices agregados pueden alcanzar otros vértices y ver si la longitud de la ruta a través de los vértices a otros puntos es más corta que la del punto de origen directamente.
Si es así, reemplace el valor de estos vértices en dis.
Luego, encuentre el valor mínimo de dis y repita la acción anterior hasta que T contenga todos los vértices del gráfico.

package org.lanqiao.algo.elementary._12_graph.bfs;

import java.util.HashSet;
import java.util.Set;


public class 图的最短路问题_Dijkstra2 {
    
    
  public static void main(String[] args) {
    
    
    int s = 1;
    int[] shortestPath = shortestPath(s);
    // Util.print(shortestPath);
    // Util.print(prev);

    // for (int i = 0; i < shortestPath.length; i++) {
    
    
    //   System.out.print((char) ('A' + s) + "->" + (char) ('A' + i) + ":" + shortestPath[i] + ";\t");
    // }
    // System.out.println();

    for (int i = 0; i < prev.length; i++) {
    
    
      System.out.println((char) ('A' + s) + "到" + (char) ('A' + i) + "的路径");
      System.out.print((char) ('A' + i) + "<-");
      int j = prev[i];
      while (j != s) {
    
    
        System.out.print((char) ('A' + j) + "<-");
        j = prev[j];
      }
      System.out.print((char) ('A' + j));
      System.out.println(":" + shortestPath[i]);
    }
  }

  static int[] prev;

  /**
   * 求起点到各顶点的最短距离
   * @param s 起点
   * @return
   */
  private static int[] shortestPath(int s) {
    
    
    //顶点个数
    int n = graph.length;
    //记录每个点的前驱
    prev = new int[n];
    //一定要初始化,源点的前驱是自身
    prev[s] = s;
    //记录s到各顶点的最短距离
    int[] d = new int[n];
    d[s] = 0;//自己到自己的距离为0
    //记录已经找到最短距离的顶点
    Set<Integer> T = new HashSet<>();
    T.add(s);

    /*-第一步:直接可达的顶点,用距离来初始化d,d[s]=0,可直达的把距离记录下来作为待定值-*/
    for (int i = 0; i < n; i++) {
    
    
      if (i != s && graph[s][i] == 0) d[i] = Integer.MAX_VALUE;//不可直达的顶点,先以最大整数作为待定值
      if (i != s && graph[s][i] > 0) {
    
    
        d[i] = graph[s][i]; // 可直达的顶点,以直达距离作为待定值
        prev[i] = s;  // 可直达的顶点,其前驱是源点
      }
    }
    // Util.print(d);

    while (T.size() < n) {
    
    
    /*-第二步:从待定的距离表中找到最小值,这个值可以作为确定值,为什么?-*/
      //找d中不在T中的最小的
      int min = minIndex(d, T);
      T.add(min);
      if (T.size() == n) break;
    /*-第三步,看这个新确定的顶点的出度,看看从源点出发是经过这个顶点到其邻居近还是直达更近,如果更近就要更新-*/
      //扫描index的邻居
      for (int neighbor = 0; neighbor < n; neighbor++) {
    
    
        int cost = graph[min][neighbor];
        //更新
        if (cost > 0 && d[neighbor] > d[min] + cost) {
    
    
          d[neighbor] = d[min] + cost;
          prev[neighbor] = min; // 更新最短路后,要更新i这个点的前驱
        }
      }
    }
    return d;
  }

  /**
   * 从未确定的点里面找一个最小的
   * @param d
   * @param t 已确定了最短距离的顶点集
   * @return
   */
  private static int minIndex(int[] d, Set<Integer> t) {
    
    
    int index = -1;
    int min = Integer.MAX_VALUE;
    for (int i = 0; i < d.length; i++) {
    
    
      if (!t.contains(i) && d[i] < min) {
    
    
        min = d[i];
        index = i;
      }
    }
    return index;
  }

  static int[][] graph = {
    
    
      {
    
    0, 2, 5, 0, 0, 0, 0},
      {
    
    2, 0, 4, 6, 10, 0, 0},
      {
    
    5, 4, 0, 2, 0, 0, 0},
      {
    
    0, 6, 2, 0, 0, 1, 0},
      {
    
    0, 10, 0, 0, 0, 3, 5},
      {
    
    0, 0, 0, 1, 3, 0, 9},
      {
    
    0, 0, 0, 0, 5, 9, 0}
  };
}

Supongo que te gusta

Origin blog.csdn.net/weixin_45952706/article/details/109252952
Recomendado
Clasificación