From 0cda517f986ec368afd33e64cce782670c6a7eb2 Mon Sep 17 00:00:00 2001 From: Timothy Middelkoop Date: Sun, 6 Apr 2014 16:39:26 -0500 Subject: [PATCH 01/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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/14] 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 dd81b4f197938921ced45af964bffaca6b4c769c Mon Sep 17 00:00:00 2001 From: mg2m5 Date: Thu, 8 May 2014 14:03:32 -0500 Subject: [PATCH 11/14] a7 --- App/osbasics.php | 200 +++++++++++++++++++++++++++++++++++++++++++++ App/test.xml | 2 + Web/Exam.php | 77 +++++++++++++++++ Web/a6.php | 84 +++++++++++++++++++ Web/a7.php | 113 +++++++++++++++++++++++++ Web/modelbasic.php | 135 ++++++++++++++++++++++++++++++ Web/osil.xml | 2 + Web/tdd.php | 29 +++++++ 8 files changed, 642 insertions(+) create mode 100644 App/osbasics.php create mode 100644 App/test.xml create mode 100644 Web/Exam.php create mode 100644 Web/a6.php create mode 100644 Web/a7.php create mode 100644 Web/modelbasic.php create mode 100644 Web/osil.xml create mode 100644 Web/tdd.php diff --git a/App/osbasics.php b/App/osbasics.php new file mode 100644 index 0000000..bbf79ac --- /dev/null +++ b/App/osbasics.php @@ -0,0 +1,200 @@ + + +XML; + +function osil(){ + $osil=new SimpleXMLElement(''); + $osil-> addChild('instanceHeader'); + return $osil-> asXML(); + +AssertEquals($xml,$osil); +} + +//Problem 6a + +function AssertContainsString($needle,$haystack){ + if (strpos($haystack,$needle)===FALSE){ + throw new Exception("AssertContainsString failed"); + } +} +AssertContainsString("needle","haystack needle"); +//AssertContainsString("needle","nada"); + +//AssertContainsString("needle","nada"); +$failed=FALSE; +try{ + //AssertContainsString("needle","needle"); + AssertContainsString("needle","HAY"); +} catch (Exception $e){ + $failed=TRUE; +} +assert($failed); + +//echo "passed\n"; + +//Problem 6b + +function AssertContains($needle,$hay){ + foreach($hay as $h) + if (strpos($h,$needle)!==FALSE){ + return TRUE; + } + throw new Exception("AssertContains failed"); +} +AssertContains("needle",array("needle hay","hay needle")); +//AssertContains("needle",array("hay hay","hay hay hay")); + +$failed=FALSE; +try{ + AssertContains("needle",array("hay","hay no sharp objects")); +} catch (Exception $e){ + $failed=TRUE; +} +assert($failed); + +//Problem 7 + +exec("\\WebIS\\bin\\OSSolverService.exe -h",$output,$result); + +AssertEquals(0,$result); + +//print_r ($output); + +$failed=FALSE; +try{ + AssertContains("OS Version X.Y.Z",$output); + //AssertContains("OS Version: 2.",$output); +} catch (Exception $e){ + $failed=TRUE; +} +assert($failed); + +AssertContains("OS Version: 2.",$output); + +//problem 8 + +function write($file){ + $osil=new SimpleXMLElement(''); + $osil -> addchild('instanceHeader'); + return $osil-> asXML($file); +} + +write('test.xml'); +$xxml=file_get_contents('test.xml'); + +//print_r($xxml); +//print_r(osil()); +AssertEquals($xxml,osil()); + + +//Problem 9 + +function solve(){ + exec("\\WebIS\\bin\\OSSolverService.exe -osil test.xml -osrl solution.xml",$output,$result); + if ($result!==0){ + throw new Exception("Solve function failed\n".implode("\n",$output)); + } + return TRUE; +} + +$osil=new SimpleXMLElement(''); +$osil -> addchild('instanceHeader'); +$osil -> addChild('instanceData') -> addChild('objectives') -> addChild('obj') -> addAttribute('numberOfObjCoef',0); +$osil -> asXML('test.xml'); + +assert(solve()); + + +//problem 10 + + +function solution(){ + $xml=file_get_contents('solution.xml'); + //print_r($xml); + $osrl=new simpleXMLElement($xml); + //print_r($osrl); + $result=(string)$osrl -> optimization->solution->status->attributes()->type(); + //print_r($result); + $value=(double)$osrl->optimization->solution->objectives->values->obj; + //print_r($value); + return $value; + //AssertEquals("optimal",$result); + //problem 11 + //AssertContains("PARSER ERROR",$xml); +} +//solution(); +//assertEquals(solution(),0); + +//problem 12 + + + +echo "done"; + +?> \ No newline at end of file diff --git a/App/test.xml b/App/test.xml new file mode 100644 index 0000000..edb4422 --- /dev/null +++ b/App/test.xml @@ -0,0 +1,2 @@ + + diff --git a/Web/Exam.php b/Web/Exam.php new file mode 100644 index 0000000..ff10ad1 --- /dev/null +++ b/Web/Exam.php @@ -0,0 +1,77 @@ +matrix["${supply}_${department}"]=$shipping; + } + + function get($supply,$department){ + if(array_key_exists("${supply}_${department}",$this->matrix)){ + return $this->matrix["${supply}_${department}"]; + } + return FALSE; + } +} + +$shipping=new ShippingClass; + +//Test Get and Set +assertEquals(FALSE,$shipping->get('supply-0','department-0')); +$shipping->set('supply-0','department-0',0.90); +assertEquals(0.90,$shipping->get('supply-0','department-0')); + +for($i=0;$i<20;$i++){ + $shipping->set($supply[array_rand($supply)],$department[array_rand($department)],rand(60,100)/100.0); +} + + +//print_r($shipping); + +//Start Optimization + +$os=new \WebIS\OS; +print_r($os->solve()); +assertNotEquals('0',$os->solve()); + +foreach($supply as $s){ + foreach($department as $d){ + $var="${s}_${d}"; + $os->addVariable($var); + $os->addObjCoef($var,1); + } +} + +assertNotEquals(0,$os->solve()); + + + +echo"End"; +?> \ No newline at end of file diff --git a/Web/a6.php b/Web/a6.php new file mode 100644 index 0000000..711ecf9 --- /dev/null +++ b/Web/a6.php @@ -0,0 +1,84 @@ +assertEquals(0,$return); + $this->assertContains("OS Version: 2.",$output[5]); + } + + function testSolver(){ + $os=New WebIS\OS; + $this->assertEquals(0.0,$os->solve(),"Solve empty problem"); + $this->assertContains(date('Y-m-d'),$os->getName(),"Solved today"); + $os->addVariable('x11'); + //$this->assertEquals(0.0,$os->solve(),"Solve problem with only one variable"); + //$this->assertEquals(0.0,$os->getVariable('x11'),"x11 is zero"); + $os->addObjCoef('x11', '3'); + //$this->assertEquals(0.0,$os->solve()); + + $os->addVariable('x12'); + $os->addObjCoef('x12', '2'); + + $os->addVariable('x21'); + $os->addObjCoef('x21', '1'); + + $os->addVariable('x22'); + $os->addObjCoef('x22', '5'); + + $os->addVariable('x31'); + $os->addObjCoef('x31', '5'); + + $os->addVariable('x32'); + $os->addObjCoef('x32', '4'); + + $os->addConstraint($ub=45); + $os->addConstraintCoef('x11',1); + $os->addConstraintCoef('x12',1); + + $os->addConstraint($ub=60); + $os->addConstraintCoef('x21',1); + $os->addConstraintCoef('x22',1); + + + $os->addConstraint($ub=35); + $os->addConstraintCoef('x31',1); + $os->addConstraintCoef('x32',1); + + $os->addConstraint(null,50); + $os->addConstraintCoef('x11',1); + $os->addConstraintCoef('x21',1); + $os->addConstraintCoef('x31',1); + + $os->addConstraint(null,60); + $os->addConstraintCoef('x12',1); + $os->addConstraintCoef('x22',1); + $os->addConstraintCoef('x32',1); + + print_r($os->solve()); + + //$this->assertEquals(-80.0,$os->solve()); + //$this->assertEquals(0,$os->getVariabl + + //$this->assertEquals(40,$os->getVariable('x2')); + + //print_r($os->getVariable('x11')); + //print_r($os->getVariable('x12')); + + } +} + +if (!defined('PHPUnit_MAIN_METHOD')) { + OsTestCase::main(); +} + +?> diff --git a/Web/a7.php b/Web/a7.php new file mode 100644 index 0000000..d20dae3 --- /dev/null +++ b/Web/a7.php @@ -0,0 +1,113 @@ +product=$p; + //print_r($this->product); + $this->cell=$c; + $this->hour=$h; + } + +} + +$demand=array(); + +foreach($product as $p){ + + $demand[]=new Demand($p,"$ccell",rand(1,3)); +} + +//print_r($demand); + + +//Problem B4 + +class Training{ + + + public $worker=array(); + public $cellproductivity=array(); + + function __construct($w,$cp){ + $this->worker=$w; + $this->cellproductivity=$cp; + } + + function set($p){ + if($p===NULL){ + $p=(rand(60,100))/100.0; + } + print_r($p); + } + + function get($worker,$cell,$productivity){ + + } + +} + +$traingingMatrix[]=array(); + + +foreach($worker as $w){ + $w=$worker[rand(0,$numworker-1)]; + $c=$cell[rand(0,$numcell-1)]; + $value="${c}_${w}"."\n"; + $trainingMatrix[$value]=(rand(60,100)/100.0); +} + +//print_r($value); + +print_r($trainingMatrix); + + + + + +echo"you made it to the end."; + +?> \ No newline at end of file diff --git a/Web/modelbasic.php b/Web/modelbasic.php new file mode 100644 index 0000000..13cc6b5 --- /dev/null +++ b/Web/modelbasic.php @@ -0,0 +1,135 @@ +modelbasic.php\n"; + +// Problem: Maximize productivity in a work-cell line. +// Workers are assigned a productivity score for each work-cell. +// Products are given a demand in normalized hours on a work-cell. +// Production is equal to (hours allocated) * (productivity on machine) + +// A: Setup. + +// 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'; + +function assertTrue(){ + return TRUE; +} +function assertFalse(){ + return FALSE; +} + +function AssertEquals($expected,$result){ + if($expected!==$result){ + throw new Exception("Assert Equals failed"); + } + return TRUE; + +} + +function AssertNotEquals($expected,$result){ + if($expected===$result){ + throw new Exception("Assert Not Equals Failed"); + } + return TRUE; +} + +assertEquals(TRUE,TRUE); +assertTrue(TRUE); +assertFalse(FALSE); + +// B: Setup problem and data structures. + +$workers=5; +$cells=4; +$products=6; + +// B1: Create arrays of workers, cells and products (worker-1, cell-3, product-4) +// called worker,cell, and product + +$worker=array(); +for($i=0;$i<$workers;$i++){ +$worker[]="worker-${i}"; +} +assertEquals($workers,sizeof($worker)); +//print_r($worker); + +$cell=array(); +for($i=0;$i<$cells;$i++){ +$cell[]="cell-${i}"; +} +assertEquals($cells,sizeof($cell)); + +$product=array(); +for($i=0;$i<$products;$i++){ +$product[]="product-${i}"; +} +assertEquals($products,sizeof($product)); + +// B2: Pick at random a worker and test using TDD. +// make sure the first and last get picked. + +$w=0; +while($worker[$w] != 'worker-1'){ +$w=array_rand($worker); +//print_r($w); +} + +// B3: 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; +public $cell=NULL; +public $hours=NULL; +function __construct($product,$cell,$hours){ +$this->product=$product; +$this->cell=$cell; +$this->hours=$hours; +} +} + +$demand=array(); +foreach($product as $p){ +$demand[]=new Demand($p,$cell[array_rand($cell)],rand(1,3)); +} + +assertEquals($products,sizeof($demand)); +//print_r($demand); + +// 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 ('_') +// Note in the "" syntax use the form ${worker} instead of $worker. + +class Training { +private $default=FALSE; +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; + +// 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')); + +// 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); +} +//print_r($training); +?> diff --git a/Web/osil.xml b/Web/osil.xml new file mode 100644 index 0000000..5044f93 --- /dev/null +++ b/Web/osil.xml @@ -0,0 +1,2 @@ + +EBE3404-PC-22 2014-04-21T11:20:00-05:003215540246912012345024135111111111111 diff --git a/Web/tdd.php b/Web/tdd.php new file mode 100644 index 0000000..ea791b5 --- /dev/null +++ b/Web/tdd.php @@ -0,0 +1,29 @@ + \ No newline at end of file From dbd9b3254907a9f15a568c979f2ff914bc85253d Mon Sep 17 00:00:00 2001 From: mg2m5 Date: Mon, 12 May 2014 12:28:38 -0500 Subject: [PATCH 12/14] Final Project Part B --- Web/FinalPartB.php | 130 +++++++++++++++++++++++++++++++++++++++++++++ Web/tdd.php | 25 +++++++++ 2 files changed, 155 insertions(+) create mode 100644 Web/FinalPartB.php create mode 100644 Web/tdd.php diff --git a/Web/FinalPartB.php b/Web/FinalPartB.php new file mode 100644 index 0000000..719dc7f --- /dev/null +++ b/Web/FinalPartB.php @@ -0,0 +1,130 @@ +matrix["${supply}_${department}"]=$shipping; + } + + function get($supply,$department){ + if(array_key_exists("${supply}_${department}",$this->matrix)){ + return $this->matrix["${supply}_${department}"]; + } + return FALSE; + } +} + +$shipping=new ShippingClass; + +foreach($supply as $s){ +$shipping->set($s,$department[array_rand($department)],rand(1,8)); +} + + +//print_r($shipping); + + + +//Start Optimization + +$os=new \WebIS\OS; + +//print_r($os->solve()); +assertTrue($os->solve()); + +foreach($supply as $s){ + foreach($department as $d){ + $var="${s}_${d}"; + //print_r($var."\n"); + $os->addVariable($var); + $os->addObjCoef($var,$shipping->get($s,$d)); + } +} + + + +foreach(array_combine($demand,$department) as $dem => $dep){ + $os->addConstraint(NULL,$dem); + //print_r($dem."\n"); + //print_r($dep."\n"); + foreach($supply as $s){ + $vari="${s}_${dep}"; + //print_r($vari."\n"); + $os->addConstraintCoef($vari,1); + } +} + + + +foreach(array_combine($capacity,$supply) as $c => $s){ + $os->addConstraint($c,NULL); + foreach($department as $d){ + $vari="${s}_${d}"; + //print_r($vari."\n"); + $os->addConstraintCoef($vari,1); + } +} + + + + +assertTrue($os->solve()); +//echo"here"; + +//print_r($os); + +$os->solve(); +$minshippingcost=$os->getsolution(); +print_r($minshippingcost); +//$maxprofit=$revenue-$minshippingcost; +//print_r("max profit: ".$maxprofit."\n"); + + +//echo"End"; +?> \ No newline at end of file diff --git a/Web/tdd.php b/Web/tdd.php new file mode 100644 index 0000000..b31a328 --- /dev/null +++ b/Web/tdd.php @@ -0,0 +1,25 @@ + \ No newline at end of file From fb0b80fc171f9a2cd0fc2889048ba1150aa111cd Mon Sep 17 00:00:00 2001 From: mg2m5 Date: Mon, 12 May 2014 14:08:04 -0500 Subject: [PATCH 13/14] Final Part E --- Web/Final-PartE.php | 180 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 Web/Final-PartE.php diff --git a/Web/Final-PartE.php b/Web/Final-PartE.php new file mode 100644 index 0000000..d259ef0 --- /dev/null +++ b/Web/Final-PartE.php @@ -0,0 +1,180 @@ +matrix["${supply}_${department}"]=$shipping; + } + + function get($supply,$department){ + if(array_key_exists("${supply}_${department}",$this->matrix)){ + return $this->matrix["${supply}_${department}"]; + } + return FALSE; + } +} + +$shipping=new ShippingClass; + +//Test Get and Set +assertEquals(FALSE,$shipping->get('supply-0','department-0')); +$shipping->set('supply-0','department-0',2); +assertEquals(2,$shipping->get('supply-0','department-0')); +$shipping->set('supply-0','department-1',3); +$shipping->set('supply-0','department-2',3); +$shipping->set('supply-0','department-3',3); +$shipping->set('supply-0','department-4',3); + +$shipping->set('supply-1','department-0',5); +$shipping->set('supply-1','department-1',2); +$shipping->set('supply-1','department-2',4); +$shipping->set('supply-1','department-3',4); +$shipping->set('supply-1','department-4',2); + +$shipping->set('supply-2','department-0',3); +$shipping->set('supply-2','department-1',2); +$shipping->set('supply-2','department-2',8); +$shipping->set('supply-2','department-3',2); +$shipping->set('supply-2','department-4',2); + +$shipping->set('supply-3','department-0',3); +$shipping->set('supply-3','department-1',2); +$shipping->set('supply-3','department-2',4); +$shipping->set('supply-3','department-3',2); +$shipping->set('supply-3','department-4',2); + + +//print_r($shipping); +//print_r($shipping->get($supply[0],$department[0])); + +$d0=array(20,30,40,25,25); +//print_r($d0[1]); + +$revenue=array(); +foreach($supply as $s){ + foreach(array_combine($department,$d0) as $d => $d1){ + $var="${s}_${d}"; + $revenue[$var]=$d1-$shipping->get($s,$d,NULL); + //print_r($revenue[$var]."\n"); + } +} + + +//Start Optimization + +$os=new \WebIS\OS; + +//print_r($os->solve()); +assertTrue($os->solve()); + +foreach($supply as $s){ + foreach($department as $d){ + $var="${s}_${d}"; + //print_r($var."\n"); + $os->addVariable($var); + $os->addObjCoef($var,$revenue[$var]); + } +} + +//print_r($os); +//echo"here\n"; + +foreach(array_combine($department,$demand) as $dep => $dem){ + $os->addConstraint($dem,NULL); + //print_r($dem."\n"); + //print_r($dep."\n"); + foreach($supply as $s){ + $vari="${s}_${dep}"; + //print_r($vari."\n"); + $os->addConstraintCoef($vari,1); + } +} + + + +foreach(array_combine($capacity,$supply) as $c => $s){ + $os->addConstraint(NULL,$c); + foreach($department as $d){ + $vari="${s}_${d}"; + $os->addConstraintCoef($vari,1); + } +} + + + +assertTrue($os->solve()); + + + +$os->solve(); +$maxprofit=$os->getsolution(); +print_r($maxprofit."\n"); + + + +//echo"End"; +?> \ No newline at end of file From 7881e31b2ae4500e5fcde53196afe9d8eaf01e5b Mon Sep 17 00:00:00 2001 From: mg2m5 Date: Mon, 12 May 2014 14:35:42 -0500 Subject: [PATCH 14/14] Final Parts F & G. --- WCS/os.php | 2 +- Web/ExamRestart.php | 28 +++++++++ Web/Final-PartA.php | 140 -------------------------------------------- Web/Final-PartE.php | 20 ++++++- 4 files changed, 46 insertions(+), 144 deletions(-) create mode 100644 Web/ExamRestart.php delete mode 100644 Web/Final-PartA.php diff --git a/WCS/os.php b/WCS/os.php index 10cba79..393502e 100644 --- a/WCS/os.php +++ b/WCS/os.php @@ -15,7 +15,7 @@ class OS { private $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'); diff --git a/Web/ExamRestart.php b/Web/ExamRestart.php new file mode 100644 index 0000000..14406da --- /dev/null +++ b/Web/ExamRestart.php @@ -0,0 +1,28 @@ + 600, "s2" => 300, "s3" => 200); +//print_r($capacity); + +$demand=array("d1"=>600, "d2"=>200, "d3"=>300); +//print_r($demand); + +$profit=array("d1"=>20, "d2"=>30, "d3"=>40); +//print_r($profit['d1']); + +$distance=array("s1,d1"=>2, "s1,d2"=>3, "s1,d3"=>3,"s2,d1"=>5, "s2,d2"=>2, "s2,d3"=>4, "s3,d1"=>3, "s3,d2"=>2, "s3,d3"=>8); +//print_r($distance['s1,d1']); + +$a=$demand['d1']*$profit['d1']; +//print_r($a); +$b=$demand['d2']*$profit['d2']; +$c=$demand['d3']*$profit['d3']; + +$revenue=$a+$b+$c; +//print_r($revenue); + +//300 from s1 to d1 + +//300 from s1 to d3 + + +?> \ No newline at end of file diff --git a/Web/Final-PartA.php b/Web/Final-PartA.php deleted file mode 100644 index 9023613..0000000 --- a/Web/Final-PartA.php +++ /dev/null @@ -1,140 +0,0 @@ -matrix["${supply}_${department}"]=$shipping; - } - - function get($supply,$department){ - if(array_key_exists("${supply}_${department}",$this->matrix)){ - return $this->matrix["${supply}_${department}"]; - } - return FALSE; - } -} - -$shipping=new ShippingClass; - -//Test Get and Set -assertEquals(FALSE,$shipping->get('supply-0','department-0')); -$shipping->set('supply-0','department-0',2); -assertEquals(2,$shipping->get('supply-0','department-0')); -$shipping->set('supply-0','department-1',3); -$shipping->set('supply-0','department-2',3); -$shipping->set('supply-1','department-0',5); -$shipping->set('supply-1','department-1',2); -$shipping->set('supply-1','department-2',4); -$shipping->set('supply-2','department-0',3); -$shipping->set('supply-2','department-1',2); -$shipping->set('supply-2','department-2',8); - -//print_r($shipping['supply-1_department-1']); -//print_r($shipping); -//print_r($shipping->get($supply[0],$department[0])); - - -//Start Optimization - -$os=new \WebIS\OS; - -//print_r($os->solve()); -assertTrue($os->solve()); - -foreach($supply as $s){ - foreach($department as $d){ - $var="${s}_${d}"; - //print_r($var."\n"); - $os->addVariable($var); - $os->addObjCoef($var,$shipping->get($s,$d)); - } -} - -foreach(array_combine($demand,$department) as $dem => $dep){ - $os->addConstraint($dem,NULL); - //print_r($dem."\n"); - //print_r($dep."\n"); - foreach($supply as $s){ - $vari="${s}_${dep}"; - //print_r($vari."\n"); - $os->addConstraintCoef($vari,1); - } -} - -foreach(array_combine($capacity,$supply) as $c => $s){ - $os->addConstraint(NULL,$c); - foreach($department as $d){ - $vari="${s}_${d}"; - $os->addConstraintCoef($vari,1); - } -} - -assertTrue($os->solve()); - -//print_r($os); - -$os->solve(); -$minshippingcost=$os->getsolution(); -//print_r($minshippingcost); -$maxprofit=$revenue-$minshippingcost; -print_r("max profit: ".$maxprofit."\n"); - - -//echo"End"; -?> \ No newline at end of file diff --git a/Web/Final-PartE.php b/Web/Final-PartE.php index d259ef0..8e8966d 100644 --- a/Web/Final-PartE.php +++ b/Web/Final-PartE.php @@ -111,18 +111,32 @@ function get($supply,$department){ //print_r($shipping); //print_r($shipping->get($supply[0],$department[0])); + +//Profit for each department respectively $d0=array(20,30,40,25,25); //print_r($d0[1]); +//Production costs for each plant respectively +$p0=array(10,14,40,11); + + +//revenue array = (profit for each department) - (shipping cost) - (production cost) $revenue=array(); foreach($supply as $s){ foreach(array_combine($department,$d0) as $d => $d1){ $var="${s}_${d}"; - $revenue[$var]=$d1-$shipping->get($s,$d,NULL); - //print_r($revenue[$var]."\n"); + $revenue[$var]=$d1-$shipping->get($s,$d); + } } +foreach($department as $d){ + foreach(array_combine($supply,$p0) as $s => $p1){ + $var="${s}_${d}"; + $revenue[$var]-=$p1; + } +} +//print_r($revenue); //Start Optimization @@ -172,7 +186,7 @@ function get($supply,$department){ $os->solve(); $maxprofit=$os->getsolution(); -print_r($maxprofit."\n"); +print_r("max profit: ".$maxprofit."\n");