function lp_maker($f = null, $a = null, $b = null, $e = null, $vlb = null, $vub = null, $xint = null, $scalemode = null, $setminim = null) { if ($f == null) { help_lp_maker(); return; } $m = count($a); $n = count($a[0]); $lp = lpsolve('make_lp', $m, $n); lpsolve('set_verbose', $lp, IMPORTANT); lpsolve('set_mat', $lp, $a); lpsolve('set_rh_vec', $lp, $b); lpsolve('set_obj_fn', $lp, $f); lpsolve('set_maxim', $lp); // default is solving minimum $lp. for ($i = 0; $i < count($e); $i++) { if ($e[$i] < 0) { $con_type = LE; } else { if ($e[$i] == 0) { $con_type = EQ; } else { $con_type = GE; } } lpsolve('set_constr_type', $lp, $i + 1, $con_type); } if ($vlb != null) { lpsolve('set_lowbo', $lp, $vlb); } if ($vub != null) { lpsolve('set_upbo', $lp, $vub); } if ($xint != null) { for ($i = 0; $i < count($xint); $i++) { lpsolve('set_int', $lp, $xint[$i], 1); } } if ($scalemode != null) { if ($scalemode != 0) { lpsolve('set_scaling', $lp, $scalemode); } } if ($setminim != null) { if ($setminim != 0) { lpsolve('set_minim', $lp); } else { lpsolve('set_maxim', $lp); } } return $lp; }
public function solve() { $lp = lpsolve('make_lp', 0, $this->objective->count()); lpsolve('set_verbose', $lp, IMPORTANT); lpsolve('set_obj_fn', $lp, $this->objective->asCoefficients()); foreach ($this->constraints as $c) { lpsolve('add_constraint', $lp, $c->getCoefficients(), $c->getComparison(), $c->getRhs()); } foreach ($this->objective->getCoefficients() as $index => $coeff) { if ($coeff->hasUpperBound()) { lpsolve('set_upbo', $lp, $index + 1, $coeff->getUpperBound()); } if ($coeff->hasLowerBound()) { lpsolve('set_lowbo', $lp, $index + 1, $coeff->getLowerBound()); } } lpsolve('set_int', $lp, $this->objective->asIntSettings()); lpsolve($this->objective->getType(), $lp); $stat = lpsolve('solve', $lp); return new Solution($stat, lpsolve('get_variables', $lp)); #dd([$stat, lpsolve('get_variables', $lp)]); }
<?php include "lp_maker.php"; $f = array(110 * 1.3, 30 * 2.0, 125 * 1.56, 75 * 1.8, 95 * 0.95, 100 * 2.25, 50 * 1.35); $A = array(array(120, 210, 150.75, 115, 186, 140, 85), array(110, 30, 125, 75, 95, 100, 50), array(1, 1, 1, 1, 1, 1, 1), array(1, -1, 0, 0, 0, 0, 0), array(0, 0, 1, 0, -2, 0, 0), array(0, 0, 0, -1, 0, -1, 1)); $b = array(55000, 40000, 400, 0, 0, 0); $lp = lp_maker($f, $A, $b, array(-1, -1, -1, -1, -1, -1), array(10, 10, 10, 10, 20, 20, 20), array(100, Infinite, 50, Infinite, Infinite, 250, Infinite), null, 1, 0); $solvestat = lpsolve('solve', $lp); $obj = lpsolve('get_objective', $lp); print $obj . "\n"; $x = lpsolve('get_variables', $lp); print_r($x); lpsolve('delete_lp', $lp);
function getBestPath($userId) { App::import('Vendor', 'phplpsolve/lp_maker'); App::import('Model', 'ProjectsUsers'); App::import('Model', 'Relation'); $projectsUsersClass = new ProjectsUsers(); $relationClass = new Relation(); $this->bindModel(array('hasOne' => array('ProjectsUsers' => array('conditions' => array('ProjectsUsers.user_id' => $userId))))); $projects = $this->find('all'); $projectIds = Set::extract($projects, '{n}.Project.id'); $relations = $relationClass->find('all', array('conditions' => array('Relation.project_id' => $projectIds, 'Relation.project_preceding_id' => $projectIds))); // create target function $targetFunctionVector = array(); foreach ($projects as $project) { $targetFunctionVector[] = $project['ProjectsUsers']['done'] ? 0.0 : $this->linearizeProject($project['Project']); } // create restrictions $restrictionsMatrix = array(); foreach ($relations as $relation) { $specificRestrArr = array(); foreach ($projects as $project) { if ($relation['Relation']['project_preceding_id'] == $project['Project']['id']) { $specificRestrArr[] = 1; } elseif ($relation['Relation']['project_id'] == $project['Project']['id']) { $specificRestrArr[] = -1; } else { $specificRestrArr[] = 0; } } $restrictionsMatrix[] = $specificRestrArr; } $inequalityArray = array(); $restrictionTargetArray = array(); for ($i = 0; $i < count($restrictionsMatrix); $i++) { $inequalityArray[] = 1; $restrictionTargetArray[] = 0; } //add now all things we want and we have.. XXX extend all 3 arrays! foreach ($projects as $vectorId => $project) { if ($project['ProjectsUsers']['done'] || $project['ProjectsUsers']['wanted']) { $specificRestrArr = array(); for ($i = 0; $i < count($projects); $i++) { $specificRestrArr[] = $i == $vectorId ? 1 : 0; } $restrictionsMatrix[] = $specificRestrArr; $inequalityArray[] = 0; $restrictionTargetArray[] = 1; } } // debug($targetFunctionVector); // debug($restrictionsMatrix); // debug($restrictionTargetArray); // debug($inequalityArray); //generate lp... $lp = lp_maker($targetFunctionVector, $restrictionsMatrix, $restrictionTargetArray, $inequalityArray); lpsolve('set_minim', $lp); //helper sets to maximize //recycle inequalityArray for setting the binary vars.. for ($i = 0; $i < count($restrictionsMatrix[0]); $i++) { lpsolve('set_binary', $lp, 1, 1); } lpsolve('solve', $lp); $lpObjective = lpsolve('get_objective', $lp); $lpVariables = lpsolve('get_variables', $lp); lpsolve('delete_lp', $lp); $neededProjectIds = array(); foreach ($lpVariables[0] as $lpVar => $needed) { if ($needed) { $neededProjectIds[] = $projects[$lpVar]['Project']['id']; } } // debug($lpObjective); // debug($lpVariables); $savedCalculus = array('costs' => $lpObjective, 'projectIds' => $neededProjectIds); App::import('Model', 'User'); $userClass = new User(); $userClass->save(array('id' => $userId, 'saved_calculus' => serialize($savedCalculus))); return $savedCalculus; }
function lp_solve($f = null, $a = null, $b = null, $e = null, $vlb = null, $vub = null, $xint = null, $scalemode = null, $keep = null) { if ($f == null) { help_lp_solve(); return; } $m = count($a); $n = count($a[0]); $lp = lpsolve('make_lp', $m, $n); lpsolve('set_verbose', $lp, IMPORTANT); lpsolve('set_mat', $lp, $a); lpsolve('set_rh_vec', $lp, $b); lpsolve('set_obj_fn', $lp, $f); lpsolve('set_maxim', $lp); // default is solving minimum $lp. for ($i = 0; $i < count($e); $i++) { if ($e[$i] < 0) { $con_type = LE; } else { if ($e[$i] == 0) { $con_type = EQ; } else { $con_type = GE; } } lpsolve('set_constr_type', $lp, $i + 1, $con_type); } if ($vlb != null) { lpsolve('set_lowbo', $lp, $vlb); } if ($vub != null) { lpsolve('set_upbo', $lp, $vub); } if ($xint != null) { for ($i = 0; $i < count($xint); $i++) { lpsolve('set_int', $lp, $xint[$i], 1); } } if ($scalemode != null) { if ($scalemode != 0) { lpsolve('set_scaling', $lp, $scalemode); } } $result = lpsolve('solve', $lp); if ($result == 0 || $result == 1 || $result == 11 || $result == 12) { $ret = lpsolve('get_solution', $lp); $obj = $ret[0]; $x = $ret[1]; $duals = $ret[2]; $ret = $ret[3]; $stat = $result; } else { $obj = array(); $x = array(); $duals = array(); $stat = $result; } if ($keep != null && $keep != 0) { lpsolve('delete_lp', $lp); } return array($obj, $x, $duals); }