From 0cda517f986ec368afd33e64cce782670c6a7eb2 Mon Sep 17 00:00:00 2001 From: Timothy Middelkoop Date: Sun, 6 Apr 2014 16:39:26 -0500 Subject: [PATCH 01/12] Week 10 Solutions. --- Web/os.php | 11 +++ Web/osTest.php | 27 +++++++ Web/osbasic.php | 204 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 242 insertions(+) create mode 100644 Web/os.php create mode 100644 Web/osTest.php create mode 100644 Web/osbasic.php diff --git a/Web/os.php b/Web/os.php new file mode 100644 index 0000000..7951d14 --- /dev/null +++ b/Web/os.php @@ -0,0 +1,11 @@ +"; + } +} + + +?> diff --git a/Web/osTest.php b/Web/osTest.php new file mode 100644 index 0000000..9d6413e --- /dev/null +++ b/Web/osTest.php @@ -0,0 +1,27 @@ + + + $os=new OS(); + $this->assertEquals("",$os->osil()); + } + +} + + +if (!defined('PHPUnit_MAIN_METHOD')) { + WebOSTestCase::main(); +} +?> diff --git a/Web/osbasic.php b/Web/osbasic.php new file mode 100644 index 0000000..dd21496 --- /dev/null +++ b/Web/osbasic.php @@ -0,0 +1,204 @@ + +// SimpleXMLElement is a class, look at the asXML method to return the string. +// Use the XML heredoc for the expected result + +function osil() { + $xml=new SimpleXMLElement(''); + return $xml->asXML(); +} + +$xml=<< + + +XML; + +assertEquals($xml,osil()); + +// Problem 6: Write assertContainsString($needle,$haystack) + +function assertContainsString($needle,$haystack){ + if(strpos($haystack,$needle)===FALSE){ + $message="assertContainsString: |$needle|$haystack|"; + throw new Exception($message); + } +} + +assertContainsString('Needle','HayStack Needle Hay Hay'); +$failed=FALSE; +try { + assertContainsString('Needle','All hay'); // Fails +} catch (Exception $e) { + $failed=TRUE; +} +assert($failed); + +// Problem 7: The haystack can be an array of strings + +function assertContains($needle,$haystack){ + if(is_string($haystack)){ + return assertContainsString($needle,$haystack); + } + foreach($haystack as $hay) + if(strpos($hay,$needle)!==FALSE){ + return; + } + $message="assertContains: |$needle|$haystack|"; + throw new Exception($message); +} + +assertContains('Needle',array('HayStack Needle Hay Hay','Hay')); + + +// Problem 7: Run "OSSolverService -h" make sure it returns 0 and contains the string "OS Version: 2." +// use the exec function +// The program in ..\\..\\..\\bin\\OSSolverService.exe + +// Make sure to test failure first. + +exec("..\\..\\..\\bin\\OSSolverService.exe -h",$output,$result); +//print_r($output); +assertEquals(0,$result); +assertContains("OS Version: 2.",$output); + +// Problem 8: Save the xml to test.xml and read it back to test it. +// reimplement osil() as a write() function. +// read + +function write($file) { + $xml=new SimpleXMLElement(''); + return $xml->asXML($file); +} + +write("test.xml"); +$xml=file_get_contents("test.xml"); +// print_r($xml); +assertContains('',$xml); + +// Problem 9: Create a function solve() "OSSolverService -osil test.xml" that throws an exception on failure +// Assume test.xml is there. +// Our problem should return a result of nonzero since it is not well formed. +// Actually it crashes. + +function solve(){ + exec("..\\..\\..\\bin\\OSSolverService.exe -osil test.xml -osrl solution.xml",$output,$result); + //print_r($output); + if($result!==0){ + $message="solve: error $result\n".implode("\n",$output); + throw new Exception($message); + } +} + +$failed=FALSE; +try { + solve(); +} catch (Exception $e){ + //print $e; + $failed=TRUE; +}; +assert($failed); + +// Problem 10: +// Generate a minimal osil document and solve() it +// + +$xml=new SimpleXMLElement(''); +$xml->addChild('instanceHeader'); +$xml->addChild('instanceData')->addChild('objectives')->addChild('obj')->addAttribute('numberOfObjCoef',0); + +//print $xml->asXML(); +$xml->asXML('test.xml'); +solve(); + +// Problem 11: +// Detect an error and report it. + +// Problem 12: Verify the minimal solution() status is "optimal" and 0, return FALSE if not optimal. +// write the output in solve() to soution.xml with the "-osrl solution.xml" switch +// parse it with simplexml_load_file +// print_r is your friend. +// You must also often cast and simpleXMLElement to a string "(string)" + +function solution(){ + solve(); + $osil=simplexml_load_file('solution.xml'); + //print_r($osil->optimization); + $result=(string)$osil->optimization->solution->status->attributes()->type; + if($result!=='optimal'){ + return FALSE; + } + return (int)(string)$osil->optimization->solution->objectives->values->obj; +} + +assert(solution()===0); + +echo "done.\n" + +?> From a6eb72b7df7d64f6e3d70bdc19bf1248939d5366 Mon Sep 17 00:00:00 2001 From: Timothy Middelkoop Date: Sun, 6 Apr 2014 17:09:50 -0500 Subject: [PATCH 02/12] Week 11 Problem 13, solve osil with SimpleXMLElement. --- Web/osbasic.php | 46 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/Web/osbasic.php b/Web/osbasic.php index dd21496..d392819 100644 --- a/Web/osbasic.php +++ b/Web/osbasic.php @@ -188,16 +188,54 @@ function solve(){ function solution(){ solve(); - $osil=simplexml_load_file('solution.xml'); + $osrl=simplexml_load_file('solution.xml'); //print_r($osil->optimization); - $result=(string)$osil->optimization->solution->status->attributes()->type; + $result=(string)$osrl->optimization->solution->status->attributes()->type; if($result!=='optimal'){ return FALSE; } - return (int)(string)$osil->optimization->solution->objectives->values->obj; + return (int)$osrl->optimization->solution->objectives->values->obj; } -assert(solution()===0); +//assert(solution()===0); + +// A bit troublesome since it generates warnings +// Not all that useful as well. + +// Problem 13: Refactor solve and solution and fix warnings. Call it solveOsil() +// This generates a warning, the XML emitted is non-conforming, fix. +// The xmlns needs a proper "uri" so we add http:// to the xmlns string. +// New function takes an SimpleXMLElement and returns the solution. +// Write the file to a temporary file using tempnam() in ..\\..\\..\\tmp +// get a file into a string with get_file_contents +// use preg_replace to alter the file. +// remove the files with unlink() when done. + +function solveOsil(SimpleXMLElement $osil){ + $osilfile=tempnam('..\\..\\..\\tmp','OS-'); + $osrlfile=tempnam('..\\..\\..\\tmp','OS-'); + $osil->asXML($osilfile); + exec("..\\..\\..\\bin\\OSSolverService.exe -osil $osilfile -osrl $osrlfile",$output,$result); + //print_r($output); + if($result!==0){ + $message="solve: error $result\n".implode("\n",$output); + throw new Exception($message); + } + $xml=file_get_contents($osrlfile); + //unlink($osilfile); + //unlink($osrlfile); + $xml=preg_replace('/"os.optimizationservices.org"/','"http://os.optimizationservices.org"',$xml); + $osrl=new SimpleXMLElement($xml); + //print_r($osrl->optimization); + $result=(string)$osrl->optimization->solution->status->attributes()->type; + if($result!=='optimal'){ + return FALSE; + } + return (int)$osrl->optimization->solution->objectives->values->obj; +} + +assert(solveOsil($xml)===0); + echo "done.\n" From 008a4aed6b3123c732d3d133289da6a130d82720 Mon Sep 17 00:00:00 2001 From: Timothy Middelkoop Date: Sun, 6 Apr 2014 17:10:41 -0500 Subject: [PATCH 03/12] Ignore test files. --- Web/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Web/.gitignore diff --git a/Web/.gitignore b/Web/.gitignore new file mode 100644 index 0000000..34f73a0 --- /dev/null +++ b/Web/.gitignore @@ -0,0 +1,2 @@ +/solution.xml +/test.xml From 41cfc31d5554b5724c57d45e6e8fb65de2a045ff Mon Sep 17 00:00:00 2001 From: Timothy Middelkoop Date: Sun, 6 Apr 2014 18:03:34 -0500 Subject: [PATCH 04/12] Week 11 OSSolverService work. --- Web/osbasic.php | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/Web/osbasic.php b/Web/osbasic.php index d392819..a93e605 100644 --- a/Web/osbasic.php +++ b/Web/osbasic.php @@ -197,12 +197,12 @@ function solution(){ return (int)$osrl->optimization->solution->objectives->values->obj; } -//assert(solution()===0); +//assertEquals(0,solution()); // A bit troublesome since it generates warnings // Not all that useful as well. -// Problem 13: Refactor solve and solution and fix warnings. Call it solveOsil() +// Problem 13: Refactor solve and solution and fix warnings. Call it solveProblem() // This generates a warning, the XML emitted is non-conforming, fix. // The xmlns needs a proper "uri" so we add http:// to the xmlns string. // New function takes an SimpleXMLElement and returns the solution. @@ -211,7 +211,7 @@ function solution(){ // use preg_replace to alter the file. // remove the files with unlink() when done. -function solveOsil(SimpleXMLElement $osil){ +function solveProblem(SimpleXMLElement $osil){ $osilfile=tempnam('..\\..\\..\\tmp','OS-'); $osrlfile=tempnam('..\\..\\..\\tmp','OS-'); $osil->asXML($osilfile); @@ -222,9 +222,16 @@ function solveOsil(SimpleXMLElement $osil){ throw new Exception($message); } $xml=file_get_contents($osrlfile); + if($xml==FALSE){ + return FALSE; + } + if(strpos($xml,'')!==FALSE){ + throw new Exception("solve: error in OSrL:".$xml); + } //unlink($osilfile); //unlink($osrlfile); $xml=preg_replace('/"os.optimizationservices.org"/','"http://os.optimizationservices.org"',$xml); + //print_r($xml); $osrl=new SimpleXMLElement($xml); //print_r($osrl->optimization); $result=(string)$osrl->optimization->solution->status->attributes()->type; @@ -234,8 +241,40 @@ function solveOsil(SimpleXMLElement $osil){ return (int)$osrl->optimization->solution->objectives->values->obj; } -assert(solveOsil($xml)===0); +assertEquals(0,solveProblem($xml)); + +// Problem 14: Create a template SimpleXMLElement in order to easily construct problems. +// Creating a function to generate a template called emptyProblem() +// be sure to include the instanceHeader->name element (populate it with the date) +// You can "chain" elements in $xml->addChild('foo')->addChild('bar') +// You can find the template in Test/osTest.php +// Don't include any namespace (xmlns) material, OSSolverService does not care. +// Debug with print_r($xml) +// Errors do not produce well formed XML. Detect this in your solveProblem function. +// For TDD simply test non zero: assert(emptyProblem()) will be tested in the next problem. + +function emptyProblem(){ + $xml=new SimpleXMLElement(''); + $xml->addChild('instanceHeader')->addChild('name'); + $data=$xml->addChild('instanceData'); + $data->addChild('objectives')->addChild('obj')->addAttribute('numberOfObjCoef',0); + $data->addChild('constraints')->addAttribute('numberOfConstraints',0); + $constraints=$data->addChild('linearConstraintCoefficients'); + $constraints->addAttribute('numberOfValues',0); + $constraints->addChild('start')->addChild('el'); + $constraints->addChild('colIdx'); + $constraints->addChild('value'); + //print_r($xml); + return $xml; +} + +assert(emptyProblem()); + +// Problem 15: Solve the homework problem by passing a SimpleXMLElement to solveOsil(). +// Start with emptyProblem() +// test against your minimal problem +// Problem 16: Generalize and implement as a class. echo "done.\n" From 72a2a71cba762b37eaad7a4aafd4fcab282a5222 Mon Sep 17 00:00:00 2001 From: Timothy Middelkoop Date: Sun, 20 Apr 2014 09:53:01 -0500 Subject: [PATCH 05/12] Basic assignment problem setup. --- Web/modelbasic.php | 110 +++++++++++++++++++++++++++++++++++++++++++++ Web/tdd.php | 37 +++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 Web/modelbasic.php create mode 100644 Web/tdd.php diff --git a/Web/modelbasic.php b/Web/modelbasic.php new file mode 100644 index 0000000..46b8d4b --- /dev/null +++ b/Web/modelbasic.php @@ -0,0 +1,110 @@ +product=$product; + $this->cell=$cell; + $this->hours=$hours; + } +} + +$demand=array(); +foreach($product as $p){ + $demand[]=new Demand($p,$cell[array_rand($cell)],rand(10,30)); +} + +assertEquals($products,sizeof($demand)); +//print_r($demand); + +// B2: Create training matrix class to hold worker/cell productivity +// If a worker/cell does not exist return a default value. +// access with set(worker,cell,productivity) and get(...) +// Use an array with the key as a string. + +class Training { + private $default=0.80; + private $matrix=array(); + function set($worker,$cell,$productivity){ + $this->matrix["${worker}_${cell}"]=$productivity; + } + function get($worker,$cell){ + if(array_key_exists("${worker}_${cell}",$this->matrix)){ + return $this->matrix["${worker}_${cell}"]; + } + return $this->default; + } +} + +$training=new Training; + +// B2.1 Use TDD to check get/set +assertEquals(0.80,$training->get('worker-1','cell-1')); +$training->set('worker-1','cell-1',0.99); +assertEquals(0.99,$training->get('worker-1','cell-1')); + +// B3: Populate training with a number of random trainings +for($i=0;$i<20;$i++){ + $training->set($worker[array_rand($worker)],$cell[array_rand($cell)],rand(70,100)/100.0); +} +//print_r($training); + + + +echo "\ndone\n"; +?> diff --git a/Web/tdd.php b/Web/tdd.php new file mode 100644 index 0000000..747e447 --- /dev/null +++ b/Web/tdd.php @@ -0,0 +1,37 @@ + From 976973b9daa0d1893c0fbe96eda27330725e71dd Mon Sep 17 00:00:00 2001 From: Timothy Middelkoop Date: Sun, 20 Apr 2014 12:35:39 -0500 Subject: [PATCH 06/12] Split solution result out of solve, now must call getSolution(). --- WCS/os.php | 17 ++++++++++------- WCS/osTest.php | 18 +++++++++++------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/WCS/os.php b/WCS/os.php index e9a4abb..10cba79 100644 --- a/WCS/os.php +++ b/WCS/os.php @@ -6,13 +6,14 @@ class OS { static $DEBUG=FALSE; static $solver="\\WebIS\\bin\OSSolverService.exe"; static $tmp="\\WebIS\\tmp\\"; // trailing slash required. - + private $linear=FALSE; + private $osil=NULL; private $osrl=NULL; private $var=array(); // Reverse IDX mapping ($idx->$name). private $value=NULL; // Solution value. + private $solution=NULL; - private $linear=FALSE; function __construct($maxOrMin='min') { $osil=new \SimpleXMLElement(''); @@ -42,7 +43,7 @@ function getName(){ return (string)$this->osrl->general->instanceName; } - function addVariable($name,$type=null){ + function addVariable($name,$type=NULL){ $variables=$this->osil->instanceData->variables; // shortcut $this->var[$name]=$variables->var->count(); // $name to $idx (zero based -- preinsert) $var=$variables->addChild('var'); @@ -72,7 +73,7 @@ function addObjCoef($name,$value){ $obj['numberOfObjCoef']=$obj->coef->count(); } - function addConstraint($ub=null,$lb=null){ + function addConstraint($lb,$ub){ $constraints=$this->osil->instanceData->constraints; $con=$constraints->addChild('con'); if(!is_null($lb)){ @@ -135,7 +136,8 @@ function solve(){ $this->osrl=new \SimpleXMLElement($xml); $result=(string)$this->osrl->optimization->solution->status->attributes()->type; if($result!=='optimal'){ - return FALSE; + $this->solution=NULL; + return $result; } // save values to array @@ -148,11 +150,12 @@ function solve(){ if(self::$DEBUG) print (float)$var."\n"; } - return (double)$this->osrl->optimization->solution->objectives->values->obj; + $this->solution=(double)$this->osrl->optimization->solution->objectives->values->obj; + return TRUE; } function getSolution(){ - return (double)$solution->objectives->values->obj; + return $this->solution; } } diff --git a/WCS/osTest.php b/WCS/osTest.php index 5578f9c..40c562b 100644 --- a/WCS/osTest.php +++ b/WCS/osTest.php @@ -18,29 +18,33 @@ function testOS() { function testSolver(){ $os=new WebIS\OS(); - $this->assertEquals(0.0,$os->solve(),"Solve empty problem"); + $this->assertTrue($os->solve(),"Solve empty problem"); + $this->assertEquals(0.0,$os->getSolution(),"Solution to empty problem is 0.0"); $this->assertContains(date('Y-m-d'),$os->getName(),"Solved today"); $os->addVariable('x1'); - $this->assertEquals(0.0,$os->solve(),"Solve problem with only one variable"); + $this->assertTrue($os->solve(),"Solve problem with only one variable"); + $this->assertEquals(0.0,$os->getSolution(),"Solution to one variable is 0.0"); $this->assertEquals(0.0,$os->getVariable('x1'),"x1 is zero"); $os->addObjCoef('x1', '-1'); - $this->assertEquals(0.0,$os->solve()); + $this->assertEquals("unbounded",$os->solve(),"Problem is unbounded"); + $this->assertEquals(0.0,$os->getSolution()); $os->addVariable('x2'); $os->addObjCoef('x2', '-2'); - $os->addConstraint(40); + $os->addConstraint(NULL,40); $os->addConstraintCoef('x1',1); $os->addConstraintCoef('x2',1); - $os->addConstraint(60); + $os->addConstraint(NULL,60); $os->addConstraintCoef('x1',2); $os->addConstraintCoef('x2',1); - $this->assertEquals(-80.0,$os->solve()); + $this->assertTrue($os->solve()); + $this->assertEquals(-80.0,$os->getSolution()); $this->assertEquals(0,$os->getVariable('x1')); $this->assertEquals(40,$os->getVariable('x2')); ## test LB $os=new WebIS\OS(); $os->addVariable('x1'); - $os->addConstraint(NULL,40); + $os->addConstraint(40,NULL); $this->assertContains('lb=',$os->getOsil()); } From f8d82558bac6a6d5d7899fc523397a415b209e05 Mon Sep 17 00:00:00 2001 From: Timothy Middelkoop Date: Sun, 20 Apr 2014 12:36:20 -0500 Subject: [PATCH 07/12] Solve simple resource allocation problem. --- Web/modelbasic.php | 138 ++++++++++++++++++++++++++++++++++++++++++--- Web/tdd.php | 11 +++- 2 files changed, 141 insertions(+), 8 deletions(-) diff --git a/Web/modelbasic.php b/Web/modelbasic.php index 46b8d4b..985baa4 100644 --- a/Web/modelbasic.php +++ b/Web/modelbasic.php @@ -1,6 +1,6 @@ modelbasic.php\n"; // Problem: Maximize productivity in a work-cell line. // Workers are assigned a productivity score for each work-cell. @@ -11,8 +11,11 @@ // A1: Use TDD functions from osbasic and store in tdd.php // Use TDD from osbasic and place in tdd.php +require_once 'Work-Cell-Scheduler/WCS/os.php'; require_once 'tdd.php'; assertEquals(TRUE,TRUE); +assertTrue(TRUE); +assertFalse(FALSE); // B: Setup problem and data structures. @@ -52,6 +55,7 @@ } // B1: Create demand using a structure/class that holds (product,cell,hours). +// Hours is between 1 and 3 hours: rand(1,3) class Demand { public $product=NULL; @@ -66,19 +70,20 @@ function __construct($product,$cell,$hours){ $demand=array(); foreach($product as $p){ - $demand[]=new Demand($p,$cell[array_rand($cell)],rand(10,30)); + $demand[]=new Demand($p,$cell[array_rand($cell)],rand(1,3)); } assertEquals($products,sizeof($demand)); //print_r($demand); // B2: Create training matrix class to hold worker/cell productivity -// If a worker/cell does not exist return a default value. +// If a worker/cell does not exist return a default value (which could be FALSE). // access with set(worker,cell,productivity) and get(...) -// Use an array with the key as a string. +// Use an array with the key as a string, join elements with the underscore symbol ('_') +// Note in the "" syntax use the form ${worker} instead of $worker. class Training { - private $default=0.80; + private $default=FALSE; private $matrix=array(); function set($worker,$cell,$productivity){ $this->matrix["${worker}_${cell}"]=$productivity; @@ -94,17 +99,136 @@ function get($worker,$cell){ $training=new Training; // B2.1 Use TDD to check get/set -assertEquals(0.80,$training->get('worker-1','cell-1')); + +assertEquals(FALSE,$training->get('worker-1','cell-1')); $training->set('worker-1','cell-1',0.99); assertEquals(0.99,$training->get('worker-1','cell-1')); // B3: Populate training with a number of random trainings + for($i=0;$i<20;$i++){ $training->set($worker[array_rand($worker)],$cell[array_rand($cell)],rand(70,100)/100.0); } //print_r($training); +// C: Optimization + +// C0: Solve empty problem. +$os=new \WebIS\OS; +assertTrue($os->solve()); + +// C1: Setup objective function, minimize worker hours on each cell +foreach($worker as $w){ + foreach($cell as $c){ + $var="${w}_${c}"; + $os->addVariable($var); + $os->addObjCoef($var,1); + } +} + +assertTrue($os->solve()); +//print_r($os); + +// C2: build production requirement, +// How much work is required on each cell. +// Calculate total production hours (used to check later). + +$celltotal=array(); +foreach($cell as $c){ + $celltotal[$c]=0.0; +} +foreach($demand as $d){ + $celltotal[$d->cell]+=$d->hours; +} +//print_r($celltotal); + +$required=0.0; +foreach($celltotal as $c=>$v){ + $required+=$v; +} +assertTrue($required>0.0); +//print_r("total: $required\n"); + + +// C3: Generate constraints off this (note OS changed to $ub,$lb and made required) and solve. +// Multiply the hours worked by productivity to get the amount of hours that are needed to work +// to fulfill the requirements. +// If there is no training do not include in problem. + +foreach($celltotal as $c=>$lb){ + $os->addConstraint($lb,NULL); + foreach($worker as $w){ + $var="${w}_${c}"; + $val=$training->get($w,$c); + if($val!==FALSE){ + $os->addConstraintCoef("${w}_${c}",$val); + } + } +} + +assertTrue($os->solve()); +$solution=$os->getSolution(); +//print_r("solution: $solution\n"); + +// C4: check that the total hours allocated is at least the total required. + +$worked=0.0; +foreach($worker as $w){ + foreach($cell as $c){ + $var="${w}_${c}"; + $val=$os->getVariable($var); + $worked+=$val; + } +} + +assertTrue($worked>=$required); + +// C5: Cap worker hours to 8 a day. + +foreach($worker as $w){ + $os->addConstraint(NULL,8); + foreach($cell as $c){ + $var="${w}_${c}"; + $val=$training->get($w,$c); + if($val!==FALSE){ + $os->addConstraintCoef("${w}_${c}",1); + } + + } +} + +assertTrue($os->solve()); +$solution=$os->getSolution(); +//print_r("solution: $solution\n"); + +// D: Verify solution. + +// D1: Dump solution to a html table (readable in the console as well), and verify solution by hand. +// include productivity and product. +// Worker as rows, cells as columns. + +echo ""; +} +foreach($worker as $w){ + echo ""; + } + echo "\n"; +} +echo ""; +foreach($celltotal as $ct){ + echo ""; +} +echo "
\n"; +foreach($cell as $c){ + echo "$c
${w}: "; + foreach($cell as $c){ + $var="${w}_${c}"; + $val=$os->getVariable($var); + $t=$training->get($w,$c); + echo "$val $t ".$val*$t."
Total$ct
"; + -echo "\ndone\n"; +// Done +echo "\n\n"; ?> diff --git a/Web/tdd.php b/Web/tdd.php index 747e447..3783c35 100644 --- a/Web/tdd.php +++ b/Web/tdd.php @@ -10,7 +10,7 @@ function assertEquals($expected,$result) { function assertNotEquals($expected,$result) { if(($expected===$result)){ - $message="assertNoeEquals: |$expected|$result|\n"; + $message="assertNotEquals: |$expected|$result|\n"; throw new Exception($message); } } @@ -34,4 +34,13 @@ function assertContains($needle,$haystack){ throw new Exception($message); } +function assertTrue($result){ + return assertEquals(TRUE,$result); +} + +function assertFalse($result){ + return assertEquals(FALSE,$result); +} + + ?> From 4c2c0b3b43cb4e4df95cd91d85c06fdf1ca40534 Mon Sep 17 00:00:00 2001 From: Timothy Middelkoop Date: Sun, 20 Apr 2014 13:57:28 -0500 Subject: [PATCH 08/12] Refactor into a class. --- Web/modelbasic.php | 4 +- Web/problembasic.php | 277 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 Web/problembasic.php diff --git a/Web/modelbasic.php b/Web/modelbasic.php index 985baa4..afd2ef6 100644 --- a/Web/modelbasic.php +++ b/Web/modelbasic.php @@ -226,7 +226,9 @@ function get($worker,$cell){ foreach($celltotal as $ct){ echo "$ct"; } -echo ""; +echo ""; + +echo "\n"; // Done diff --git a/Web/problembasic.php b/Web/problembasic.php new file mode 100644 index 0000000..28125b7 --- /dev/null +++ b/Web/problembasic.php @@ -0,0 +1,277 @@ +problembasic.php\n"; +require_once 'Work-Cell-Scheduler/WCS/os.php'; +require_once 'tdd.php'; + +// E: Refactor modelbasic.php to problembasic.php. +// Make the problem a class so that it can be replaced by a Business Object backed by a database at some point. + +class SimpleProblem { + + // E1 + private $workers=5; + private $cells=4; + private $products=6; + + // E4 + /** + * Solver + * @var \WebIS\OS + */ + private $os=NULL; + + // E1 + function loadProblem($workers,$cells,$products){ + $this->workers=$workers; + $this->cells=$cells; + $this->products=$products; + + $worker=array(); + for($i=0;$i<$workers;$i++){ + $worker[]="worker-${i}"; + } + $this->worker=$worker; + + $cell=array(); + for($i=0;$i<$cells;$i++){ + $cell[]="cell-${i}"; + } + $this->cell=$cell; + + $product=array(); + for($i=0;$i<$products;$i++){ + $product[]="product-${i}"; + } + $this->product=$product; + } + + // E2 + function loadDemand(){ + $demand=array(); + foreach($this->product as $p){ + $c=$this->cell[array_rand($this->cell)]; + $d=rand(1,3); + $var="${p}_${c}"; + $demand[$var]=new Demand($p,$c,$d); + } + $this->demand=$demand; + } + + // E3 + function loadTraining() { + $training=new Training; + for($i=0;$i<20;$i++){ + $training->set($this->worker[array_rand($this->worker)],$this->cell[array_rand($this->cell)],rand(70,100)/100.0); + } + $this->training=$training; + } + + // E4 + function calculate() { + $celltotal=array(); + foreach($this->cell as $c){ + $celltotal[$c]=0.0; + } + foreach($this->demand as $var=>$d){ + $celltotal[$d->cell]+=$d->hours; + } + $this->celltotal=$celltotal; + + $required=0.0; + foreach($celltotal as $c=>$v){ + $required+=$v; + } + $this->required=$required; + } + + // E5 + function displayWorkers() { + $output=array(); + $solution=''; + if($this->os){ + $solution=$this->os->getSolution(); + } + $output[]=""; + } + $output[]=""; + } + $output[]=""; + foreach($this->celltotal as $ct){ + $output[]=""; + } + $output[]=""; + + $output[]="\n
$solution\n"; + foreach($this->cell as $c){ + $output[]="$cTotal\n"; + $total=0.0; + foreach($this->worker as $w){ + $output[]="
${w}"; + $hours=0.0; + foreach($this->cell as $c){ + $var="${w}_${c}"; + $t=$this->training->get($w,$c); + if($this->os){ + $val=$this->os->getVariable($var); + $hours+=$val; + $total+=$val*$t; + }else{ + $val=''; + } + $output[]="$val$t".$val*$t; + } + $output[]="$hours
Total$ct$total
\n"; + return implode(" ",$output); + } + + // E6 + function displayProblem() { + $output=array(); + $output[]=""; + } + $output[]=""; + } + $output[]=""; + $total=0.0; + foreach($this->celltotal as $ct){ + $output[]=""; + $total+=$ct; + } + $output[]=""; + + $output[]="\n
\n"; + foreach($this->cell as $c){ + $output[]="$cTotal\n"; + foreach($this->product as $p){ + $output[]="
${p}"; + $total=0.0; + foreach($this->cell as $c){ + $hours=0.0; + $var="${p}_${c}"; + if(array_key_exists($var,$this->demand)){ + $d=$this->demand[$var]; + $hours=$d->hours; + } + $output[]="$hours"; + $total+=$hours; + } + $output[]="$hours
Total$ct$total
\n"; + return implode(" ",$output); + } + + // E7 Solve + function solve(){ + $os=new \WebIS\OS; + + $worker=$this->worker; + $cell=$this->cell; + + // Variables and objective function + foreach($worker as $w){ + foreach($cell as $c){ + $var="${w}_${c}"; + $os->addVariable($var); + $os->addObjCoef($var,1); + } + } + + // Production constraints (use effective hours for productivity) + $celltotal=$this->celltotal; + $training=$this->training; + foreach($celltotal as $c=>$lb){ + $os->addConstraint($lb,NULL); + foreach($worker as $w){ + $var="${w}_${c}"; + $val=$training->get($w,$c); + if($val!==FALSE){ + $os->addConstraintCoef("${w}_${c}",$val); + } + } + } + // Maximum 8 hours per week. + foreach($worker as $w){ + $os->addConstraint(NULL,8); + foreach($cell as $c){ + $var="${w}_${c}"; + $val=$training->get($w,$c); + if($val!==FALSE){ + $os->addConstraintCoef("${w}_${c}",1); + } + } + } + + $this->os=$os; + return $os->solve(); + } + +} + + +class Demand { + // E2 + public $product=NULL; + public $cell=NULL; + public $hours=NULL; + + // E2 + function __construct($product,$cell,$hours){ + $this->product=$product; + $this->cell=$cell; + $this->hours=$hours; + } +} + +class Training { + // E3 + private $default=FALSE; + private $matrix=array(); + + // E3 + function set($worker,$cell,$productivity){ + $this->matrix["${worker}_${cell}"]=$productivity; + } + + // E3 + function get($worker,$cell){ + if(array_key_exists("${worker}_${cell}",$this->matrix)){ + return $this->matrix["${worker}_${cell}"]; + } + return $this->default; + } +} + + +// E1: Use an empty constructor and use a function call loadProblem() with workers,cells, and products +// This function generates the list of workers, cells, and products. +// Store in an associative array with product_cell as key. + +$p=new SimpleProblem; +$p->loadProblem(5,4,6); + +// E2: Refactor demand generation as loadDemand() +$p->loadDemand(); + +// E3: Refactor training generation as loadTraining() +$p->loadTraining(); + +// E4: Refactor Calculate values (cell totals, overall total) with calculate(); +$p->calculate(); + +// E5: Refactor display solution (empty) to verify problem with displayWorkers(); include row and column sum. +//echo $p->displayWorkers(); + +// E6: Create a displayProblem function to show product/cell demand, include row and column sum. +//echo $p->displayProblem(); + +// E7: Refactor solve() and redisplay +// echo "
\n"; +$p->solve(); +echo $p->displayWorkers(); +echo $p->displayProblem(); + +// F: Refactor the "data" out of the class into a $data and $problem. +// G: Replace the generated $data with one supplied by a database $data. + +echo "\n\n"; +?> \ No newline at end of file From ae75625cb3f8b37013b290e843f3494737661eda Mon Sep 17 00:00:00 2001 From: Timothy Middelkoop Date: Sun, 20 Apr 2014 14:08:18 -0500 Subject: [PATCH 09/12] Split Problem into data and model --- Web/problembasic.php | 3 - Web/problemdata.php | 271 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 271 insertions(+), 3 deletions(-) create mode 100644 Web/problemdata.php diff --git a/Web/problembasic.php b/Web/problembasic.php index 28125b7..fb0b46f 100644 --- a/Web/problembasic.php +++ b/Web/problembasic.php @@ -270,8 +270,5 @@ function get($worker,$cell){ echo $p->displayWorkers(); echo $p->displayProblem(); -// F: Refactor the "data" out of the class into a $data and $problem. -// G: Replace the generated $data with one supplied by a database $data. - echo "\n\n"; ?> \ No newline at end of file diff --git a/Web/problemdata.php b/Web/problemdata.php new file mode 100644 index 0000000..c387628 --- /dev/null +++ b/Web/problemdata.php @@ -0,0 +1,271 @@ +problembasic.php\n"; +require_once 'Work-Cell-Scheduler/WCS/os.php'; +require_once 'tdd.php'; + +// F: Refactor the "data" out of the class into a $data and $problem. + +class SimpleProblemData { + + // E1 + private $workers=5; + private $cells=4; + private $products=6; + + // E1 + function loadProblem($workers,$cells,$products){ + $this->workers=$workers; + $this->cells=$cells; + $this->products=$products; + + $worker=array(); + for($i=0;$i<$workers;$i++){ + $worker[]="worker-${i}"; + } + $this->worker=$worker; + + $cell=array(); + for($i=0;$i<$cells;$i++){ + $cell[]="cell-${i}"; + } + $this->cell=$cell; + + $product=array(); + for($i=0;$i<$products;$i++){ + $product[]="product-${i}"; + } + $this->product=$product; + } + + // E2 + function loadDemand(){ + $demand=array(); + foreach($this->product as $p){ + $c=$this->cell[array_rand($this->cell)]; + $d=rand(1,3); + $var="${p}_${c}"; + $demand[$var]=new Demand($p,$c,$d); + } + $this->demand=$demand; + } + + // E3 + function loadTraining() { + $training=new Training; + for($i=0;$i<20;$i++){ + $training->set($this->worker[array_rand($this->worker)],$this->cell[array_rand($this->cell)],rand(70,100)/100.0); + } + $this->training=$training; + } + + // E4 + function calculate() { + $celltotal=array(); + foreach($this->cell as $c){ + $celltotal[$c]=0.0; + } + foreach($this->demand as $var=>$d){ + $celltotal[$d->cell]+=$d->hours; + } + $this->celltotal=$celltotal; + + $required=0.0; + foreach($celltotal as $c=>$v){ + $required+=$v; + } + $this->required=$required; + } + +} + + +class ProblemModel { + + /** + * Solver + * @var \WebIS\OS + */ + private $os=NULL; + private $data=NULL; + + // F + function __construct($data){ + $this->data=$data; + } + + // E5 + function displayWorkers() { + $data=$this->data; + $output=array(); + $solution=''; + if($this->os){ + $solution=$this->os->getSolution(); + } + $output[]=""; + } + $output[]=""; + } + $output[]=""; + foreach($data->celltotal as $ct){ + $output[]=""; + } + $output[]=""; + + $output[]="\n
$solution\n"; + foreach($data->cell as $c){ + $output[]="$cTotal\n"; + $total=0.0; + foreach($data->worker as $w){ + $output[]="
${w}"; + $hours=0.0; + foreach($data->cell as $c){ + $var="${w}_${c}"; + $t=$data->training->get($w,$c); + if($this->os){ + $val=$this->os->getVariable($var); + $hours+=$val; + $total+=$val*$t; + }else{ + $val=''; + } + $output[]="$val$t".$val*$t; + } + $output[]="$hours
Total$ct$total
\n"; + return implode(" ",$output); + } + + // E6 + function displayProblem() { + $data=$this->data; + $output=array(); + $output[]=""; + } + $output[]=""; + } + $output[]=""; + $total=0.0; + foreach($data->celltotal as $ct){ + $output[]=""; + $total+=$ct; + } + $output[]=""; + + $output[]="\n
\n"; + foreach($data->cell as $c){ + $output[]="$cTotal\n"; + foreach($data->product as $p){ + $output[]="
${p}"; + $total=0.0; + foreach($data->cell as $c){ + $hours=0.0; + $var="${p}_${c}"; + if(array_key_exists($var,$data->demand)){ + $d=$data->demand[$var]; + $hours=$d->hours; + } + $output[]="$hours"; + $total+=$hours; + } + $output[]="$hours
Total$ct$total
\n"; + return implode(" ",$output); + } + + // E7 Solve + function solve(){ + $os=new \WebIS\OS; + + $worker=$this->data->worker; + $cell=$this->data->cell; + + // Variables and objective function + foreach($worker as $w){ + foreach($cell as $c){ + $var="${w}_${c}"; + $os->addVariable($var); + $os->addObjCoef($var,1); + } + } + + // Production constraints (use effective hours for productivity) + $celltotal=$this->data->celltotal; + $training=$this->data->training; + foreach($celltotal as $c=>$lb){ + $os->addConstraint($lb,NULL); + foreach($worker as $w){ + $var="${w}_${c}"; + $val=$training->get($w,$c); + if($val!==FALSE){ + $os->addConstraintCoef("${w}_${c}",$val); + } + } + } + // Maximum 8 hours per week. + foreach($worker as $w){ + $os->addConstraint(NULL,8); + foreach($cell as $c){ + $var="${w}_${c}"; + $val=$training->get($w,$c); + if($val!==FALSE){ + $os->addConstraintCoef("${w}_${c}",1); + } + } + } + + $this->os=$os; + return $os->solve(); + } + +} + + +class Demand { + // E2 + public $product=NULL; + public $cell=NULL; + public $hours=NULL; + + // E2 + function __construct($product,$cell,$hours){ + $this->product=$product; + $this->cell=$cell; + $this->hours=$hours; + } +} + +class Training { + // E3 + private $default=FALSE; + private $matrix=array(); + + // E3 + function set($worker,$cell,$productivity){ + $this->matrix["${worker}_${cell}"]=$productivity; + } + + // E3 + function get($worker,$cell){ + if(array_key_exists("${worker}_${cell}",$this->matrix)){ + return $this->matrix["${worker}_${cell}"]; + } + return $this->default; + } +} + + +$d=new SimpleProblemData; +$d->loadProblem(5,4,6); + +$d->loadDemand(); +$d->loadTraining(); +$d->calculate(); + +$m=new ProblemModel($d); +$m->solve(); +echo $m->displayWorkers(); +echo $m->displayProblem(); + +// G: Replace the generated $data with one supplied by a database $data. + +echo "\n\n"; +?> \ No newline at end of file From a5775fab604df1c495885b3f3351824149fe50ae Mon Sep 17 00:00:00 2001 From: Timothy Middelkoop Date: Sun, 20 Apr 2014 14:18:38 -0500 Subject: [PATCH 10/12] Change numbering to match handout. --- Web/modelbasic.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Web/modelbasic.php b/Web/modelbasic.php index afd2ef6..78b2e60 100644 --- a/Web/modelbasic.php +++ b/Web/modelbasic.php @@ -54,7 +54,7 @@ //print_r($w); } -// B1: Create demand using a structure/class that holds (product,cell,hours). +// B3: Create demand using a structure/class that holds (product,cell,hours). // Hours is between 1 and 3 hours: rand(1,3) class Demand { @@ -76,7 +76,7 @@ function __construct($product,$cell,$hours){ assertEquals($products,sizeof($demand)); //print_r($demand); -// B2: Create training matrix class to hold worker/cell productivity +// B4: Create training matrix class to hold worker/cell productivity // If a worker/cell does not exist return a default value (which could be FALSE). // access with set(worker,cell,productivity) and get(...) // Use an array with the key as a string, join elements with the underscore symbol ('_') @@ -98,13 +98,13 @@ function get($worker,$cell){ $training=new Training; -// B2.1 Use TDD to check get/set +// B5: Use TDD to check get/set assertEquals(FALSE,$training->get('worker-1','cell-1')); $training->set('worker-1','cell-1',0.99); assertEquals(0.99,$training->get('worker-1','cell-1')); -// B3: Populate training with a number of random trainings +// B6: Populate training with a number of random trainings for($i=0;$i<20;$i++){ $training->set($worker[array_rand($worker)],$cell[array_rand($cell)],rand(70,100)/100.0); From e6ce64421a6153e2576b09e871cd88db23574052 Mon Sep 17 00:00:00 2001 From: scmmv4 Date: Mon, 12 May 2014 12:18:55 -0500 Subject: [PATCH 11/12] WebIS Final --- Web/Final-partA.php | 108 ++++++++++++++++++++++++++++++++++++++++++++ Web/Final-partB.php | 79 ++++++++++++++++++++++++++++++++ Web/Final.html | 76 +++++++++++++++++++++++++++++++ Web/OSRL.html | 41 +++++++++++++++++ 4 files changed, 304 insertions(+) create mode 100644 Web/Final-partA.php create mode 100644 Web/Final-partB.php create mode 100644 Web/Final.html create mode 100644 Web/OSRL.html diff --git a/Web/Final-partA.php b/Web/Final-partA.php new file mode 100644 index 0000000..7f4f9eb --- /dev/null +++ b/Web/Final-partA.php @@ -0,0 +1,108 @@ +600,'S2'=>300,'S3'=>200); +//$department=array('D1'=>600,'D2'=>200,'D3'=>300); +//$dprofit=array('profit-1'=>20,'profit-2'=>30,'profit-3'=>40); + +$supplier = array (); +$numSupplier = 3; +for($i = 1; $i <= $numSupplier; $i ++) { + $supplier [] = "S" . $i; +} + +$numDepart = 3; +for($i = 1; $i <= $numDepart; $i ++) { + $department [] = "D" . $i; +} + +$numProfit=3; +for ($i=1; $i<=$numProfit; $i++) { +$dprofit[]="profit-".$i; +} + +//print_r($supplier)."\n"; +//print_r($department)."\n"; + +$distance = array ( + 'D1_S1' => 2, + 'D1_S2' => 5, + 'D1_S3' => 3, + 'D2_S1' => 3, + 'D2_S2' => 2, + 'D2_S3' => 2, + 'D3_S1' => 3, + 'D3_S2' => 4, + 'D3_S3' => 8 +); + +// print_r($distance); + +$capacity = array (0,600,300,200); +$demand = array (0,600,200,300); +$dProfit = array ('D1' => 20,'D2' => 30,'D3' => 40 ); +$realProfit = array (); +// print_r($dProfit); + +foreach ( $supplier as $key => $value ) { + foreach ( $dProfit as $k => $v ) { + $newkey = "{$k}_{$value}"; + $realProfit [$newkey] = $v - $distance [$newkey]; + } +} +// print_r($realProfit); + +// create supply capacity +$supplyVar = array (); +for($i = 1; $i <= $numSupplier; $i ++) { + $supplyVar ["S$i"] = $capacity [$i]; +} +// print_r($supplyVar); + +// create department demand +$demandVar = array (); +for($i = 1; $i <= $numDepart; $i ++) { + $demandVar ["D$i"] = $demand [$i]; +} +// print_r($demandVar); + +// create decision variable +$decVar = array (); +foreach ( $supplier as $s ) { + foreach ( $department as $d ) { + $decVar [] = "{$s}_{$d}"; + } +} +// print_r($decVar); + +// create OSIL + +$os = new \WebIS\OS (); + +foreach ( $realProfit as $key => $value ) { + $os->addVariable ( $key ); + $os->addObjCoef ( $key, $value ); +} + +// create supply constraint +//foreach ( $supplier as $s ) { + //$os->addConstraint ( $supplyVar [$s], NULL ); + //foreach ( $department as $d ) { + //$os->addConstraintCoef ( "{$s}_{$d}", 1 ); + //} +//} + +// create demand constraint +//foreach ( $department as $d ) { + //$os->addConstraint ( NULL, $demandVar [$d] ); + //foreach ( $supplier as $s ) { + //$os->addConstraintCoef ( "{$s}_{$d}", 1 ); + //} +//} + +print_r ( $os ); + +?> \ No newline at end of file diff --git a/Web/Final-partB.php b/Web/Final-partB.php new file mode 100644 index 0000000..10885ea --- /dev/null +++ b/Web/Final-partB.php @@ -0,0 +1,79 @@ +$d){ + $profit[$key]=rand(5,50); +} +//print_r($profit) + +// create cost / distance +$cost=array(); +foreach($decVar as $key => $var){ + $cost[$var]=rand(2,10); +} +//print_r($cost) + +// create real profit +$realProfit=array(); +foreach($department as $d){ + $value=$profit[$d]; + foreach ($supplier as $s){ + $realProfit["{$s}_{$d}"]=$value-$cost["{$s}_{$d}"]; + } +} +print_r($realProfit); + +// create OSIL file + +$os=new \WebIS\OS; + +foreach ( $realProfit as $key => $value ) { + $os->addVariable ( $key ); + $os->addObjCoef ( $key, $value ); +} +print_r($os); + + + +?> \ No newline at end of file diff --git a/Web/Final.html b/Web/Final.html new file mode 100644 index 0000000..0a50758 --- /dev/null +++ b/Web/Final.html @@ -0,0 +1,76 @@ + + + + +Decision Support Systems - IMSE 4420 Final + + +

