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> 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) p>
{
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; p>
}
}
/* 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;
} p>
/* 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;
} p>
}
}
/* 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);
} p>
/* 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 { p>
printf(" -");
}
}
putchar('\n');
}
obtener();
}