Red de conocimiento informático - Conocimiento de la instalación - Programa Find c para encontrar el camino más corto entre dos puntos de la red

Programa Find c para encontrar el camino más corto entre dos puntos de la red

/*

* Archivo:short.c

* Descripción: Algoritmo de Dijkstra para el camino más corto entre dos puntos de la red

* Algoritmo de Dijkstra de ruta más corta

* Creado: 25/11/2001

* Autor: Justin Hou [mailto: justin_hou@hotmail.com]

* /

#include lt; stdio.hgt;

#define verdadero 1

#define falso 0

#define I 9999 / * infinito*/

#define N 20 /* Número de vértices de la ciudad*/

int cost[N][N] = {

{0, 3, yo, yo, yo, 1, yo, yo, yo, yo, yo, yo, yo, yo, yo, yo, yo, yo, yo, yo, yo},

{3,0 ,5,yo ,yo,yo,6,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo},

{yo,5, 0,4, yo,yo,yo,1,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo},

{yo,yo,4 ,0,2 ,yo,yo,yo,6,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo},

{yo,yo,yo, 2,0, yo,yo,yo,yo,7,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo},

{1,yo,yo,yo ,Yo,0 ,1,Yo,Yo,Yo,2,Yo,Yo,Yo,Yo,Yo,Yo,Yo,Yo,Yo},

{Yo,6,Yo,Yo, I,1, 0, 6, I, I, I, 7, I, I, I, I, I, I, I, I},

{I, I, 1, I, I , Yo, 6 ,0,2,Yo,Yo,Yo,3,Yo,Yo,Yo,Yo,Yo,Yo,Yo},

{Yo,Yo,Yo,6,Yo, Yo,yo, 2, 0, 8, yo, yo, yo, 4, yo, yo, yo, yo, yo, yo},

{Yo, yo, yo, yo, 7, yo , Yo, Yo ,8,0,Yo,Yo,Yo,Yo,5,Yo,Yo,Yo,Yo,Yo},

{Yo,Yo,Yo,Yo,Yo,2, Yo,yo,yo,yo,0,4,yo,yo,yo,3,yo,yo,yo,yo},

{yo,yo,yo,yo,yo,yo,7 ,yo,yo ,yo,4,0,3,yo,yo,yo,4,yo,yo,yo},

{yo,yo,yo,yo,yo,yo,yo, 3,yo,yo,yo,3,0,3,yo,yo,yo,5,yo,yo},

{yo,yo,yo,yo,yo,yo,yo,yo ,4,yo ,yo,yo,3,0,7,yo,yo,yo,2,yo},

{yo,yo,yo,yo,yo,yo,yo,yo, Yo,5, Yo,Yo,Yo,7,0,Yo,Yo,Yo,Yo,3},

{Yo,Yo,Yo,Yo,Yo,Yo,Yo,Yo,Yo,Yo ,Yo,3 ,Yo,Yo,Yo,Yo,0,5,Yo,Yo,Yo},

{Yo,Yo,Yo,Yo,Yo,Yo,Yo,Yo,Yo,Yo, Yo,yo, 4, yo, yo, yo, 5, 0, 8, yo, yo},

{Yo, yo,

Yo, yo, yo, yo, yo, yo, yo, yo, yo, yo, 5, yo, yo, yo, 8, 0, 6, yo},

{Yo, yo, yo ,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo,2,yo,yo,yo,6,0,4},

{yo,yo,yo, Yo,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo,yo,3,yo,yo,yo,4,0}

};

int dist[N]; /* Almacena la longitud de ruta más corta actual*/

int v0 = 'A' - 65 /* El punto inicial es A */

void main; ()

{

int final[N], i, v, w, min;

/* Inicializa los datos de longitud de ruta más corta, todos los datos son datos no finales */

for (v = 0; v lt; N; v) {

final[v] = false

dist[v] ] = costo [v0][v];

}

/* Primero, la distancia de v0 a v0 debe ser la más corta y los datos finales*/

final[v0] = true;

/* Encuentra otros N-1 nodos*/

for (i = 0; i lt; N-1; i) {

min = I; /* La longitud más corta inicial es infinita*/

/* Encuentra el lado más corto*/

para (w = 0; w lt; N; w) {

si (!final[w] amp; amp; dist[w] lt; min) {

min = dist[w]; p>

v = w ;

}

}

final[v] = true; /* Agregar nuevo borde*/

for (w = 0 ; w lt; N; w ) { /* Actualizar datos dist[]*/

if (!final[w] amp; amp; dist[v] costo[ v][w] lt; dist [w]) {

dist[w] = dist[v] costo[v][w]; p> }

}

for (i = 0; i lt; N; i) { /* Pantalla a monitorear*/

printf("c-gt;c: 2d\t", v0 65, i 65, dist[i]);

}

}); >if (izquierda == NULL || derecha == NULL) {

fprintf(stderr, "Error malloc.\n");

salir(-1); p>

}

