PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/decision/k11.php

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