PageRenderTime 57ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/decision/k14.php

https://bitbucket.org/siosonel/flora
PHP | 258 lines | 193 code | 51 blank | 14 comment | 73 complexity | 6b2305859d7199e88a37c848fa1648da MD5 | raw file
  1. <?php
  2. /*
  3. K14 Decision Class -- based on k11.php but does not assign brandIndex or brandRater
  4. Assigns accountant to person
  5. Edgar Sioson
  6. */
  7. class K14 {
  8. function __construct($name='') {
  9. if (!$name) $name = 'K14';
  10. msgAddr($name, $this);
  11. }
  12. function rcv($Data) {
  13. if (!$Data) Error::halt("Invalid data: null or not in valid json.","K7");
  14. if ($Data['maxCycle']) return $this->init($Data);
  15. else if (is_numeric($Data['person_id'])) {
  16. if ($Data['loc'] == -1) return $this->setPerson($Data);
  17. else if (is_array($Data["F"]) AND min($Data["F"]) < 50) return $this->shop($Data);
  18. else if ($Data['nextAct'][0] == "C") return $this->shop($Data);
  19. }//else if ($Data['keys']) return $this->confirmAccess($Data);
  20. //else if (is_numeric($Data['linearTick'])) return $this->sync($Data);
  21. else {print_r($Data); Error::halt("No data received. [K10->rcv]");}
  22. }
  23. function init($Data) {
  24. $this->pwd = "k7po";
  25. $this->P = array();
  26. $this->IMMED_LOC = $Data['IMMED_LOC'];
  27. $locBeg = $Data['locBeg'];
  28. $this->acctant = $Data['acctant'];
  29. $this->inven = $Data['inven'];
  30. //$this->brandIndex = $Data['brandIndex']; intend to have K13 to not use any brand index
  31. $this->pQty = $Data['pQty'];
  32. $this->cQty = $Data['cQty'];
  33. $this->wQty = $Data['wQty'];
  34. $this->brandLocs = RandomInit::assignRsrcLocs($Data['numBrands'], $Data['locBeg'], $Data['numLocs'], $Data['brandPrefix'], $Data['brandSuffix']); //print_r($this->brandLocs); exit();
  35. if (!$_GET['cleanNoCleanIntervals']) exit("K14 requires a cleanNoCleanIntervals value. [K14->init]");
  36. list($cleanBrand,$noCleanBrand) = explode(".", $_GET['cleanNoCleanIntervals']);
  37. if (!is_numeric($cleanBrand) OR !is_numeric($noCleanBrand)) exit("Dot-separated values for cleanNoCleanIntervals value must be integers. [K14->init]");
  38. $posMarker= $cleanBrand;
  39. $currPos=1;
  40. $currBool = 1;
  41. foreach($this->brandLocs AS $brand => $items) {
  42. msg2way($this->acctant, array("do"=> "setLedger", "brand" => $brand, "pwd" => $this->pwd, "inventory"=>$this->inven, "brandIndex"=> $this->brandIndex, "minPN" => 0.7, "maxPN" => 1.5));
  43. foreach($items AS $rId => $locId) {
  44. msg2way($this->inven, array("do" => "setLoc", "brand" => $brand, "pwd" => $this->pwd, "locId" => $locId,
  45. "rsrcId" => $rId, "price"=>array("unitB"=>1)));
  46. msg2way("L$locId", array("do" => "setOwner", "owner" => $this->inven, "brand" => $brand, "pwd"=>$this->pwd));
  47. }
  48. $this->locAsCleaner[$brand] = $currBool;
  49. if ($currPos < $posMarker) $currPos++;
  50. else {
  51. $currPos = 1;
  52. if ($currBool) {
  53. $currBool = 0;
  54. $posMarker = $noCleanBrand;
  55. }
  56. else {
  57. $currBool = 1;
  58. $posMarker = $cleanBrand;
  59. }
  60. }
  61. }
  62. $this->members = RandomInit::assignMembers($this->brandLocs, $Data['personBeg'], $Data['numP']);
  63. }
  64. function setPerson($Data) {
  65. foreach($this->members AS $brand => $personArr) {
  66. foreach($personArr As $pId) {
  67. if ($Data['person_id'] == $pId) {
  68. msg2way($this->acctant, array("do"=> "addMember", "brand" => $brand, "pwd" => $this->pwd, "userId"=> "p".$pId));
  69. $rIds = array_keys($this->brandLocs[$brand]);
  70. shuffle($rIds);
  71. //in order to get the correct number of activities using the foreach loop below,
  72. //we need to adjust the number of resource Id's to 4
  73. $numIds = count($rIds);
  74. if ($numIds == 1) $rIds = array($rIds[0],$rIds[0],$rIds[0],$rIds[0]);
  75. else if ($numIds == 2) {
  76. $rIds[] = $rIds[0];
  77. $rIds[] = $rIds[1];
  78. }
  79. else if ($numIds == 3) $rIds[] = $rIds[0];
  80. else if ($numIds > 4) $rIds = array_slice($rIds, 0, 4);
  81. foreach($rIds AS $rId) {
  82. for($j=1; $j<7; $j++) {
  83. if ($j < 5) $cycle[] = array("P", $rId, $this->pQty, $this->brandLocs[$brand][$rId]);
  84. else if ($j == 5) $cycle[] = array("C", $rId, $this->cQty, $this->brandLocs[$brand][$rId]);
  85. else {
  86. if ($this->locAsCleaner[$brand]) $cycle[] = array("W", "", $this->wQty, $this->brandLocs[$brand][$rId]);
  87. else $cycle[] = array("P", $rId, $this->pQty, $this->brandLocs[$brand][$rId]);
  88. }
  89. }
  90. }
  91. foreach($this->brandLocs[$brand] AS $locId) {
  92. msg2way("L$locId", array("do"=> "setAccess", "type"=> "adder", "pwd"=>$this->pwd, "person_id" => $pId));
  93. $asAdder[] = $locId;
  94. }
  95. break 2;
  96. }
  97. }
  98. }
  99. return array("cycle" => $cycle, "loc" => $locId, "brand" => $brand, "asAdder"=>$asAdder, "brandRater"=> $this->brandIndex);
  100. }
  101. function shop(&$Person) {
  102. $fMin = min($Person["F"]);
  103. $keyMin = array_search($fMin, $Person["F"]);
  104. $fMax = max($Person["F"]);
  105. $keyMax = array_search($fMax, $Person["F"]);
  106. $tempAveF = 0;
  107. $H = array();
  108. //lump personal holding qty's by resource Id, i.e., pool qty's by expiration into one unexpired total
  109. foreach($Person['holding'] AS $rId => $qtyByExp) {
  110. $avail = 0;
  111. foreach($qtyByExp AS $exp =>$qty) {
  112. if ($qty) $avail += $qty;
  113. }
  114. if ($avail) $H[] = array("", 0, $rId, $avail, 1);
  115. }
  116. //create a reference array for Person keys, to be used later for conveniently searching for accesible resource locations
  117. //keys format {"keystr1": [ [locId,qty,levels(...)], [...], ..., [...] ], "keystr2": [ [], [], [] ] }
  118. $locKeys = array();
  119. foreach($Person['keys'] AS $key => $locsArr) {
  120. foreach($locsArr AS $arr) $locKeys[ $arr[0] ][] = array($key, $arr[1], $arr[2]);
  121. }
  122. $catalog = msg2way($this->inven, array("do" => "viewItems", "priceUnits"=>"unitB")); //print_r($catalog); exit();
  123. if (!is_array($catalog)) exit("Catalog should be an array(brand, loc, resourceId, qty). [K10]");
  124. $H = array_merge($H, $catalog);
  125. $Bals = msg2way($this->acctant,array("do"=>"getUserBal", "userId" => "p".$Person['person_id'], "units"=>"unitB")); //print_r($Bals); exit();
  126. if (!$Bals) return array("status" => "ok");
  127. $bal = max($Bals);
  128. foreach($H AS $arr) {
  129. $brand = $arr[0];
  130. $locId = $arr[1];
  131. $rId = $arr[2];
  132. $qty = $arr[3];
  133. $price = $arr[4];
  134. $rDigits = str_split($rId,1);
  135. for($i=0; $i < NUM_DIMENSIONS; $i++) {
  136. if ($rDigits[$i] == 0) $qtyByDigit[$i] = 0;
  137. else $qtyByDigit[$i] = floor((99 - $Person['F'][$i]) / $rDigits[$i]);
  138. }
  139. for($i=0; $i < NUM_DIMENSIONS; $i++) {
  140. if (!$qtyByDigit[$i]) $qtyByDigit[$i] = max($qtyByDigit);
  141. }
  142. $tempQty = min(min($qtyByDigit), $qty);
  143. for($i=0; $i < NUM_DIMENSIONS; $i++) $tempF[$i] = $Person['F'][$i] + $tempQty*$rDigits[$i];
  144. if ($tempQty>0 AND $price*$tempQty <= $bal) $options[min($tempF)][] = array($brand, $locId, $rId, $tempQty, $price);
  145. }
  146. if ($options) {
  147. krsort($options); //print_r($options); exit();
  148. foreach($options AS $optGrp) {
  149. //TO-DO: optimize farther by option that give highest average fitness
  150. foreach($optGrp AS $choice) {
  151. foreach($locKeys AS $locNum => $accessInfo) {
  152. if ($choice[1] == $locNum) { //see if person already has access to location by key
  153. if ($accessInfo[3] < 0) { //see if access level includes resource removal privileges
  154. $to_brand = $choice[0];
  155. $bestLoc = $choice[1];
  156. $bestHeld = $choice[2];
  157. $rQty = $choice[3];
  158. $price = $choice[4] * $choice[3];
  159. if ($accessInfo[1] == $choice[3]) return array("act"=>array("C", $choice[2], $choice[3], $locNum));
  160. else $tempQty = $choice[3] - $accessInfo[1];
  161. }
  162. else $tempQty = $choice[3];
  163. }
  164. }
  165. if (!$bestHeld) {
  166. $to_brand = $choice[0];
  167. $bestLoc = $choice[1];
  168. $bestHeld = $choice[2];
  169. $rQty = $choice[3];
  170. $price = $choice[4] * $choice[3];
  171. }
  172. if ($tempQty OR $rQty) { //try to obtain a key to gain access to location and remove needed resource quantity
  173. $from_brand = array_search($bal, $Bals);
  174. $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);
  175. if ($reply['status'] == "ok") {
  176. return array("act"=>array("C", $bestHeld, $rQty, $bestLoc), "claimKey" => $reply['claimKey'], "loc"=>$bestLoc, "qty" => -$rQty);
  177. }
  178. else {
  179. foreach($reply['reasons'] AS $reason) {
  180. if ($reason == "PNratio") {
  181. return array("status"=>"rejected"); //array("act"=>array("W", $reply['wasteId'], $rQty, $reply['wasteLoc']));
  182. }
  183. else {
  184. return array("status"=>"rejected");
  185. }
  186. }
  187. }
  188. }
  189. }
  190. }
  191. } else return array("status" => "ok"); //("No options. [K10->shop]");
  192. if (!$bestHeld) {print_($Person); exit("k13->shop");}
  193. }
  194. }
  195. if ($_GET['test']) {
  196. header("content-type: text/plain");
  197. $k11n = "K11";
  198. $K11 = new K11();
  199. $K11->rcv(array("maxCycle"=>30, "IMMED_LOC" => 30, "locBeg" => 0));
  200. $K11->rcv(array("person_id"=>1));
  201. $K11->rcv(array("person_id"=>6));
  202. if ($K11>rcv(array("loc"=>1,"keys"=>array("m_1" => 20)))) echo "\nAccess confirmed\n"; else echo "\nAccess denied\n";
  203. //$K7->rcv(array("linearTick"=1);
  204. echo "\nmem_usage= ". memory_get_usage() ."\n";
  205. print_r($K11);
  206. }
  207. ?>