Permalink
Browse files

Update to use Bron-Kerbosch algorithm

  • Loading branch information...
Michael Dombrowski Michael Dombrowski
Michael Dombrowski authored and Michael Dombrowski committed Oct 25, 2017
1 parent 1d2f661 commit 9102865b320d16a431ec98a109d8e43a363849a2
Showing with 89 additions and 17 deletions.
  1. +21 −16 src/classes/ScheduleGenerate.php
  2. +66 −0 src/classes/ScheduleGenerateBronKerbosch.php
  3. +2 −1 src/newSched.php
@@ -2,15 +2,15 @@
class ScheduleGenerate {
/** @var Ingest $ingest */
private $ingest;
protected $ingest;
/** @var \LimitedMinHeap $schedules */
private $schedules;
protected $schedules;
/** @var int $numSchedules */
private $numSchedules = 0;
protected $numSchedules = 0;
/** @var int $sectionCount */
private $sectionCount = 0;
protected $sectionCount = 0;
/** @var array $conflictMatrix sparse boolean matrix true if a conflict exists */
private $conflictMatrix = [];
protected $conflictMatrix = [];
/**
* ScheduleGenerate constructor.
@@ -29,7 +29,6 @@ public function __construct(Ingest $ingest){
*/
public function generateSchedules($allSections){
$this->sectionCount = count($allSections);
foreach($allSections as $k => $v){
unset($allSections[$k]);
if(!isset($v->meetingTime)){
@@ -39,20 +38,26 @@ public function generateSchedules($allSections){
}
}
private function conflictMatrixLookup(\Section $a, \Section $b){
if(!isset($this->conflictMatrix[$a->getId()]) || !isset($this->conflictMatrix[$a->getId()][$b->getId()])){
if(!isset($this->conflictMatrix[$a->getId()])){
$this->conflictMatrix[$a->getId()] = [];
$this->conflictMatrix[$b->getId()] = [];
protected function sectionsAreCompatible(\Section $a, \Section $b){
$aId = $a->getId();
$bId = $b->getId();
if($aId == $bId){
return false;
}
if(!isset($this->conflictMatrix[$aId]) || !isset($this->conflictMatrix[$aId][$bId])){
if(!isset($this->conflictMatrix[$aId])){
$this->conflictMatrix[$aId] = [];
$this->conflictMatrix[$bId] = [];
}
$conflictStatus = !$a->conflictsWith($b);
// Put it in both ways because there is a reciprocal relationship
$this->conflictMatrix[$a->getId()][$b->getId()] = $conflictStatus;
$this->conflictMatrix[$b->getId()][$a->getId()] = $conflictStatus;
$this->conflictMatrix[$aId][$bId] = $conflictStatus;
$this->conflictMatrix[$bId][$aId] = $conflictStatus;
}
return $this->conflictMatrix[$a->getId()][$b->getId()];
return $this->conflictMatrix[$aId][$bId];
}
/**
@@ -66,8 +71,8 @@ private function run($sections, $pick, $curr = []){
$curr[] = $pick;
$temp = $sections;
$temp = array_filter($temp, function($v) use($pick){
return $this->conflictMatrixLookup($v, $pick);
$temp = array_filter($temp, function(Section $v) use($pick){
return $this->sectionsAreCompatible($v, $pick);
});
if(count($temp) == 0){
@@ -0,0 +1,66 @@
<?php
class ScheduleGenerateBronKerbosch extends \ScheduleGenerate {
private $allSections;
private $neighborSections;
public function generateSchedules($allSections){
$this->sectionCount = count($allSections);
$sectionIDs = [];
foreach($allSections as $s){
/** @var $s \Section */
$sectionIDs[] = $s->getId();
$this->allSections[$s->getId()] = $s;
}
$this->run([], $sectionIDs, []);
}
private function neighborMemoizer($sId){
if(!isset($this->neighborSections[$sId])){
$neighbors = array_map(
function(Section $i){
return $i->getId();
},
array_filter($this->allSections,
function(Section $s) use ($sId){
return $this->sectionsAreCompatible($this->allSections[$sId], $s);
}
)
);
$this->neighborSections[$sId] = $neighbors;
}
return $this->neighborSections[$sId];
}
private function run(array $r, array $p, array $x){
if(empty($p) && empty($x)){
$requiredCourses = 0;
$a = new Schedule();
foreach($r as $b){
$b = $this->allSections[$b];
/** @var $b \Section */
if($b->isRequiredCourse()){
$requiredCourses++;
}
$a->addSection($b);
}
if($requiredCourses == $this->ingest->getRequiredCourseNum()){
$a->setScore($this->ingest->getMorning());
$this->schedules->insert($a);
$this->numSchedules++;
}
}
foreach($p as $v){
$neighbors = $this->neighborMemoizer($v);
$this->run(array_merge($r, [$v]), array_intersect($p, $neighbors), array_intersect($x, $neighbors));
$p = array_diff($p, [$v]);
$x = array_values(array_merge($x, [$v]));
}
}
}
@@ -35,7 +35,8 @@
$ingest = new Ingest(new MySQLDAL($link), urldecode($_GET["i"]));
$ingest->generateSections();
$scheduleGenerator = new ScheduleGenerate($ingest);
$scheduleGenerator = new ScheduleGenerateBronKerbosch($ingest);
$scheduleGenerator->generateSchedules($ingest->getAllSections());
$numSchedules = $scheduleGenerator->getNumSchedules();

0 comments on commit 9102865

Please sign in to comment.