J'ai une forêt, c'est-à-dire des nœuds avec des bords dirigés et aucun cycle (dirigé ou non). Je définis la hauteur d'un sommet comme 0 s'il n'a pas d'arêtes entrantes, ou le nombre maximum d'arêtes à parcourir en sens inverse pour atteindre un sommet de hauteur 0.
Je sais également que le degré moyen d'un nœud est une petite constante, disons environ 2. Pour trouver la hauteur de tous les sommets, je peux penser à deux algorithmes:
Algorithme de marche
- Parcourez et marquez pour les sommets sans arêtes entrantes.
- Pour chaque sommet avec , suivez les bords sortants, en mettant à jour la hauteur de chaque sommet rencontré si sa hauteur précédente est plus petite.
Algorithme de frontière
- Parcourez et marquez pour les sommets sans arêtes entrantes, et marquez-les comme frontière.
- Pour chaque sommet de frontière, voyez si son parent a des enfants à la frontière ou en dessous. Si c'est le cas, marquez le parent comme ayant plus la plus grande hauteur parmi ses enfants. Marquez le parent comme étant à la frontière.
- Répétez 2 jusqu'à ce qu'il n'y ait rien au-delà de la frontière.
Mes questions:
- Y a-t-il un nom pour ce problème et une solution la plus rapide bien connue?
- J'ai tendance à penser simplement en remontant de toutes les vertices est la solution la plus rapide. Ai-je raison?
la source
Je ne sais pas si ce problème a un nom officiel ou non. Votre titre résume assez bien. Monter à partir des nœuds de hauteur 0 sera rapide, à condition de prendre soin d'éviter les travaux en double. Supposons que vous ayez un nœud avec de nombreux enfants et un long chemin au-dessus de ce nœud jusqu'à la racine. Supposons également que les hauteurs de chacun des enfants soient différentes. Chaque enfant peut mettre à jour la hauteur du nœud en question. C'est bon. Mais vous devez également éviter de mettre à jour le long chemin au-dessus de ce nœud jusqu'à ce que tous ses enfants aient signalé leurs hauteurs.
L'algorithme résultant s'exécutera en temps linéaire et le pseudo-code ressemblerait à ceci:
la source
Un problème si similaire qu'il pourrait être intéressant est «Préfixe parallèle sur les arbres dirigés enracinés». L'algorithme trouve le nombre d'arêtes à la racine de chaque nœud. Ainsi, les racines se retrouvent avec la valeur 0, tandis que par exemple le nœud en bas à droite se retrouverait avec une valeur de deux.
Notez que l'algorithme ci-dessous résout le problème plus général des bords pondérés, mais vous pouvez simplement initialiser le W (i) à 1 pour tout i. Et le successeur de chaque nœud i est donné par P (i) = j.
L'image ci-dessous illustre la "réduction de moitié" des longueurs de trajet et rend le temps d'exécution logarithmique facile à comprendre. Il ne montre cependant pas les hauteurs de nœud calculées.
(extrait de "Introduction to Parallel Algorithms" de Joseph Jaja).
Utilisant plusieurs processeurs, il est résoluble en temps O (lg n), mais utilise des opérations O (n lg n). Il existe un hack pour le ramener au travail linéaire, mais il est légèrement impliqué.
la source
S(i)
représente?