Comment faire pour trouver le plus court chemin dans un Arbre dans un temps linéaire?
Ici est un problème à partir d'Algorithmes livre par Vazirani
L'entrée de ce problème est un arbre T entier avec des poids sur les arêtes. Le poids peut être négatif,
zéro ou positif. Donner un temps linéaire de l'algorithme pour trouver le plus court chemin simple en T. La longueur d'un
le chemin est la somme des poids des arêtes dans le chemin. Un chemin est simple, si pas de sommet est répété. Note
que les points de terminaison de la voie sont sans contrainte.INDICE: C'est très similaire au problème de trouver le plus grand ensemble indépendant dans un arbre.
Comment puis-je résoudre ce problème en temps linéaire?
Voici mon algorithme, mais je suis me demande si c'est linéaire dans le temps, car il n'est rien d'autre que de la profondeur d'abord:
- Traverse l'arbre (profondeur d'abord)
- Garder l'index (nœuds)
- ajouter les valeurs
- faire (1) jusqu'à la fin de l'arbre
- comparer la somme et imprimer le chemin d'accès et le montant
ce problème est similaire à ce sujet mais il n'y a pas de réponse certaine.
- Vazirani rapprochement livre? Je ne peut pas comprendre le problème, chaque arête de l'arbre est le chemin, et le plus petit bord est le chemin le plus court, voulez-vous me préciser par la présente, ou de dire le nom exact de problème aussi google? avez-vous trouver le plus court chemin de l'arbre? ou de la racine de l'arbre?
- la plus petite arête n'est pas nécessairement le chemin le plus court, parce que vous pouvez avoir le poids est négatif.
- oui j'avais oublié 🙂
- ce vide est le chemin - c'est le plus court, n'est-ce pas? Vous n'avez pas mis une seule exigence de ce que tha chemin d'accès doit contenir. Il ne fait pas de sens.
- Vide chemin a poids égal à zéro. Un chemin constitué d'un seul poids négatif de bord est plus courte.
- L'INDICE dit que ce problème est lié à la découverte de la plus grande indépendant situé dans un arbre. Toute réflexion sur ce que cela signifie?
Vous devez vous connecter pour publier un commentaire.
Ce problème est à peu près équivalent à la montant minimum sous-suite problème, et peut être résolu d'une manière similaire par la programmation dynamique.
Nous allons calculer les tableaux suivants en utilisant DF recherches:
Si vous pouvez calculer ces, prendre
min(dw1[k], dw1[k] + dw2[k])
sur tous lesk
. C'est parce que votre chemin sera de prendre l'une de ces formes de base:Qui sont toutes couvertes par les sommes d'argent que nous prenons.
Calcul dw1
Exécution d'un DFS du nœud racine. Dans le DFS, de garder trace de l'actuel nœud et son père. À chaque nœud, assumer ses enfants sont
d1, d2, ... dk
. Puisdw1[i] = min(min{dw1[d1] + cost[i, d1], dw1[d2] + cost[i, d2], ..., dw1[dk] + cost[i, dk]}, min{cost[i, dk]})
. Ensembledw1[i] = 0
pour les nœuds feuilles. N'oubliez pas de mettre à jourpw1[i]
avec le prédécesseur.Calcul dw2
Exécution d'un DFS du nœud racine. Faire la même chose que vous avez fait pour
dw1
, sauf lorsqu'on passe d'un nœudi
pour l'un de ses enfantsk
, mettre à jour uniquementdw2[i]
sipw1[i] != k
. Vous appelez la fonction récursive pour tous les enfants toutefois. Il ressemblerait à quelque chose comme ça en pseudo-code:dw1[i]
,dw2[i]
etup[i]
devrait inclure des 0 dans lamin{...}
pour permettre le chemin pour y mettre fin (de sorte que, par exemple, un arbre contenant pas de longueur négative bords de retour d'un score de 0); (3) Je crois que votre calcul dedw2[i]
devrait exclure l'optimal bord...i
seulement, mais à des niveaux inférieurs doivent inclure optimale des bords (vous demander si vous avez besoin de précisions); (4)up[i]
calculs peuvent être simplifiés en notant que chaque parcours est de 1 de 2 types: soit il est "directement vers le bas" ou qu'il contient un "coin supérieur" (un sommet v tel que le parent de v n'est pas dans le path) -- un chemin contenant un coin supérieur à un certain sommet v sera trouvée en considérantdw1[v] + dw2[v]
, doncup[i]
seulement besoin de calculer les coûts droite un chemin de retour vers la racine (c'est à direup[i]
sera le coût minimum d'un "droit-vers le bas" chemin se terminant ài
).i
, vous automatiquement exclure le reste ainsi. (4) je ne suis pas sûr de ce que vous voulez dire ici. Dans ma solution,up
ne stocke pas seulement des voies droites dei
à la racine. Si vous le faites, comment obtiendrez-vous votre réponse? Becase le minimum ne doit pas nécessairement être un chemin droit.dw1[k] + dw2[k]
, parce que les deux chemins ont en commun les bords.min()
permettra null chemins, mais en le laissant complètement forcera tous les chemins pour mettre fin à une feuille -- certainement pas ce qui est voulu. Si vous voulez autoriser les chemins qui se terminent avant les feuilles, mais interdire null chemins, c'est certainement possible, mais nécessite de garder plus des scores pour chaque nœud, je pense. (3) Pas vrai -- rappelez-vous que c'est un arbre, donc si vous avez 2 à la baisse des chemins de départ à v dont la première bords sont différents, ils auront forcément pas de sommets communs (sauf pour v). ...dw2[i]
éviter optimal à bas-bord au niveaui
est suffisante pour garantir que les chemins représenté pardw1[i]
etdw2[i]
sont sommet-disjoints en dehors dei
; éviter optimale de bas bords pourdw2[i]
à chaque niveau tout à faitdw2[i]
pire que ce qu'elle doit être.up
magasin seulement straight-up chemins dei
, parce que le cas où vous êtes inquiet au sujet (quand vous dites que le minimum ne doit pas nécessairement être un chemin droit) seront traitées comme suit: Supposons que le chemin d'accès minimal par le sommet u passe par le bord de u est parent, mais n'est pas "straight up". Dans ce cas, il y a quelques vertex v ci-dessus (plus proche de la racine de) u "qui est le coin supérieur" de ce chemin, et quand nous les parcourir tous les sommets à la recherche pour le meilleur chemin à travers chaque, nous allons trouver ce chemin lorsque nous regardons vertex v. Clair?up
n'est pas du tout nécessaire, si la valeur est null chemins sont autorisés, depuis tout "straight-down" chemin d'accès est équivalent à un chemin d'accès avec un "coin supérieur", dans lequel l'un des 2 "rayons" de ce coin vertex est un null chemin. 🙂dw2[i]
ne sera pas pire que ce qu'elle devrait l'être, parce que vous allez être en utilisant ledw1
dei
s 'enfants de la calculer.dw1
dei
's d'enfants pour le calculer" -- OK on dirait que vous vous êtes déjà à faire ce que je dis alors. La description de votre poste pourrait être lu comme disant quedw2
est calculée de manière récursive à l'aide dedw2
, qui donne à l'suboptimality j'étais inquiet au sujet. Peut-être que vous pourriez mentionner que le calculdw2[i]
revient à l'utilisation dedw1[i]
sur les enfants dans le post?up
peuvent être éliminés par la modification de la réponse globale pour un nœudk
àmin(dw1[k], dw2[k], dw1[k] + dw2[k])
? Cela modifie l'interprétation globale de la requête sur un nœudq
de "Quel est le plus court chemin d'accès contenantq
?" à "qu'est-Ce que le chemin le plus court dont la plus élevée estq
?" - mais c'est OK, parce que chaque chemin d'accès a un plus haut de nœud. 🙂dw2[k]
dans le minimum nécessaire? Il ne sera jamais plus petit quedw1[k]
. Il y a quelques temps, j'ai résolu un problème qui a demandé à des requêtes telles quewhat's the shortest path containing q?
, j'ai donc été mis sur l'utilisation deup
. Rends compte qu'il n'est pas nécessaire ici.dw2[k]
n'est pas nécessaire, au minimum, car il ne peut pas être inférieure àdw1[k]
. De plus en plus simple!