Sean McLerran - scmmv4

+

Supply Data

+ + + + $s"; + } +echo""; +foreach($supplyVar as $s){ + echo""; + } +echo""; +?> + +
Supplier
Supply$s
+

Demand Data

+ + + + $d"; + } +echo""; +foreach($demandVar as $d){ + echo""; + } +echo""; +?> + +
Department
Demand$d
+

Profit Data

+ + + + $d"; + } +echo""; +foreach($dProfit as $p){ + echo""; + } +echo""; +?> + +
Department
Profit$p
+ +

Shipping Data

+ + + + $d"; + } +echo""; +foreach($realProfit as $p){ + echo""; + } +echo""; +?> + +
Supplier to Department
Real Profit$p
+ + + \ No newline at end of file diff --git a/Web/OSRL.html b/Web/OSRL.html new file mode 100644 index 0000000..4e46723 --- /dev/null +++ b/Web/OSRL.html @@ -0,0 +1,41 @@ + + + + +OSRL Solution + + +

OSRL Solution

+

Sean McLerran - scmmv4

+ + + + + solve(); +echo "
Objective Value
$objvalue" +?> +
+

Shipping Values

+ + + + $s\n"; +} +?> + + "; +foreach($supplier as $s){ +echo ""; +echo "\n"; +} +} +?> +
$d".$os->getVariable("{$s}_{$d}")."
+
+ + \ No newline at end of file From 47e32139f26e3574e893b43ac985fd7643be78fe Mon Sep 17 00:00:00 2001 From: scmmv4 Date: Mon, 12 May 2014 14:31:47 -0500 Subject: [PATCH 12/12] e, f, and i complete on part B. -Couldn't fix error on line 127 of os.php -Not displaying on workspace --- WCS/os.php | 18 ++++---- Web/Final-partA.php | 103 ++++++++++++++++++++++++++++---------------- Web/Final-partB.php | 2 + Web/OSRL.html | 2 +- 4 files changed, 77 insertions(+), 48 deletions(-) diff --git a/WCS/os.php b/WCS/os.php index 10cba79..2bec5bf 100644 --- a/WCS/os.php +++ b/WCS/os.php @@ -5,17 +5,17 @@ class OS { static $DEBUG=FALSE; static $solver="\\WebIS\\bin\OSSolverService.exe"; - static $tmp="\\WebIS\\tmp\\"; // trailing slash required. + static $temp="\\WebIS\\tmp\\"; // trailing slash required. private $linear=FALSE; - private $osil=NULL; - private $osrl=NULL; - private $var=array(); // Reverse IDX mapping ($idx->$name). - private $value=NULL; // Solution value. - private $solution=NULL; + public $osil=NULL; + public $osrl=NULL; + public $var=array(); // Reverse IDX mapping ($idx->$name). + public $value=NULL; // Solution value. + public $solution=NULL; - function __construct($maxOrMin='min') { + function __construct($maxOrMin='max') { $osil=new \SimpleXMLElement(''); $osil->addChild('instanceHeader')->addChild('name',php_uname('n').' '.date('c')); $data=$osil->addChild('instanceData'); @@ -105,8 +105,8 @@ function addConstraintCoef($name,$value){ } function solve(){ - $osilfile=tempnam(OS::$tmp,'OS-'); - $osrlfile=tempnam(OS::$tmp,'OS-'); + $osilfile=tempnam(OS::$temp,'OS-'); + $osrlfile=tempnam(OS::$temp,'OS-'); if(self::$DEBUG){ $osilfile='osil.xml'; $osrlfile='osrl.xml'; diff --git a/Web/Final-partA.php b/Web/Final-partA.php index 7f4f9eb..87a8609 100644 --- a/Web/Final-partA.php +++ b/Web/Final-partA.php @@ -9,17 +9,17 @@ //$dprofit=array('profit-1'=>20,'profit-2'=>30,'profit-3'=>40); $supplier = array (); -$numSupplier = 3; +$numSupplier = 4; for($i = 1; $i <= $numSupplier; $i ++) { - $supplier [] = "S" . $i; + $supplier [] = "S".$i; } -$numDepart = 3; +$numDepart = 5; for($i = 1; $i <= $numDepart; $i ++) { - $department [] = "D" . $i; + $department [] = "D".$i; } -$numProfit=3; +$numProfit=5; for ($i=1; $i<=$numProfit; $i++) { $dprofit[]="profit-".$i; } @@ -27,33 +27,38 @@ //print_r($supplier)."\n"; //print_r($department)."\n"; +//added part e. $distance = array ( 'D1_S1' => 2, 'D1_S2' => 5, 'D1_S3' => 3, + 'D1_S4' => 3, 'D2_S1' => 3, 'D2_S2' => 2, 'D2_S3' => 2, + 'D2_S4' => 2, 'D3_S1' => 3, 'D3_S2' => 4, - 'D3_S3' => 8 + 'D3_S3' => 8, + 'D3_S4' => 4, + 'D4_S1' => 3, + 'D4_S2' => 4, + 'D4_S3' => 2, + 'D4_S4' => 2, + 'D5_S1' => 3, + 'D5_S2' => 2, + 'D5_S3' => 2, + 'D5_S4' => 2 + ); +//part e) shown in $distance - added S4, D4, D5 +//distsance calculated below - $distance - 5 BONUS POINTS! +print_r($distance); -// print_r($distance); - -$capacity = array (0,600,300,200); -$demand = array (0,600,200,300); -$dProfit = array ('D1' => 20,'D2' => 30,'D3' => 40 ); -$realProfit = array (); -// print_r($dProfit); - -foreach ( $supplier as $key => $value ) { - foreach ( $dProfit as $k => $v ) { - $newkey = "{$k}_{$value}"; - $realProfit [$newkey] = $v - $distance [$newkey]; - } -} -// print_r($realProfit); +$capacity = array (0,600,300,200,500); +$demand = array (0,600,200,300,100,300); +$dProfit = array ('D1' => 20,'D2' => 30,'D3' => 40, 'D4' => 25,'D5' => 25); +//print_r($dProfit); // create supply capacity $supplyVar = array (); @@ -76,33 +81,55 @@ $decVar [] = "{$s}_{$d}"; } } -// print_r($decVar); +//print_r($decVar); + +// problem f) add plant production costs +$pCosts=array('S1'=>10,'S2'=>14,'S3'=>40,'S4'=>11); +//print_r($pCosts); +$costs=array(); +foreach ($supplier as $s) { + $costs[]=$pCosts[$s]; +} +//print_r($costs); + +// define real profit - objective +$realProfit = array (); +foreach ( $supplier as $key => $value ) { + foreach ( $dProfit as $k => $v ) { + $newkey = "{$k}_{$value}"; + $realProfit [$newkey] = $v - $distance [$newkey] - $pCosts[$s]; + } +} +// f) complete in $realProfit - 10 POINTS +print_r($realProfit); // create OSIL $os = new \WebIS\OS (); -foreach ( $realProfit as $key => $value ) { - $os->addVariable ( $key ); - $os->addObjCoef ( $key, $value ); +foreach ( $decVar as $dVar ) { + $os->addVariable ( "$dVar" ); + $os->addObjCoef ( "$dVar" , $value) ; } // create supply constraint -//foreach ( $supplier as $s ) { - //$os->addConstraint ( $supplyVar [$s], NULL ); - //foreach ( $department as $d ) { - //$os->addConstraintCoef ( "{$s}_{$d}", 1 ); - //} -//} +foreach ( $supplier as $s ) { + $os->addConstraint ( $supplyVar [$s], NULL ); + foreach ( $department as $d ) { + $os->addConstraintCoef ( "{$s}_{$d}", 1 ); + } +} // create demand constraint -//foreach ( $department as $d ) { - //$os->addConstraint ( NULL, $demandVar [$d] ); - //foreach ( $supplier as $s ) { - //$os->addConstraintCoef ( "{$s}_{$d}", 1 ); - //} -//} +foreach ( $department as $d ) { + $os->addConstraint ( NULL, $demandVar [$d] ); + foreach ( $supplier as $s ) { + $os->addConstraintCoef ( "{$s}_{$d}", 1 ); + } +} -print_r ( $os ); +$os -> solve(); +//print_r ( $os ); +//print_r("end of exam"); ?> \ No newline at end of file diff --git a/Web/Final-partB.php b/Web/Final-partB.php index 10885ea..5546bad 100644 --- a/Web/Final-partB.php +++ b/Web/Final-partB.php @@ -72,6 +72,8 @@ $os->addVariable ( $key ); $os->addObjCoef ( $key, $value ); } + +$os -> solve(); print_r($os); diff --git a/Web/OSRL.html b/Web/OSRL.html index 4e46723..9658767 100644 --- a/Web/OSRL.html +++ b/Web/OSRL.html @@ -5,8 +5,8 @@ OSRL Solution -

OSRL Solution

Sean McLerran - scmmv4

+

OSRL Solution

Objective Value