/decision/k11.php
PHP | 231 lines | 171 code | 45 blank | 15 comment | 63 complexity | 9d319909a9debfd5b2ceba27e2462e6e MD5 | raw file
- <?php
- /*
- K11 Decision Class -- to be instantiated directly by main.php
- Assigns accountant and brandRater to person
- Edgar Sioson
- */
-
- class K11 {
- function __construct($name='') {
- if (!$name) $name = 'K11';
- msgAddr($name, $this);
- }
-
- function rcv($Data) {
- if (!$Data) Error::halt("Invalid data: null or not in valid json.","K7");
-
- if ($Data['maxCycle']) return $this->init($Data);
- else if (is_numeric($Data['person_id'])) {
- if ($Data['loc'] == -1) return $this->setPerson($Data);
- else if (is_array($Data["F"]) AND min($Data["F"]) < 50) return $this->shop($Data);
- else if ($Data['nextAct'][0] == "C") return $this->shop($Data);
- }//else if ($Data['keys']) return $this->confirmAccess($Data);
- //else if (is_numeric($Data['linearTick'])) return $this->sync($Data);
- else {print_r($Data); Error::halt("No data received. [K10->rcv]");}
- }
-
- function init($Data) {
- $this->pwd = "k7po";
- $this->P = array();
- $this->IMMED_LOC = $Data['IMMED_LOC'];
- $locBeg = $Data['locBeg'];
- $this->acctant = $Data['acctant'];
- $this->inven = $Data['inven'];
- $this->brandIndex = $Data['brandIndex'];
- $this->pQty = $Data['pQty'];
- $this->cQty = $Data['cQty'];
- $this->wQty = $Data['wQty'];
-
- $this->brandLocs = RandomInit::assignRsrcLocs($Data['numBrands'], $Data['locBeg'], $Data['numLocs'], $Data['brandPrefix'], $Data['brandSuffix']); //print_r($this->brandLocs); exit();
-
- foreach($this->brandLocs AS $brand => $items) {
- msg2way($this->acctant, array("do"=> "setLedger", "brand" => $brand, "pwd" => $this->pwd, "minPN" => 0.7, "maxPN" => 1.5));
-
- foreach($items AS $rId => $locId) {
- msg2way($this->inven, array("do" => "setLoc", "brand" => $brand, "pwd" => $this->pwd, "locId" => $locId,
- "rsrcId" => $rId, "price"=>array("unitB"=>1)));
- msg2way("L$locId", array("do" => "setOwner", "owner" => $this->inven, "brand" => $brand, "pwd"=>$this->pwd));
- }
- }
-
- $this->members = RandomInit::assignMembers($this->brandLocs, $Data['personBeg'], $Data['numP']);
- }
-
- function setPerson($Data) {
-
- foreach($this->members AS $brand => $personArr) {
- foreach($personArr As $pId) {
- if ($Data['person_id'] == $pId) {
- msg2way($this->acctant, array("do"=> "addMember", "brand" => $brand, "pwd" => $this->pwd, "userId"=> "p".$pId));
-
- $rIds = array_keys($this->brandLocs[$brand]);
- shuffle($rIds);
-
- //in order to get the correct number of activities using the foreach loop below,
- //we need to adjust the number of resource Id's to 4
- $numIds = count($rIds);
- if ($numIds == 1) $rIds = array($rIds[0],$rIds[0],$rIds[0],$rIds[0]);
- else if ($numIds == 2) {
- $rIds[] = $rIds[0];
- $rIds[] = $rIds[1];
- }
- else if ($numIds == 3) $rIds[] = $rIds[0];
- else if ($numIds > 4) $rIds = array_slice($rIds, 0, 4);
-
- foreach($rIds AS $rId) {
- for($j=1; $j<7; $j++) {
- if ($j < 5) $cycle[] = array("P", $rId, $this->pQty, $this->brandLocs[$brand][$rId]);
- else if ($j == 5) $cycle[] = array("C", $rId, $this->cQty, $this->brandLocs[$brand][$rId]);
- else $cycle[] = array("W", "", $this->wQty, $this->brandLocs[$brand][$rId]);
- }
- }
-
- //prepare key-based access to locations
- //$p_Key = "m_". $pId;
-
- foreach($this->brandLocs[$brand] AS $locId) {
- msg2way("L$locId", array("do"=> "setAccess", "type"=> "adder", "pwd"=>$this->pwd, "person_id" => $pId)); //echo "\nK10: $pId $locId $p_Key";
- $asAdder[] = $locId;
- }
-
- break 2;
- }
- }
- }
-
- return array("cycle" => $cycle, "loc" => $locId, "brand" => $brand, "asAdder"=>$asAdder, "brandRater"=> $this->brandIndex); //"keys" => $keys,
- }
-
-
- function shop(&$Person) {
- $fMin = min($Person["F"]);
- $keyMin = array_search($fMin, $Person["F"]);
- $fMax = max($Person["F"]);
- $keyMax = array_search($fMax, $Person["F"]);
- $tempAveF = 0;
-
- $H = array();
-
- //lump personal holding qty's by resource Id, i.e., pool qty's by expiration into one unexpired total
- foreach($Person['holding'] AS $rId => $qtyByExp) {
- $avail = 0;
- foreach($qtyByExp AS $exp =>$qty) {
- if ($qty) $avail += $qty;
- }
-
- if ($avail) $H[] = array("", 0, $rId, $avail, 1);
- }
-
-
- //create a reference array for Person keys, to be used later for conveniently searching for accesible resource locations
- //keys format {"keystr1": [ [locId,qty,levels(...)], [...], ..., [...] ], "keystr2": [ [], [], [] ] }
- $locKeys = array();
- foreach($Person['keys'] AS $key => $locsArr) {
- foreach($locsArr AS $arr) $locKeys[ $arr[0] ][] = array($key, $arr[1], $arr[2]);
- }
-
- $catalog = msg2way($this->inven, array("do" => "viewItems", "priceUnits"=>"unitB")); //print_r($catalog); exit();
- if (!is_array($catalog)) exit("Catalog should be an array(brand, loc, resourceId, qty). [K10]");
-
- $H = array_merge($H, $catalog);
-
- $Bals = msg2way($this->acctant,array("do"=>"getUserBal", "userId" => "p".$Person['person_id'], "units"=>"unitB")); //print_r($Bals); exit();
- $bal = max($Bals);
-
- foreach($H AS $arr) {
- $brand = $arr[0];
- $locId = $arr[1];
- $rId = $arr[2];
- $qty = $arr[3];
- $price = $arr[4];
-
- $rDigits = str_split($rId,1);
-
- for($i=0; $i < NUM_DIMENSIONS; $i++) {
- if ($rDigits[$i] == 0) $qtyByDigit[$i] = 0;
- else $qtyByDigit[$i] = floor((99 - $Person['F'][$i]) / $rDigits[$i]);
- }
-
- for($i=0; $i < NUM_DIMENSIONS; $i++) {
- if (!$qtyByDigit[$i]) $qtyByDigit[$i] = max($qtyByDigit);
- }
-
- $tempQty = min(min($qtyByDigit), $qty);
- for($i=0; $i < NUM_DIMENSIONS; $i++) $tempF[$i] = $Person['F'][$i] + $tempQty*$rDigits[$i];
-
- if ($tempQty>0 AND $price*$tempQty <= $bal) $options[min($tempF)][] = array($brand, $locId, $rId, $tempQty, $price);
- }
-
- if ($options) {
- krsort($options); //print_r($options); exit();
-
- foreach($options AS $optGrp) {
- //TO-DO: optimize farther by option that give highest average fitness
-
- foreach($optGrp AS $choice) {
- foreach($locKeys AS $locNum => $accessInfo) {
- if ($choice[1] == $locNum) { //see if person already has access to location by key
- if ($accessInfo[3] < 0) { //see if access level includes resource removal privileges
- $to_brand = $choice[0];
- $bestLoc = $choice[1];
- $bestHeld = $choice[2];
- $rQty = $choice[3];
- $price = $choice[4] * $choice[3];
- if ($accessInfo[1] == $choice[3]) return array("act"=>array("C", $choice[2], $choice[3], $locNum));
- else $tempQty = $choice[3] - $accessInfo[1];
- }
- else $tempQty = $choice[3];
- }
- }
-
- if (!$bestHeld) {
- $to_brand = $choice[0];
- $bestLoc = $choice[1];
- $bestHeld = $choice[2];
- $rQty = $choice[3];
- $price = $choice[4] * $choice[3];
- }
-
- if ($tempQty OR $rQty) { //try to obtain a key to gain access to location and remove needed resource quantity
- $from_brand = array_search($bal, $Bals);
- $reply = msg2way($this->acctant,array("do"=>"purchase", "pwd"=>$this->pwd, "brand" => $from_brand, "from_acct"=>"p".$Person['person_id'], "to"=>$to_brand, "amount"=>$price, "qty"=>$rQty, "loc" => $bestLoc)); //print_r($reply);
-
- if ($reply['status'] == "ok") {
- return array("act"=>array("C", $bestHeld, $rQty, $bestLoc), "claimKey" => $reply['claimKey'], "loc"=>$bestLoc, "qty" => -$rQty);
- }
- else {
- foreach($reply['reasons'] AS $reason) {
- if ($reason == "PNratio") {
- return array("status"=>"rejected"); //array("act"=>array("W", $reply['wasteId'], $rQty, $reply['wasteLoc']));
- }
- else {
- return array("status"=>"rejected");
- }
- }
- }
- }
- }
- }
- } else return array("status" => "ok"); //("No options. [K10->shop]");
- if (!$bestHeld) {print_($Person); exit("k11->shop");}
- }
- }
-
- if ($_GET['test']) {
- header("content-type: text/plain");
-
- $k11n = "K11";
-
- $K11 = new K11();
- $K11->rcv(array("maxCycle"=>30, "IMMED_LOC" => 30, "locBeg" => 0));
- $K11->rcv(array("person_id"=>1));
- $K11->rcv(array("person_id"=>6));
-
- if ($K11>rcv(array("loc"=>1,"keys"=>array("m_1" => 20)))) echo "\nAccess confirmed\n"; else echo "\nAccess denied\n";
- //$K7->rcv(array("linearTick"=1);
- echo "\nmem_usage= ". memory_get_usage() ."\n";
-
- print_r($K11);
- }
-
- ?>