Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Dalam graf berwajaran dua arah, cari jarak terpendek antara nod yang diberikan dengan mengalih keluar sebarang tepi K

Dalam graf berwajaran dua arah, cari jarak terpendek antara nod yang diberikan dengan mengalih keluar sebarang tepi K

WBOY
WBOYke hadapan
2023-09-11 17:01:13991semak imbas

Dalam graf berwajaran dua arah, cari jarak terpendek antara nod yang diberikan dengan mengalih keluar sebarang tepi K

Pengenalan

Atur cara C ini mengira jarak terpendek antara dua nod yang diberikan dalam graf berwajaran dua arah dengan mengalih keluar sebarang tepi K. Ia menggunakan algoritma Dijkstra yang diubah suai yang menganggap penyingkiran tepi K sebagai kekangan. Program ini menggunakan baris gilir keutamaan untuk memilih nod dengan cekap dan melaraskan berat tepi secara dinamik berdasarkan keperluan penyingkiran. Ia memberikan jarak minimum antara nod yang diberikan dengan merentasi graf dan mencari laluan terpendek, dengan mengambil kira kesan mengalihkan tepi K.

Kaedah 1: Algoritma Dijkstra yang diubah suai

Algoritma

Langkah 1: Buat struktur untuk menyimpan nod dan jarak pemisahannya daripada nod sumber

Langkah 2: Mulakan pemisahan semua pusat kepada infiniti, tetapi tetapkan pemisahan pusat sumber kepada 0.

Langkah 3: Letakkan nod sumber ke dalam baris keperluan bersama-sama dengan nod yang berasingan.

Langkah 4: Lakukan semula langkah berikut sehingga baris yang diperlukan dikosongkan:

a. Keluarkan nod dengan penyingkiran minimum daripada baris yang diperlukan

b. Untuk setiap jiran nod yang dinyah gilir, hitung pemadaman yang tidak digunakan dengan memasukkan berat tepi dan semak sama ada ia lebih kecil daripada pemadaman semasa.

c. Jika penyingkiran yang tidak digunakan kurang, tingkatkan detasmen dan masukkan pusat ke barisan permintaan.

d. Jejaki bilangan tepi pemindahan setiap hab.

Langkah 5: Selepas mempertimbangkan untuk mengalih keluar tepi K, kembalikan laluan paling ketat antara nod sumber dan nod sasaran.

Terjemahan bahasa Cina bagi

Contoh

ialah:

Contoh

#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;
}

Output

shortest distance: 8

Kaedah 2: Algoritma Floyd-Walsh

Algoritma

Langkah 1: Mulakan dist rangkaian dua dimensi[][] dengan pemberat tepi dalam graf.

Langkah 2: Mulakan kekisi dua dimensi yang dikosongkan[][] untuk menjejak bilangan tepi yang diusir antara setiap pasangan nod.

Langkah 3: Gunakan kaedah pengiraan Floyd-Walsh untuk mengira laluan terpendek antara setiap perlawanan berganti-ganti, dengan mengambil kira penarikan tepi K.

Langkah 4: Selepas mempertimbangkan dan mengecualikan tepi K, kembalikan jarak terpendek antara nod sumber dan nod sasaran.

Terjemahan bahasa Cina bagi

Contoh

ialah:

Contoh

#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;
}

Output

Shortest distance: 8

Kesimpulan

Kami mengkaji dua kaedah untuk mencari penyingkiran terpendek antara pusat yang diberikan dalam graf berwajaran dua arah dengan mempertimbangkan pemindahan tepi K. Kaedah ini, khususnya pengiraan Dijkstra yang diubah suai, pengiraan Freud-Walcher, menyediakan pelbagai cara untuk memahami masalah. Dengan memanfaatkan pengiraan ini dalam C, kami akan mengira dengan tepat jumlah penyingkiran minimum sambil memenuhi pemindahan tepi K. Pilihan kaedah bergantung pada komponen seperti metrik graf, kerumitan, dan prasyarat khusus masalah yang dihadapi.

Atas ialah kandungan terperinci Dalam graf berwajaran dua arah, cari jarak terpendek antara nod yang diberikan dengan mengalih keluar sebarang tepi K. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:tutorialspoint.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam
Artikel sebelumnya:Melaksanakan B*-tree dalam C++Artikel seterusnya:Melaksanakan B*-tree dalam C++