Advertisement
sebbu

Graphs

Nov 17th, 2014
269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.14 KB | None | 0 0
  1. <?php
  2. function array_splice_INV(array $array , int $offset , int $length = NULL , mixed $replacement = NULL ) {
  3.     return array_merge(array_slice($array, 0, $offset), $replacement, array_slice($array, $offset+$length));
  4. }
  5. interface Graph {
  6.     //points / vertices / nodes
  7.     public function addPoint($name);
  8.     public function countPoints();
  9.     public function pointExists($name);
  10.     public function delPoint($name);
  11.     //arcs / edges / links / lines
  12.     public function addLine($src, $dst);
  13.     public function countLines();
  14.     public function lineExists($src, $dst);
  15.     public function delLine($src, $dst);
  16.     //browsing
  17.     public function listLinesFrom($src);
  18.     public function listLinesTo($dst);
  19.     //starts and ends
  20.     public function listSources();
  21.     public function listSinks();
  22.     //iterators ?
  23. };
  24.  
  25. class AdjencyList implements Graph {
  26.     private $names;
  27.     private $points;
  28.     private $lines;
  29.     public function dump() {
  30.         echo '$names=';var_dump($this->names);
  31.         echo '$points=';var_dump($this->points);
  32.         echo '$lines=';var_dump($this->lines);
  33.     }
  34.     public function __construct() {
  35.         $this->names=array();
  36.         $this->points=array();
  37.         $this->lines=array();
  38.     }
  39.     //names
  40.     public function getName($index) {
  41.         return $this->names[$index];
  42.     }
  43.     //points
  44.     public function addPoint($name) {
  45.         $i=count($this->names);
  46.         $this->names[$i]=$name;
  47.         $this->points[$i]=0;
  48.         return $i;
  49.     }
  50.     public function countPoints() {
  51.         assert(count($this->names)==count($this->points));
  52.         return count($this->points);
  53.     }
  54.     public function pointExists($name) {
  55.         return array_search($name, $this->names, true);
  56.     }
  57.     public function delPoint($name) {
  58.         $i=$this->pointExists($name);
  59.         if($i===false) return false;
  60.         $pos1=array_sum(array_slice($this->points,0,$i));
  61.         $pos2=$this->points[$i];
  62.         $nb=count($this->lines);
  63.         $ar=array_splice($this->lines, $pos1, $pos2);
  64.         assert(count($ar)==$this->points[$i]) or die('delPoint inconsistency');
  65.         $this->points[$i]=0;
  66.         foreach($this->points as $k=>$v) {
  67.             $this->delLine($this->getName($k), $name);//easyness
  68.         }
  69.         unset($this->names[$i]);
  70.         unset($this->points[$i]);
  71.     }
  72.     //lines
  73.     public function addLine($src, $dst) {
  74.         $s=$this->pointExists($src);
  75.         $d=$this->pointExists($dst);
  76.         if($s===false || $d===false) return false;
  77.         $pos1=array_sum(array_slice($this->points,0,$s));
  78.         $pos2=$this->points[$s];
  79.         //throw new Exception('not yet implemented.');
  80.         $begin=array_slice($this->lines, 0, $pos1);
  81.         $ext=array_slice($this->lines, $pos1, $pos2);
  82.         $end=array_slice($this->lines, $pos1+$pos2);
  83.         assert(array_merge($begin,$ext,$end)===$this->lines) or die('addLine inconsistency');
  84.         $ext[]=$d;
  85.         $ext=array_unique($ext);
  86.         sort($ext);
  87.         $this->lines=array_merge($begin,$ext,$end);
  88.         $this->points[$s]=count($ext);
  89.         return true;
  90.     }
  91.     public function countLines() {
  92.         return count($this->lines);
  93.     }
  94.     public function lineExists($src, $dst) {
  95.         $s=$this->pointExists($src);
  96.         $d=$this->pointExists($dst);
  97.         if($s===false || $d===false) return false;
  98.         $pos1=array_sum(array_slice($this->points,$s));
  99.         $pos2=$pos1+$this->points[$s];
  100.         for($i=$pos1;$i<$pos2;$i++) {
  101.             if($this->lines[$i]==$d) return true;
  102.         }
  103.         return false;
  104.     }
  105.     public function delLine($src, $dst) {
  106.         $s=$this->pointExists($src);
  107.         $d=$this->pointExists($dst);
  108.         if($s===false || $d===false) return false;
  109.         $pos1=array_sum(array_slice($this->points,0,$s));
  110.         $pos2=$this->points[$s];
  111.         //throw new Exception('not yet implemented.');
  112.         $begin=array_slice($this->lines, 0, $pos1);
  113.         $ext=array_slice($this->lines, $pos1, $pos2);
  114.         $end=array_slice($this->lines, $pos1+$pos2);
  115.         assert(array_merge($begin,$ext,$end)===$this->lines) or die('delLine inconsistency');
  116.         $pos=array_search($d, $ext);
  117.         if($pos===false) return false;
  118.         $ar=array_splice($ext, $pos, 1);
  119.         assert($ar==array($d)) or die('delLine removal inconsistency');
  120.         $ext=array_unique($ext);
  121.         sort($ext);
  122.         $this->lines=array_merge($begin,$ext,$end);
  123.         $this->points[$s]=count($ext);
  124.         return true;
  125.     }
  126.     //browsing
  127.     public function listLinesFrom($src) {
  128.         $s=$this->pointExists($src);
  129.         if($s===false) return false;
  130.         $pos1=array_sum(array_splice_INV($this->points,$s));
  131.         $pos2=$this->points[$s];
  132.         return array_slice(array_slice($this->points, 0, $pos1),$pos2);
  133.     }
  134.     public function listLinesTo($dst) {
  135.         $d=$this->pointExists($dst);
  136.         $res=array();
  137.         $j=0;
  138.         $k=0;
  139.         for($i=0;$i<count($this->points);$i++) {
  140.             $n=$this->points[$i];
  141.             $k+=$n;
  142.             for(;$j<$k;$j++) {
  143.                 if($this->lines[$j]==$d) {
  144.                     $res[]=$i;
  145.                     break;
  146.                 }
  147.             }
  148.         }
  149.         return $res;
  150.     }
  151.     //starts and ends
  152.     public function listSources() {
  153.         $res=array();
  154.         for($i=0;$i<count($this->points);$i++) {
  155.             if(array_search($i, $this->lines, true)===false) $res[]=$i;
  156.         }
  157.         return $res;
  158.     }
  159.     public function listSinks() {
  160.         $res=array();
  161.         for($i=0;$i<count($this->points);$i++) {
  162.             if($this->points[$i]==0) $res[]=$i;
  163.         }
  164.         return $res;
  165.     }
  166. };
  167. $graph=new AdjencyList();
  168. $graph->addPoint('A');
  169. $graph->addPoint('B');
  170. $graph->addPoint('C');
  171. $graph->addLine('A','B');
  172. $graph->addLine('B','C');
  173. $graph->addLine('C','A');
  174. $graph->addLine('C','B');
  175. $graph->addLine('A','C');
  176. $graph->addLine('B','A');
  177. $graph->dump();
  178. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement