Cinco minutos para comprender el algoritmo de búsqueda de caminos más corto: Dijkstra Dijkstra

Algoritmo de búsqueda de ruta más corta

Los algoritmos de búsqueda de rutas son muy comunes en la vida diaria. Este artículo implementa un algoritmo de búsqueda de ruta más corta para gráficos.
Este algoritmo es más común en juegos y navegación de mapas en interiores.

lograr

Ejemplo: entre varios nodos, el segmento de línea conectado tiene una longitud fija y la longitud es definitivamente el costo de paso. Encuentra el camino con el menor coste. La estructura gráfica es

5米
2米
4米
5米
2米
2米
2米
8米
起点A
B
C
F
终点D
Ideas:

Se puede ver que los costos de A>B>D y A>C>D son los mismos, y la suma de los lados es igual a 10. El costo de ruta de A>C>B es igual a 9, que es el camino más corto.

  1. Guarde los nodos secundarios de cada nodo, incluida la ruta, como una tabla hash.
  2. Verifique recursivamente cada nodo relevante para ver si se puede alcanzar el punto final, registre el costo, la ruta y guarde la ruta con el costo más bajo en comparación con la última ruta exitosa hasta el punto final.
  3. Siga actualizando hasta recorrer cada nodo.
  4. El resultado final es el camino más corto deseado.

Complejidad: el peor de los casos debería ser O((n-1) 2 )

Encuentra todos los caminos entre dos puntos cualesquiera sin referencia a los pesos.
//csharp版代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace ConsoleApp1test
{
    
    
    class Program
    {
    
       //创建图数据
        static Hashtable myGraph = new Hashtable();
        static void Main(string[] args) 
        {
    
    
            //A节点及其信息与关系
            myGraph["A"] = new Hashtable();
            (myGraph["A"] as Hashtable)["B"] = 5;
            (myGraph["A"] as Hashtable)["C"] = 2;
            (myGraph["A"] as Hashtable)["F"] = 2;
            //B节点
            myGraph["B"] = new Hashtable();
            (myGraph["B"] as Hashtable)["D"] = 5;
            (myGraph["B"] as Hashtable)["F"] = 5;
            //C
            myGraph["C"] = new Hashtable();
            (myGraph["C"] as Hashtable)["B"] = 2;
            (myGraph["C"] as Hashtable)["D"] = 8;
            //D
            myGraph["D"] = new Hashtable();
            //f
            myGraph["F"] = new Hashtable();
            //递归监测
            GetPath(myGraph["A"] as Hashtable, "A", "D");
           
            Console.ReadKey();
        }

        //创建用于存储代价的变量
        static int cost = 0;
        //创建用于记录路径的数据表
        static Hashtable rote = new Hashtable();
        static List<string> rotearray = new List<string>();
        public static void GetPath(Hashtable targetNode, string startPoint, string endPoint)
        {
    
    
            //记录当前节点
            rotearray.Add(startPoint);
            Console.WriteLine("当前节点:"+ startPoint);
            string st = "";
            foreach (string name in rotearray)
            {
    
    
                st += name + ">";
            }
            Console.WriteLine("当前结构:"+st);
            //当前节点是否是根节点
            if (startPoint == endPoint)
            {
    
    
                //已经到达终点  //输出当前分支的每个节点
                string s = "";
                foreach (string name in rotearray)
                {
    
    
                    s += name + ">";
                }
                Console.WriteLine("到达终点,路径:"+s);
                Console.WriteLine("=================");
            } else {
    
    
                //未到达指定节点 遍历每个节点下相关联的子节点
                foreach (string connected_node_name in targetNode.Keys)//在第一次输入时,不应该遍历所有的值
                {
    
    
                    GetPath(myGraph[connected_node_name] as Hashtable, connected_node_name, endPoint);
                }
            }

            //删除当前节点回 到上层
            if (rotearray.Count > 0)
                rotearray.RemoveAt(rotearray.Count - 1);
        }
    }
}

resultado:

当前节点:A
当前结构:A>
当前节点:C
当前结构:A>C>
当前节点:D
当前结构:A>C>D>
到达终点,路径:A>C>D>
=================
当前节点:B
当前结构:A>C>B>
当前节点:F
当前结构:A>C>B>F>
当前节点:D
当前结构:A>C>B>D>
到达终点,路径:A>C>B>D>
=================
当前节点:F
当前结构:A>F>
当前节点:B
当前结构:A>B>
当前节点:F
当前结构:A>B>F>
当前节点:D
当前结构:A>B>D>
到达终点,路径:A>B>D>
=================

Encuentre el camino mínimo (más corto) entre los dos puntos especificados

