/** * Main visit function * * Visit function to process an automaton (directed, cyclic, discontinuous * graph). No more detailed methods are defined, since the process of * visiting is highly dependent on the concrete visitor implementation. * * Optionally labels may be passed for each node in the graph, which might * be used during the rendering process. * * Returns an array with the support for each node, which just represents * the number of incoming edges. * * @param slAutomaton $automaton * @return array */ public function visit(slAutomaton $automaton, array $labels = array()) { $nodes = $automaton->getNodes(); $ranks = array(); foreach ($nodes as $node) { $ranks[$node] = count($automaton->getIncoming($node)); } return $ranks; }
/** * Merge singleton nodes * * All equivalency classes which consist of just one nodes are considered * singleton nodes. This method merges all maximum sets of singleton nodes, * which share the same successors and precedessors. * * @param slAutomaton $automaton * @return void */ protected function mergeSingletonNodes(slAutomaton $automaton) { $classes = array_keys($this->equivalenceClasses); $classCount = count($classes); for ($i = 0; $i < $classCount; ++$i) { if (!isset($this->equivalenceClasses[$classes[$i]]) || count($this->equivalenceClasses[$classes[$i]]) > 1) { // We only care for singletons continue; } for ($j = $i + 1; $j < $classCount; ++$j) { if (!isset($this->equivalenceClasses[$classes[$j]]) || count($this->equivalenceClasses[$classes[$j]]) > 1) { // We only care for singletons continue; } if ($automaton->getOutgoing($classes[$i]) === $automaton->getOutgoing($classes[$j]) && $automaton->getIncoming($classes[$i]) === $automaton->getIncoming($classes[$j])) { $this->equivalenceClasses[$classes[$i]][] = $classes[$j]; unset($this->equivalenceClasses[$classes[$j]]); $automaton->removeNode($classes[$j]); } } } }
/** * Main visit function * * Visit function to process an automaton (directed, cyclic, discontinuous * graph). No more detailed methods are defined, since the process of * visiting is highly dependent on the concrete visitor implementation. * * Optionally labels may be passed for each node in the graph, which might * be used during the rendering process. * * Returns an array with values for each node, representing their "imporance" * in the graph based on Googles PageRank algorithm. * * @param slAutomaton $automaton * @return array */ public function visit(slAutomaton $automaton, array $labels = array()) { $nodes = $automaton->getNodes(); $ranks = array(); foreach ($nodes as $node) { $ranks[$node] = 1; } for ($i = 0; $i < $this->iterations; ++$i) { foreach ($nodes as $node) { $rank = 0; foreach ($automaton->getIncoming($node) as $src) { $pr = $ranks[$src]; $c = count($automaton->getOutgoing($src)); $rank += $pr / $c; } $ranks[$node] = 1 - $this->dampingFactor + $this->dampingFactor * $rank; } } return $ranks; }