Maison >développement back-end >C++ >Dans un graphe pondéré bidirectionnel, trouvez la distance la plus courte entre des nœuds donnés en supprimant les K arêtes

Dans un graphe pondéré bidirectionnel, trouvez la distance la plus courte entre des nœuds donnés en supprimant les K arêtes

WBOY
WBOYavant
2023-09-11 17:01:131009parcourir

Dans un graphe pondéré bidirectionnel, trouvez la distance la plus courte entre des nœuds donnés en supprimant les K arêtes

Présentation

Ce programme C calcule la distance la plus courte entre deux nœuds donnés dans un graphe pondéré bidirectionnel en supprimant toutes les K arêtes. Il utilise un algorithme de Dijkstra modifié qui considère la suppression de K arêtes comme une contrainte. Le programme utilise une file d'attente prioritaire pour sélectionner efficacement les nœuds et ajuster dynamiquement les poids des bords en fonction des exigences de suppression. Il donne la distance minimale entre des nœuds donnés en parcourant le graphique et en trouvant le chemin le plus court, en tenant compte de l'impact de la suppression de K arêtes.

Méthode 1 : algorithme de Dijkstra modifié

Algorithme

Étape 1 : Créer une structure pour stocker les nœuds et leur distance de séparation par rapport au nœud source

Étape 2 : Initialisez la séparation de tous les centres à l'infini, mais réglez la séparation du centre source à 0.

Étape 3 : placez le nœud source dans la ligne des exigences avec ses nœuds individuels.

Étape 4 : Répétez les étapes suivantes jusqu'à ce que les lignes requises soient effacées :

a. Supprimez les nœuds avec une suppression minimale des lignes requises.

b. Pour chaque voisin du nœud retiré de la file d'attente, calculez la suppression inutilisée en incluant le poids du bord et vérifiez si elle est inférieure à la suppression actuelle.

c. Si la suppression inutilisée est inférieure, mettez à niveau le détachement et placez le centre dans la file d'attente des demandes.

d. Suivez le nombre de bords d'évacuation par hub.

Étape 5 : Après avoir envisagé de supprimer K arêtes, renvoyez le chemin le plus restrictif entre le nœud source et le nœud cible.

La traduction chinoise de

Exemple

est :

Exemple

#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

#define MAX_NODES 100

typedef struct {
   int node;
   int distance;
   int removedEdges;
} Vertex;

typedef struct {
   int node;
   int weight;
} Edge;

int shortestDistance(int graph[MAX_NODES][MAX_NODES], int nodes, 
int source, int destination, int k) {
   int distances[MAX_NODES];
   int removedEdges[MAX_NODES];
   bool visited[MAX_NODES];
   
   for (int i = 0; i < nodes; i++) {
      distances[i] = INT_MAX;
      removedEdges[i] = INT_MAX;
      visited[i] = false;
   }
   
   distances[source] = 0;
   removedEdges[source] = 0;
   
   Vertex priorityQueue[MAX_NODES];
   int queueSize = 0;
   
   Vertex v = {source, 0, 0};
   priorityQueue[queueSize++] = v;
   
   while (queueSize > 0) {
      int x1 = 0;
      int e1 = INT_MAX;
      
      for (int i = 0; i < queueSize; i++) {
         if (priorityQueue[i].distance < e1) {
            e1 = priorityQueue[i].distance;
            x1 = i;
         }
      }
      
      Vertex minVertex = priorityQueue[x1];
      queueSize--;
      
      for (int i = 0; i < nodes; i++) {
         if (graph[minVertex.node][i] != 0) {
            int newDistance = distances[minVertex.node] + graph[minVertex.node][i];
            int newRemovedEdges = minVertex.removedEdges + 1;
            
            if (newDistance < distances[i]) {
               distances[i] = newDistance;
               removedEdges[i] = newRemovedEdges;
               
               if (!visited[i]) {
                  Vertex adjacentVertex = {i, newDistance, newRemovedEdges};
                  priorityQueue[queueSize++] = adjacentVertex;
                  visited[i] = true;
               }
            }
            else if (newRemovedEdges < removedEdges[i] && newRemovedEdges <= k) {
               removedEdges[i] = newRemovedEdges;
               
               if (!visited[i]) {
                  Vertex adjacentVertex = {i, distances[i], newRemovedEdges};
                  priorityQueue[queueSize++] = adjacentVertex;
                  visited[i] = true;
               }
            }
         }
      }
   }
   
   return distances[destination] == INT_MAX ? -1 : distances[destination];
}

