PageRenderTime 41ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/decision/k12r.php

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