Example #1
0
 /**
  * Calculate the PageRank for all nodes in $graph.
  * @param Graph $graph
  * @param bool $keepAllRoundData [optional]. Default: false. If true, the values for every round of calculation is kept. Great for understanding what's going on during the calculation.
  * @return PageRankResult
  */
 public function calculatePagerank(Graph $graph, $keepAllRoundData = false)
 {
     $round = 0;
     $rounds = [];
     $ns = $graph->getNodes();
     $edges = $graph->getEdges();
     /** @var PageRankNode[] $nodes */
     $nodes = [];
     //transform to PageRankNodes
     foreach ($edges as $edge) {
         $prFromNode = $this->getPageRankNode($edge->getFrom(), $nodes);
         $prNodeTo = $this->getPageRankNode($edge->getTo(), $nodes);
         $prFromNode->addLinkTo($prNodeTo);
         $prNodeTo->addLinkFrom($prFromNode);
     }
     //transform (remaining) disconnected Nodes (that are not part of an Edge) to PageRankNodes
     foreach ($ns as $node) {
         $this->getPageRankNode($node, $nodes);
     }
     $this->getLogger()->debug("Got " . count($nodes) . " nodes in total");
     do {
         $distance = 0;
         $currentRound = new PageRankNodeHistory($round);
         $newPrCache = [];
         foreach ($nodes as $key => $node) {
             $node->setOldPr($node->getPr());
             $newPr = $node->calculatePageRank($this->dampingFactor, count($nodes));
             $curDistance = abs($node->getOldPr() - $newPr);
             if ($curDistance > $distance) {
                 $distance = $curDistance;
             }
             $entry = new PageRankNodeHistoryEntry($node, $node->getOldPr(), $newPr);
             $newPrCache[$key] = $newPr;
             $currentRound->addEntry($entry);
         }
         foreach ($nodes as $key => $node) {
             $newPr = $newPrCache[$key];
             $node->setPr($newPr);
         }
         if (!$keepAllRoundData) {
             $rounds = [];
         }
         $rounds[$round] = $currentRound;
         $round++;
         $this->getLogger()->debug("Calculating round {$round}. Max rounds: {$this->maxRounds}. Last max distance: {$distance}. Required max distance: {$this->maxDistance}");
     } while ($round < $this->maxRounds && ($distance == 0 || $distance > $this->maxDistance));
     $result = new PageRankResult($graph, $rounds);
     return $result;
 }