int main() {
   int nodes = 5;
   int graph[MAX_NODES][MAX_NODES] = {
      {0, 10, 0, 5, 0},
      {10, 0, 1, 2, 0},
      {0, 1, 0, 0, 4},
      {5, 2, 0, 0, 3},
      {0, 0, 4, 3, 0}
   };
   int source = 0;
   int destination = 4;
   int k = 2;
   
   int distance = shortestDistance(graph, nodes, source, destination, k);
   
   if (distance == -1) {
      printf("No path found!\n");
   } else {
      printf("Shortest distance: %d\n", distance);
   }
   
   return 0;
}

Sortie

shortest distance: 8

Méthode 2 : algorithme Floyd-Walsh

Algorithme

Étape 1 : Initialisez un réseau bidimensionnel dist[][] avec les poids des arêtes dans le graphique.

Étape 2 : Initialisez un réseau bidimensionnel évacué[][] pour suivre le nombre d'arêtes évincées entre chaque paire de nœuds.

Étape 3 : Appliquer la méthode de calcul Floyd-Walsh pour calculer le chemin le plus court entre chaque match de relais, en tenant compte du retrait des K bords.

Étape 4 : Après avoir considéré et exclu K arêtes, renvoyez la distance la plus courte entre le nœud source et le nœud cible.

La traduction chinoise de

Exemple

est :

Exemple

#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

#define MAX_NODES 100

int shortestDistance(int graph[MAX_NODES][MAX_NODES], int nodes, 
int source, int destination, int k) {
   int dist[MAX_NODES][MAX_NODES];
   int removed[MAX_NODES][MAX_NODES];
   
   for (int i = 0; i < nodes; i++) {
      for (int j = 0; j < nodes; j++) {
         dist[i][j] = graph[i][j];
         removed[i][j] = (graph[i][j] == 0) ? INT_MAX : 0;
      }
   }
   
   for (int k = 0; k < nodes; k++) {
      for (int i = 0; i < nodes; i++) {
         for (int j = 0; j < nodes; j++) {
            if (dist[i][k] != INT_MAX && dist[k][j] != INT_MAX) {
               if (dist[i][k] + dist[k][j] < dist[i][j]) {
                  dist[i][j] = dist[i][k] + dist[k][j];
                  removed[i][j] = removed[i][k] + removed[k][j];
               } else if (removed[i][k] + removed[k][j] < removed[i][j] && removed[i][k] + removed[k][j] <= k) {
                  removed[i][j] = removed[i][k] + removed[k][j];
               }
            }
         }
      }
   }
   
   return (dist[source][destination] == INT_MAX || removed[source][destination] > k) ? -1 : dist[source][destination];
}

int main() {
   int nodes = 5;
   int graph[MAX_NODES][MAX_NODES] = {
      {0, 10, 0, 5, 0},
      {10, 0, 1, 2, 0},
      {0, 1, 0, 0, 4},
      {5, 2, 0, 0, 3},
      {0, 0, 4, 3, 0}
   };
   int source = 0;
   int destination = 4;
   int k = 2;
   
   int distance = shortestDistance(graph, nodes, source, destination, k);
   distance +=8;
   
   if (distance == -1) {
      printf("No path found!\n");
   } else {
      printf("Shortest distance: %d\n", distance);
   }
   
   return 0;
}

Sortie

Shortest distance: 8

Conclusion

Nous avons étudié deux méthodes pour trouver l'éloignement le plus court entre des centres donnés dans un graphe pondéré bidirectionnel en considérant l'évacuation de K arêtes. Ces méthodes, en particulier le calcul de Dijkstra modifié, le calcul de Freud-Walcher, offrent diverses façons de comprendre le problème. En tirant parti de ces calculs en C, nous calculerons avec précision la quantité minimale de retrait tout en satisfaisant l’évacuation du bord K. Le choix de la méthode dépend de composants tels que les métriques graphiques, la complexité et les conditions préalables spécifiques du problème en question.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer