Maison  >  Article  >  développement back-end  >  Dans un graphe pondéré orienté, trouvez le chemin le plus court contenant exactement k arêtes.

Dans un graphe pondéré orienté, trouvez le chemin le plus court contenant exactement k arêtes.

PHPz
PHPzavant
2023-09-11 19:17:02942parcourir

Dans un graphe pondéré orienté, trouvez le chemin le plus court contenant exactement k arêtes.

Dans un graphe pondéré coordonné, le problème de trouver le chemin le plus court avec exactement k arêtes implique de déterminer le chemin avec le plus petit poids tout en parcourant exactement k arêtes. Cet objectif sera atteint en employant des stratégies de programmation dynamiques, telles que l'utilisation de cadres 3D pour stocker des poids minimaux de toutes les manières imaginables. Le calcul est répété aux sommets et aux arêtes, en ajustant le poids minimum à chaque étape. En considérant toutes les manières possibles d’avoir exactement k arêtes, le calcul peut distinguer la manière la plus limitée d’avoir k arêtes dans le graphe.

Méthode à utiliser

  • Méthode récursive naïve

  • Algorithme de Dijkstra avec contraintes de bord

Méthode récursive naïve

Les méthodes récursives naïves peuvent constituer une stratégie importante et claire pour la résolution de problèmes, qui consiste à décomposer des problèmes complexes en sous-problèmes plus petits et à les résoudre de manière récursive. Dans cette approche, le travail s'appelle plusieurs fois pour explorer les sous-problèmes jusqu'à ce que le cas de base soit atteint. Néanmoins, cela peut être un gaspillage pour des problèmes plus importants en raison du double comptage et de la couverture des sous-problèmes. Cela nécessite des méthodes d’optimisation telles que la programmation mémoire ou énergétique. Les méthodes récursives crédules sont faciles à obtenir et à mettre en œuvre, mais peuvent souffrir d'une complexité temporelle exponentielle. Il est souvent utilisé pour résoudre des problèmes à petite échelle ou comme point de départ pour des calculs plus optimaux.

Algorithme

  • Représente le chemin le plus court de travail (graphique, u, v, k) qui prend en entrée un graphique, un sommet source u, un sommet cible v et le nombre d'arêtes k.

  • Vérifiez la situation de base :

  • a. Renvoie si k et u atteignent le seuil de rentabilité avec v (puisqu'aucune arête n'est autorisée dans ce cas).

  • Le deuxième. Si k vaut 1 et qu’il y a une arête entre u et v dans le graphique, son poids est renvoyé.

  • c. Si k est inférieur ou égal à 0, renvoie un nombre illimité (puisque les bords négatifs ou nuls ne sont pas autorisés).

  • Initialisez une résolution variable infinie pour stocker la distance de chemin la plus courte.

  • Le graphique doit parcourir tous les sommets comme suit :

  • a. Si u et i ne s'élèvent pas vers u ou v, alors il existe un bord de u à i :

  • Appelez le chemin le plus court de manière récursive, où i est le sommet source moderne, v est le sommet cible et k−1 est le nombre d'arêtes restantes.

  • Si le résultat renvoyé n'est pas infini, res est mis à niveau vers la valeur minimale de res et le poids du bord actuel et le résultat récursif.

  • Renvoie la valeur de res comme moyen le plus limité de séparer avec précision les k bords.

Exemple

#include <iostream>
#include <climits>

#define V 4
#define INF INT_MAX

int shortestPathWithKEdges(int graph[][V], int source, int destination, int k) {
    // Base cases
    if (k == 0 && source == destination)
        return 0;
    if (k == 1 && graph[source][destination] != INF)
        return graph[source][destination];
    if (k <= 0)
        return INF;

    // Initialize result
    int shortestPathDistance = INF;

    // Explore all adjacent vertices of the source vertex
    for (int i = 0; i < V; i++) {
        if (graph[source][i] != INF && source != i && destination != i) {
            int recursiveDistance = shortestPathWithKEdges(graph, i, destination, k - 1);
            if (recursiveDistance != INF)
                shortestPathDistance = std::min(shortestPathDistance, graph[source][i] + recursiveDistance);
        }
    }

    return shortestPathDistance;
}

int main() {
    int graph[V][V] = {
        {0, 10, 3, 2},
        {INF, 0, INF, 7},
        {INF, INF, 0, 6},
        {INF, INF, INF, 0}
    };
    int source = 0, destination = 3, k = 2;
    std::cout << "Weight of the shortest path is " << shortestPathWithKEdges(graph, source, destination, k) << std::endl;
    return 0;
}

Sortie

Weight of the shortest path is 9

Algorithme de Dijkstra avec contraintes de bord