/* Inicializa los nodos de las ramas izquierda y derecha*/

left-gt;bound = root.bound /* Hereda el límite inferior de el nodo padre*/

left-gt; matriz = LeftNode(root.matrix, selectedEdge /* Eliminar bordes de rama*/

left-gt; ;/* Hereda la ruta del nodo padre, sin agregar nuevos bordes*/

left-gt; left = NULL

left-gt; >

right-gt;bound = root.bound;

right-gt; matriz = RightNode(root.matrix, selectedEdge, root.path /* Eliminar filas, columnas y bordes de bucle*); /

right-gt; path = AddEdge(selectedEdge, root.path); /* Agrega el borde seleccionado*/

right-gt;

right-gt ;right = NULL;

/* Reducir los nodos de las ramas izquierda y derecha*/

left-gt; );

right-gt;bound = Simplify(amp;right-gt;matrix);

/* Enlace a raíz*/

root.left = izquierda;

p>

root.right = derecha;

/* Mostrar a monitor*/

puts("Rama derecha:\n --------- ---");

ShowMatrix(right-gt;matrix);

puts("Rama izquierda:\n---- -------") ;

ShowMatrix(left-gt; Matrix);

/* Si el límite inferior del nodo derecho es más pequeño que la mejor respuesta actual , continúa la búsqueda de ramas*/

if (right-gt;bound lt; minDist) {

BABA(*right);

}

/* De lo contrario, no se realiza ninguna búsqueda porque esta rama es imposible generar una ruta mejor*/

else {

printf("Current minDist es d, " , minDist);

printf("Bloqueado de la rama derecha (= d).\n", right-gt; enlazado);

printf("Esta rama está muerta.\n ");

}

/* Si el límite inferior del nodo derecho es más pequeño que la mejor respuesta actual, continúe la búsqueda de rama*/

>if (left-gt;bound lt; minDist) {

BABA(*left);

}

/* De lo contrario, no busques, porque this Es imposible generar una ruta mejor*/

else {

printf("La minDist actual es d, ", minDist;

printf(" Límite de la rama izquierda(= d).\n", left-gt;bound);

printf("Esta rama está muerta.\n");

}

printf("La mejor respuesta ahora es d\n", minDist

return (minPath

}

/* patch); ruta */

RUTA MendPath(RUTA ruta, MATRIZ c)

{

int fila, col;

BORDE borde;

p>

int n = c.citiesNumber;

for (fila = 0; fila lt; n; fila) {

edge.head = fila;

for (col = 0; col lt; n; col) {

edge.tail = col;

if (c.distance[fila ][col] == 0) {

ruta = AddEdge(borde, ruta);

}

}

}

ruta de retorno;

}

/* Reducir la matriz de costos, devolver la constante de reducción de la matriz de costos*/

int Simplificar( MATRIZ* c)

{

int fila, col, min_dist, h;

int n = c-gtnúmero de ciudades

h = 0;

/* Reducción de filas*/

for (fila = 0; fila lt; n; fila) {

/* Encuentra el elemento más pequeño en esta fila */

min_dist = INFINITY;

for (col = 0; col lt; n; col) {

if (c- gt; distancia[fila ][col] lt; min_dist) {

min_dist = c-gt; distancia[fila][col];

}

}

/* Si los elementos de esta fila son todos infinitos, significa que esta fila ha sido eliminada*/

if (min_dist == INFINITY) continuar;

/* Cada elemento de esta fila Resta el elemento más pequeño*/

for (col = 0; col lt; n; col) {

if (c-gt; distancia[fila][col] != INFINITO ) {

c-gt;distancia[fila][col] -= min_dist;

}

}

/* Cálculo Constante de reducción*/

h = min_dist;

}

/* Reducción de columna*/

for (col = 0; col lt; n ; col ) {

/* Encuentra el elemento más pequeño en esta columna*/

min_dist = INFINITY;

for (fila = 0; fila lt; n ; fila ) {

if (c-gt; distancia[fila][col] lt; min_dist) {

min_dist = c-gt; distancia[fila][col]; /p>

}

}

/* Si los elementos de esta columna son infinitos, significa que esta columna ha sido eliminada*/

if ( min_dist == INFINITY) continue;

/* Reste el elemento mínimo de los elementos de esta columna*/

for (fila = 0; fila lt; n; fila) {

if (c-gt;distancia[fila][col] != INFINITO) {

c-gt;distancia[fila][col] -= min_dist;

}

}

/* Calcular la constante de reducción*/

h = min_dist;

}

return (h);

}

/* Busque el borde más adecuado entre todos los bordes de costo cero para agrandar el límite inferior de la rama izquierda*/

EDGE SelectBestEdge (MATRIZ c)

{

int fila, col;

int n = c.citiesNumber;

int maxD;

int maxD; p>

EDGE mejor, borde;

/* Declaración de función utilizada*/

int D (MATRIZ, BORDE);

maxD = 0

for (fila = 0; fila lt; n; fila) {

for (col = 0 ; col lt; n; col) {

borde .head = fila

borde.cola = col

if (!c.distance[fila; ][col] amp; maxD lt; D(c, borde) ) {

maxD = D(c, borde);

mejor = borde;

}

}

}

retorno (mejor);

}

/* Calcular el aumento en el límite inferior de la rama izquierda (excluyendo el borde) si se selecciona borde como borde de la rama Cantidad*/

int D(MATRIX c, EDGE edge)

{.

int fila, col, dRow, dCol;

int n = c.citiesNumber;

dRow = INFINITY;

for ( col = 0; col lt; col ) {

if (dRow lt ; c.distance[edge.head][col] amp; amp; col != borde.

cola) {

dRow = c.distance[edge.head][col];

}

}

dCol = INFINITY ;

for (fila = 0; fila lt; n; fila) {

if (dCol lt; c.distance[fila][edge.tail] amp; amp; fila != borde.cabeza) {

dCol = c.distance[fila][borde.cola];

}

}

return (dRow dCol);

}

/* Eliminar el borde de la rama seleccionada*/

MATRIX LeftNode(MATRIX c, borde EDGE)

{

c.distance[edge.head][edge.tail] = INFINITO;

retorno c;

}

/* Eliminar la matriz después de filas, columnas y bordes de bucle*/

MATRIX RightNode(MATRIX c, borde EDGE, ruta PATH)

{

int fila, col;

int n = c.citiesNumber;

EDGE loopEdge;

/* Declarar la función de borde de bucle requerida*/

BORDE LoopEdge(RUTA, BORDE);

for (col = 0; col lt; n; col)

c.distance[edge.head][ col] = INFINITO;

for (fila = 0; fila lt; n; fila)

c.distance[fila][edge.tail] = INFINITO;

loopEdge = LoopEdge(ruta, borde);

c.distance[loopEdge.head][loopEdge.tail] = INFINITY;

return (c);

}

/* Función para calcular los bordes del bucle

* Además de los nuevos bordes agregados, el conjunto de rutas del nodo actual también puede contener algunos bordes seleccionados. Estos bordes forman uno. o

* varios caminos Para no formar un bucle, los caminos que contienen nuevos bordes no deben estar conectados de principio a fin. Esta función devuelve este

* camino que está conectado. desde el principio hasta el final para establecer la longitud del lado del bucle en infinito.

*/

EDGE LoopEdge(ruta RUTA, borde EDGE)

{

int i, j;

EDGE loopEdge;

/* Borde de bucle mínimo*/

loopEdge.head = edge.tail;

loopEdge.tail = edge.head

/* Encuentre el punto final del encabezado del borde del bucle, es decir, el punto final de la ruta que contiene el nuevo borde*/

for (i = 0; i lt; path. bordesNumber; i) {

for (j = 0; j lt; ruta.edgesNumber; j ) {

if (loopEdge.head == ruta.edge[j].head ) {

/* Expandir borde del bucle*/

loopEdge.head = path.edge[j].tail;

break;

}

}

}

/* Encuentre el punto final del borde del bucle, es decir, el punto final del camino que contiene el nuevo borde*/

for ( i = 0; i lt; path.edgesNumber; i ) {

for (j = 0; j lt; path.edgesNumber; j ) {

if (loopEdge.tail = = path.edge[j].tail) {

/* Expandir borde del bucle*/

loopEdge.tail = ruta .edge[j].head;

romper;

}

}

}

regresar ( loopEdge);

}

/* Agregar nuevos bordes al camino*/

RUTA AddEdge(borde EDGE, camino de RUTA)

{

path.edge [path.edgesNumber] = borde;

ruta de retorno;

}

/* Calcular el actual orden de la matriz de costos*/

int MatrixSize(MATRIX c, PATH path)

{

return (c.citiesNumber - path.edgesNumber);

}

/* Mostrar ruta*/

void ShowPath(ruta RUTA, MATRIZ c)

{

int i, dist;

BORDE borde;

int n = ruta.númerodebordes;

dist = 0;

printf( "\nLa ruta es: ");

for (i = 0; i lt; n; i) {

edge = path.edge[i];

printf("(d, d) ", borde .cabeza 1, borde.cola 1);

dist = c.distance[edge.head][edge.tail];

}

/* printf("[Costo total: d]\n", dist */

}

/* Mostrar matriz de costos*/

<) p>void ShowMatrix(MATRIX c)

{

int fila, col;

int n = c.citiesNumber;

para (fila = 0; fila lt; n; fila) {

for (col = 0; col lt; n; col) {

if (c.distance[fila][ col] != INFINITO) {

printf("3d", c.distance[fila][col]);

}

else {

printf(" -");

}

}

putchar('\n');

}

obtener();

}