Este fragmento de código se usa para encontrar la ruta más corta en un gráfico ponderado, agregando antibucle y se puede usar en gráficos dirigidos y no dirigidos.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace ConsoleApp1test
{
    
    
    class Program
    {
    
       
    	//创建图数据
        static Hashtable myGraph = new Hashtable();
        static void Main(string[] args) 
        {
    
    
            //A节点及其信息与关系
            myGraph["A"] = new Hashtable();
            (myGraph["A"] as Hashtable)["B"] = 5;
            (myGraph["A"] as Hashtable)["C"] = 2;
            (myGraph["A"] as Hashtable)["F"] = 2;
            //B节点
            myGraph["B"] = new Hashtable();
            (myGraph["B"] as Hashtable)["D"] = 5;
            (myGraph["B"] as Hashtable)["F"] = 5;
            //C
            myGraph["C"] = new Hashtable();
            (myGraph["C"] as Hashtable)["B"] = 2;
            (myGraph["C"] as Hashtable)["D"] = 8;
            //D
            myGraph["D"] = new Hashtable();
            //f
            myGraph["F"] = new Hashtable();
            (myGraph["F"] as Hashtable)["B"] = 2;
            //递归监测
            GetPath(myGraph["A"] as Hashtable, "A", "D");
            Console.WriteLine("最短路径:" + shortestPath + " 代价:" + shortestCost + "米");
            Console.ReadKey();
        }

        //创建用于存储代价\记录路径的数据表
        static List<string> pathList = new List<string>();
        static List<int> pathCostList = new List<int>();
        static int shortestCost = 100000;
        static string shortestPath = "";

        public static void GetPath(Hashtable targetNode, string startPoint, string endPoint)
        {
    
    
            //记录当前节点
            pathList.Add(startPoint);
            Console.WriteLine("当前节点:"+ startPoint);
            string allPath = "";
            for(int i=0; i < pathList.Count; i++)
            {
    
    
                allPath += pathList[i];
                allPath += (i == (pathList.Count - 1)) ? "" : ">";
            }
            Console.WriteLine("当前结构:" + allPath);

            //当前节点是否是根节点
            if (startPoint == endPoint)
            {
    
    
                //已经到达终点  //输出当前分支的每个节点
                Console.WriteLine("到达终点,路径:"+ allPath);

                //计算所有的权值
                int pathCost_total = 0;
                foreach (int pathCost in pathCostList)
                {
    
    
                    pathCost_total += pathCost;
                }
                Console.WriteLine("代价:" + pathCost_total.ToString() + "米");

                //更新最短路径信息
                if (pathCost_total < shortestCost) {
    
    
                    shortestCost = pathCost_total;
                    shortestPath = allPath;
                }
                Console.WriteLine("==========害羞而淫荡的分割线==========");
            } else {
    
    
                //未到达指定节点 遍历每个节点下相关联的子节点
                foreach (string connected_node_name in targetNode.Keys)
                {
    
    
                    //如果,路径中已存在节点,就不走了。 避免循环。
                    if (!pathList.Contains(connected_node_name)) {
    
    
                    //记录路径权值
                    pathCostList.Add((int)targetNode[connected_node_name]);
                    GetPath(myGraph[connected_node_name] as Hashtable, connected_node_name, endPoint);
                    //记录路径权值
                    if (pathCostList.Count > 0)
                        pathCostList.RemoveAt(pathCostList.Count - 1);
                    }
                }
            }

            //删除当前节点回 到上层
            if (pathList.Count > 0)
                pathList.RemoveAt(pathList.Count - 1);
        }
    }
}


resultado:

当前节点:A
当前结构:A
当前节点:C
当前结构:A>C
当前节点:D
当前结构:A>C>D
到达终点,路径:A>C>D
代价:10==========害羞而淫荡的分割线==========
当前节点:B
当前结构:A>C>B
当前节点:F
当前结构:A>C>B>F
当前节点:D
当前结构:A>C>B>D
到达终点,路径:A>C>B>D
代价:9==========害羞而淫荡的分割线==========
当前节点:F
当前结构:A>F
当前节点:B
当前结构:A>F>B
当前节点:D
当前结构:A>F>B>D
到达终点,路径:A>F>B>D
代价:9==========害羞而淫荡的分割线==========
当前节点:B
当前结构:A>B
当前节点:F
当前结构:A>B>F
当前节点:D
当前结构:A>B>D
到达终点,路径:A>B>D
代价:10==========害羞而淫荡的分割线==========
最短路径:A>C>B>D 代价:9

En un gráfico ponderado, en teoría, los pesos se pueden convertir en nodos iguales y el algoritmo de nodo más corto también se puede utilizar para encontrar la ruta más corta.

Supongo que te gusta

Origin blog.csdn.net/lengyoumo/article/details/132518139
Recomendado
Clasificación