L'algorithme de Dijkstra avec contraintes de bord est un calcul de parcours de graphe utilisé pour identifier le chemin le plus court entre un sommet source et tous les autres sommets du graphe. Il prend en compte les limites ou contraintes sur les bords du graphique, telles que les poids des bords les plus ou les moins extrêmes. Le calcul conserve les lignes de sommets requises et sélectionne de manière itérative le moins de sommets à supprimer. À ce stade, si un chemin plus court est trouvé, il assouplit les sommets adjacents en augmentant la distance entre eux. Cette préparation se poursuit jusqu'à ce que tous les sommets aient été visités. L'algorithme de Dijkstra avec commandes de bord garantit que la voie choisie satisfait aux contraintes de bord requises tout en trouvant la voie la plus limitée

Algorithme

  • Créez l'œuvre de Dijkstra en utilisant les paramètres suivants

  • Graphique : graphique d'entrée avec sommets et arêtes

    Source : sommet de départ du chemin le plus limité

    Contraintes : Limitations ou obstacles aux bords

    Initialisez un ensemble de sommets disparus et une ligne de demande pour stocker les sommets et leurs distances.

  • Créez un cluster de suppression et définissez la suppression sur terminabilité pour tous les sommets à l'exception du sommet source, qui est défini sur 0.

  • Organisez les sommets sources dans les lignes souhaitées avec leur distance.

  • Bien que le pipeline de demande ne puisse pas être purgé, veuillez procéder comme suit :

  • Supprimez le sommet avec le moins d'éliminations de la file d'attente souhaitée.

  • Si le sommet n'est plus visité maintenant,

  • Marquez-le comme visité.

  • Pour chaque sommet adjacent d'un sommet moderne :

  • Appliquez des barrières de bord pour déterminer si un bord peut être pris en compte.

  • Calculez la distance inutilisée entre les sommets d'alimentation et les sommets adjacents en tenant compte des poids et des contraintes des bords.

  • Améliorez le tableau de délimiteurs si les délimiteurs actuels sont plus courts que les délimiteurs modernes.

  • Mettez en file d'attente les sommets adjacents avec leur distance inutilisée dans la ligne souhaitée.

  • Une fois tous les sommets atteints, un cluster distinct contiendra la courte distance maximale entre le sommet d'alimentation et chaque sommet qui satisfait aux contraintes de bord.

  • Renvoyer les clusters individuels comme résultats.

示例

#include <iostream>
#include <vector>
#include <limits>

struct Edge {
    int destination;
    int weight;
};

void dijkstra(const std::vector<std::vector<Edge>>& graph, int source, std::vector<int>& distance) {
    int numVertices = graph.size();
    std::vector<bool> visited(numVertices, false);
    distance.resize(numVertices, std::numeric_limits<int>::max());
    distance[source] = 0;

    for (int i = 0; i < numVertices - 1; ++i) {
        int minDistance = std::numeric_limits<int>::max();
        int minVertex = -1;

        for (int v = 0; v < numVertices; ++v) {
            if (!visited[v] && distance[v] < minDistance) {
                minDistance = distance[v];
                minVertex = v;
            }
        }

        if (minVertex == -1)
            break;

        visited[minVertex] = true;

        for (const auto& edge : graph[minVertex]) {
            int destination = edge.destination;
            int weight = edge.weight;

            if (!visited[destination] && distance[minVertex] != std::numeric_limits<int>::max() &&
                distance[minVertex] + weight < distance[destination]) {
                distance[destination] = distance[minVertex] + weight;
            }
        }
    }
}

int main() {
    int numVertices = 4;
    int source = 0;
    std::vector<std::vector<Edge>> graph(numVertices);

    // Add edges to the graph (destination, weight)
    graph[0] = {{1, 10}, {2, 3}};
    graph[1] = {{2, 1}, {3, 7}};
    graph[2] = {{3, 6}};

    std::vector<int> distance;
    dijkstra(graph, source, distance);

    // Print the shortest distances from the source vertex
    std::cout << "Shortest distances from vertex " << source << ":\n";
    for (int i = 0; i < numVertices; ++i) {
        std::cout << "Vertex " << i << ": " << distance[i] << '\n';
    }

    return 0;
}

输出

Shortest distances from vertex 0:
Vertex 0: 0
Vertex 1: 10
Vertex 2: 3
Vertex 3: 9

结论

本文概述了两个重要的计算,以帮助理解协调和加权图表中的大多数问题。它阐明了易受骗的递归方法和带有边缘限制的 Dijkstra 计算。轻信递归方法包括递归地研究具有精确 k 个边的所有可能的方式,以发现最有限的方式。 Dijkstra 的边命令式计算采用了所需的线和面积规则,成功地找出了图表中从供给顶点到所有不同顶点的最大受限方式。本文包含了计算的具体说明,并给出了测试代码来说明其用法.

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