/** * Der Graph muss aus DependencyVertices bestehen * * die besonderen Knoten brauchen wir, da wir "hasOutgoingEdges()" nicht ganz easy berechnen können * (wir bräuchten die EdgesList flipped) * * Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford (2001), "Section 22.4: Topological sort", Introduction to Algorithms (2nd ed.), MIT Press and McGraw-Hill, pp. 549–552, ISBN 0-262-03293-7. * * gibt eine Liste aller Vertices in der topologischen Sortierung zurück * die elemente mit "den meisten dependencies" befinden sich hinten in der liste * @return array */ public static function TopologicalSort(Graph $g) { $list = array(); if (count($g->V()) == 0) { return $list; } // rufe DFS auf $g auf // füge jeden abgearbeiteten Knoten an den Kopf einer Liste ein $dfsVisit = function (DependencyVertice $vertice) use($g, &$list, &$dfsVisit) { if (!$vertice->isVisited()) { $vertice->setVisited(TRUE); foreach ($g->N($vertice) as $adjacentVertice) { $dfsVisit($adjacentVertice); } array_unshift($list, $vertice); } }; // wir beginnen nicht mit einem Startknoten sondern mit allen Startknoten, die keine dependencies haben $s = array(); foreach ($g->V() as $vertice) { if (count($vertice->getDependencies()) === 0) { $s[] = $vertice; $dfsVisit($vertice); } } if (count($s) === 0) { throw new TopologicalSortRuntimeException('Der Graph g kann nicht topologisch sortiert werden. Es wurden keine Startknoten gefunden die überhaupt keine Dependencies haben'); } return $list; }