Consideremos el siguiente ejemplo de implementación del algoritmo de Dijkstra para encontrar la ruta más corta utilizando el montón binario.
import java.util. *;
La clase estática pública Vertex implementa comparable {
Nombre de cadena final público;
public int dist = Integer.MAX_VALUE; // MAX_VALUE se supone que es infinito
Vértice público anterior = nulo;
public public Map neighbours = new HashMap ();
- ¿Cómo describirías el algoritmo de Quora usando una ecuación?
- Es un método de retroceso para imprimir permutaciones de cadena. No entiendo de qué manera se produce el flujo de control, como después de encontrar el intercambio, el intercambio se llama luego permutar y luego nuevamente. ¿Esto no se me viene a la cabeza?
- ¿Cuál es el problema de partición y cómo lo resolvemos?
- ¿Qué es un algoritmo eficiente para encontrar un circuito euleriano en un gráfico no dirigido?
- Cómo encontrar los cambios mínimos necesarios para convertir una cuerda en un palíndromo
Vértice público (nombre de cadena)
{
this.name = nombre;
}
privado vacío printPath ()
{
if (this == this.previous)
{
System.out.printf (“% s”, this.name);
}
si no (this.previous == null)
{
System.out.printf (“% s (no alcanzado)”, this.name);
}
más
{
this.previous.printPath ();
System.out.printf (“->% s (% d)”, this.name, this.dist);
}
}
public int compareTo (otro vértice)
{
if (dist == other.dist)
return name.compareTo (otro.nombre);
return Integer.compare (dist, other.dist);
}
@Override public String toString ()
{
return “(” + nombre + “,” + dist + “)”;
}
}
/ ** Crea un gráfico a partir de un conjunto de aristas * /
Gráfico público (Bordes [] bordes) {
graph = new HashMap (edge.length);
// una pasada para encontrar todos los vértices
para (Borde e: bordes) {
if (! graph.containsKey (e.v1)) graph.put (e.v1, nuevo Vertex (e.v1));
if (! graph.containsKey (e.v2)) graph.put (e.v2, nuevo Vertex (e.v2));
}
// otro pase para establecer vértices vecinos
para (Borde e: bordes) {
graph.get (e.v1) .neighbours.put (graph.get (e.v2), e.dist);
//graph.get(e.v2).neighbours.put(graph.get(e.v1), e.dist); // también haga esto para un gráfico no dirigido
}
}
/ ** Ejecuta dijkstra utilizando un vértice de origen especificado * /
public void dijkstra (String startName) {
if (! graph.containsKey (startName)) {
System.err.printf (“El gráfico no contiene el vértice de inicio \”% s \ “\ n”, startName);
regreso;
}
Fuente de vértice final = graph.get (startName);
NavigableSet q = nuevo TreeSet ();
// configurar vértices
para (Vértice v: graph.values ()) {
v.previous = v == fuente? fuente: nulo;
v.dist = v == fuente? 0: Integer.MAX_VALUE;
q.add (v);
}
dijkstra (q);
}
/ * Implementación del algoritmo de dijkstra utilizando un montón binario. * /
dijkstra privado vacío (NavigableSet final q) {
Vértice u, v;
while (! q.isEmpty ()) {
u = q.pollFirst (); // vértice con la distancia más corta (la primera iteración devolverá la fuente)
if (u.dist == Integer.MAX_VALUE) descanso; // podemos ignorar u (y cualquier otro vértice restante) ya que son inalcanzables
// mira las distancias a cada vecino
para (Map.Entry a: u.neighbours.entrySet ()) {
v = a.getKey (); // el vecino en esta iteración
final int alternateDist = u.dist + a.getValue ();
if (alternateDist <v.dist) {// ruta más corta al vecino encontrada
q.remove (v);
v.dist = alternateDist;
v.previous = u;
q.add (v);
}
}
}
}
/ ** Imprime una ruta desde el origen hasta el vértice especificado * /
public void printPath (String endName) {
if (! graph.containsKey (endName)) {
System.err.printf (“El gráfico no contiene el vértice final \”% s \ “\ n”, endName);
regreso;
}
graph.get (endName) .printPath ();
System.out.println ();
}
/ ** Imprime la ruta desde el origen a cada vértice (no se garantiza el orden de salida) * /
public void printAllPaths () {
para (Vértice v: graph.values ()) {
v.printPath ();
System.out.println ();
}
}
}
clase Graph {
gráfico de mapa final privado ; // mapeo de nombres de vértices a objetos Vertex, construidos a partir de un conjunto de bordes
/ * Un borde del gráfico (solo utilizado por el constructor de gráficos) * /
clase estática pública Edge {
Cadena pública final v1, v2;
public final int dist;
Public Edge (String v1, String v2, int dist) {
this.v1 = v1;
this.v2 = v2;
this.dist = dist;
}
}
clase pública Dijkstra {
Privado estático final Graph.Edge [] GRAPH = {
nuevo Graph.Edge (“a”, “b”, 8),
nuevo Graph.Edge (“a”, “c”, 2),
nuevo Graph.Edge (“a”, “d”, 5),
nuevo Graph.Edge (“b”, “d”, 2),
nuevo Graph.Edge (“b”, “f”, 13),
nuevo Graph.Edge (“c”, “d”, 2),
nuevo Graph.Edge (“c”, “e”, 5),
nuevo Graph.Edge (“d”, “e”, 1),
nuevo Graph.Edge (“d”, “g”, 3),
nuevo Graph.Edge (“e”, “g”, 1),
nuevo Graph.Edge (“f”, “g”, 2),
nuevo Graph.Edge (“f”, “h”, 3),
nuevo Graph.Edge (“g”, “h”, 6),
nuevo Graph.Edge (“g”, “f”, 2),
};
Private static final String START = “a”;
Cadena estática final privada END = “h”;
public static void main (String [] args) {
Gráfico g = nuevo Gráfico (GRÁFICO);
g.dijkstra (START);
g.printPath (END);
}
}
Salida:
a -> c (2) -> d (4) -> e (5) -> g (6) -> f (8) -> h (11)