/decision/k6.php
PHP | 311 lines | 190 code | 52 blank | 69 comment | 57 complexity | 16b331583369b9c86ef1a2b8384f5a1f MD5 | raw file
- <?php
- /*
- More intelligent decision engine that uses infrastructure module components
- Uses OCAUP accounting by brand
- Edgar Sioson
- 10/24/2011
- */
-
- header("content-type: text/plain");
- if ($_POST) $_GET = $_POST;
-
- $ledger = "k6";
- $pwd = "k6po";
- $IMMED_LOC = 30;
- $locBeg = 1;
- $pId = 0;
-
- $brandLocs = array(
- "abc.org" => array("0001"=>$locBeg+17, "2100"=>$locBeg+18, "2010"=>$locBeg+19, "2001"=>$locBeg+20),
- "def.com" => array("0010"=>$locBeg+21, "1200"=>$locBeg+22, "0210"=>$locBeg+23, "0201"=>$locBeg+24),
- "ghi.gov" => array("0100"=>$locBeg+25, "1020"=>$locBeg+26, "0120"=>$locBeg+27, "0021"=>$locBeg+28),
- "mno.edu" => array("1000"=>$locBeg+29, "1002"=>$locBeg+30, "0102"=>$locBeg+31, "0012"=>$locBeg+32)
- );
-
-
- if ($_GET['maxCycle']) { //set up ledger
- postHTTP("http://127.0.0.1/flora/infras/ocaup.php","ledger=$ledger&pwd=$pwd&brandLocs=". urlencode(json_encode($brandLocs)));
- exit('{"status":"ok"}');
- }
- else if (is_numeric($_GET['linearTick'])) {
- $locsToCheck = $locBeg+17;
- for($i=18; $i<33; $i++) $locsToCheck .= ",". ($locBeg+$i);
-
- //pay wages to location contributors
- postHTTP("http://127.0.0.1/flora/infras/ocaup.php","ledger=$ledger&pwd=$pwd&from=locs&locsToCheck=$locsToCheck");
-
- //purchase soon-to-be consumed resources
- include "k6_purchase.php"; //print_r($D);
-
- exit(json_encode(array("status"=>"ok", "data"=>$D)));
- }
- else if (is_numeric($_GET['person_id'])) { //set up activity cycle for person
- $person_id = $_GET['person_id'];
-
- include "k6_initCycle.php";
- }
- else {
- $jsondata = file_get_contents("php://input");
-
- $Person = json_decode($jsondata); //print_r($Person);
- if (!$Person) exit(json_encode(array("status"=>"error","message"=>$_GET)));
-
- if (is_array($Person->F)) $fitness = floor(array_sum($Person->F)/4);
- $fMin = min($Person->F);
-
- $pCache = json_decode(file_get_contents("cache/". $Person->id));
- if (!$pCache) exit(json_encode(array("status"=>"error")));
-
- $locRef = json_decode(file_get_contents("cache/k4_locRef"));
-
- $Accts = postHTTP("http://127.0.0.1/flora/infras/ocaup.php?ledger=$ledger&pwd=$pwd&acctId=$Person->id");
- if ($Accts->acctId != $Person->id) exit("k6 170: ". json_encode($Accts));
-
- //this part adjusts a person's cycle if the person's token balance falls below a certain amount
- //which indicates that the person produces something that is not selling
- /*if ($Accts->balance < 200) {
- $mostQty = 0;
-
- //determine what resource this person uses a lot
- foreach($pCache->interrupts AS $rId=>$qty) {
- if ($qty > $mostQty) {
- $mostQty = $qty;
- $mostUsed = $rId;
- }
- }
-
- //these are candidate cycle positions representing resources
- //that could be swapped for resources that are used more often
- $leastUsed = array(15,0,3,6,9,12);
-
-
- if (!is_array($pCache->swap)) $cyclePos = 15;
- else {
- foreach($leastUsed AS $pos) {
- if (!in_array($cyclePos, $pCache->swap)) {
- $cyclePos = $pos;
- break;
- }
- }
- }
-
- if ($cyclePos AND $mostUsed) {
- $locNum = $rLocs[$mostUsed];
- $pCache->cycle[$cyclePos] = array("P", $mostUsed, $pQty, $locNum);
- $pCache->cycle[$cyclePos+1] = array("P", $mostUsed, $pQty, $locNum);
- $pCache->cycle[$cyclePos+2] = array("C", $mostUsed, $cQty, $locNum);
-
- $pCache->swap[] = $cyclePos;
-
- $pCache->interrupts->$mostUsed=0;
- file_put_contents("cache/". $Person->id, json_encode($pCache));
-
- if (!in_array($Person->id, $locRef->$locNum)) array_push($locRef->$locNum, $Person->id);
- $cycle = $pCache->cycle;
-
- file_put_contents("cache/". $Person->id, json_encode(array(
- "interrupts"=>$pCache->interrupts,
- "cycle"=>$cycle,
- "swap" =>$pCache->swap
- )));
- }
- } */
-
- if ($fMin < 50) {
- $keyMin = array_search($fMin, $Person->F);
-
- $fMax = max($Person->F);
- $keyMax = array_search($fMax, $Person->F);
- $tempAveF = 0;
-
- //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) { //echo "\n117 $rId $qtyByExp";
- $avail = 0;
-
- foreach($qtyByExp AS $exp =>$qty) {
- if ($qty) $avail += $qty;
- }
-
- if ($avail) $H[] = array("", 0, $rId, $avail);
- }
-
- $H = array();
-
- //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) {
- if (strpos($arr[2],"r") !== false) $locKeys[ $arr[0] ][] = array($key, $arr[1], $arr[2]);
- }
- }
-
- //locations to check will be all locations known to decision engine
- $locsToCheck = $locBeg;
- for($i=1; $i<16; $i++) $locsToCheck .= ",". ($locBeg+$i);
-
- if ($locsToCheck) {
- $reply = file_get_contents("http://127.0.0.1/flora/infras/ocaup.php?ledger=$ledger&pwd=$pwd&catalog=all");
- $Reply = json_decode($reply);
- if ($Reply AND $Reply->catalog) { //Reply->catalog item format: [brand, locId, rsrcId, qty]
- foreach($Reply->catalog AS $item) {
- if ($item[3] > 0) $H[] = $item;
- }
- }
- }
-
- //find viable options for resource consumption including personal + ** advertised location holdings **
- foreach($H AS $arr) {
- $to_brand = $arr[0];
- $locId = $arr[1];
- $rId = $arr[2];
- $qty = $arr[3];
-
- $rDigits = str_split($rId,1);
-
- for($i=0; $i<4; $i++) {
- if ($rDigits[$i] == 0) $qtyByDigit[$i] = "";
- else $qtyByDigit[$i] = floor((99 - $Person->F[$i]) / $rDigits[$i]);
- }
-
- for($i=0; $i<4; $i++) {
- if ($qtyByDigit[$i] == "") $qtyByDigit[$i] = max($qtyByDigit);
- }
-
- $tempQty = min(min($qtyByDigit), $qty);
- for($i=0; $i<4; $i++) $tempF[$i] = $Person->F[$i] + $tempQty*$rDigits[$i];
-
- //$currMinF = min($tempF); //echo "\n$rId $tempQty aveF: $currAveF vs $tempAveF ";
-
- $options[min($tempF)][] = array($to_brand, $locId, $rId, $tempQty);
- }
-
- //Select from options; if applicable, try to purchase resource
- //in contrast to other decision engines, k2 factors access by key and potential reputation/payment constraints
- if ($options) {
- krsort($options);
-
- foreach($options AS $optGrp) {
- foreach($optGrp AS $choice) {
- $to_brand = $choice[0];
- $locId = $choice[1];
- $rId = $choice[2];
- $qty = $choice[3];
-
- if (!$to_brand) { //indicates personal holding
- $bestLoc = "";
- $bestHeld = $rId;
- $rQty = $qty;
- break 2;
- }
- else {
- foreach($locKeys AS $key=> $locArr) {
- foreach($locArr AS $locNum => $accessInfo) {
- if ($locId == $locNum) { //see if person already has access to location by key
- if (strpos($accessInfo[2],"r") !== false) { //see if access level includes resource removal privileges
- if ($accessInfo[1] == "*" OR $accessInfo[1] >= $choice[2]) {
- $bestLoc = $locNum;
- $bestHeld = $rId;
- $rQty = $qty;
- break 2;
- }
- else {
- $claimKey = $accessInfo[0];
- $tempQty = $qty - $accessInfo[1];
- }
- } else {echo "\nk6 215"; print_r($accessInfo);}
- }
- }
- }
-
- if (!$rQty) {
- if (!$tempQty) $tempQty = $qty;
-
- $balance = 0;
- $from_brand = '';
- if (is_object($Accts->balance)) {
- foreach($Accts->balance AS $fbrand => $bal) { $fBrandList[] = $fbrand;
- if ($bal > $balance) {
- $balance = $bal;
- $from_brand = $fbrand;
- }
- }
- }
-
- if ($balance >= $tempQty AND $from_brand) { //pay for access
- $bestLoc = $locId;
- $bestHeld = $rId;
- $rQty = $tempQty; //not tempQty since tempQty just tops off existing remover access
-
- //submit request to flora to grant key-based access to locations
- if (!$claimKey) $claimKey = mt_rand(0,1000) ."_". $Person->id;
- $keyInfo = array($claimKey, $locId, $rQty, "r");
-
- $context = stream_context_create(array("http"=>array(
- "timeout" => 1,
- "content" => json_encode(array("$locId" => array("remover" => array( $claimKey=> $rQty))))
- )));
-
- $reply = file_get_contents("http://127.0.0.1/flora/loc.php",false,$context); $locReply = json_decode($reply);
- if (!$locReply OR $locReply->status != "ok") echo "\n247 $reply";
-
- //debit and credit accounts
- postHTTP("http://127.0.0.1/flora/infras/ocaup.php","ledger=$ledger&pwd=$pwd&from=$from_brand&from_acct=".$Person->id."&to=$to_brand&amount=$tempQty&locQty=$locId,$rQty");
- break 2;
- }
- }
- }
- }
- }
- }
-
- //prepare decision response
- if ($bestHeld AND $rQty AND $rQty > 0) {
- $act = array("C","$bestHeld",$rQty,$bestLoc);
- $pCache->interrupts->$bestHeld += $rQty;
-
- file_put_contents("cache/". $Person->id, json_encode($pCache));
-
- //to-do: submit key to allow person to remove quantity from a location
- }
- else {
- $act = $pCache->cycle[$Person->currTick];
- }
-
- $D = array("person_id" => $Person->id, "act" => $act, "key" => $keyInfo, "cycle" => $cycle);
- }
- else {
- $act = $pCache->cycle[$Person->currTick];
- $D = array("person_id" => $Person->id, "act" => $act);
- }
-
- if (!$act) $D = array("person_id" => $Person->id, "act" => $pCache->cycle[$Person->currTick]);
- }
-
- echo json_encode(array("status"=>"ok", "data"=> $D));//, "jsondata"=> $jsondata));
-
- if ($_GET['test'] AND $D['act'][0] == "C") {
- echo "\n\nOld fitness: ". json_encode($Person->F);
- echo "\nNew fitness: ";
- $i=0;
- foreach($Person->F AS $f) {
- echo $f + $D['act'][2]*substr($D['act'][1],$i,1) ." ";
- $i++;
- }
- }
-
- function postHTTP($url, $data='') {
- if ($data) $context = stream_context_create(array("http" => array("timeout"=>1,"content"=>$data,"method" => "POST")));
- else $context = stream_context_create(array("http" => array("timeout"=>1,"content"=>"","method" => "POST")));
-
- $reply = file_get_contents($url,false,$context);
- $Reply = json_decode($reply);
- if (!$Reply OR $Reply->status != "ok") {
- echo "\ntrace: $trace "; global $Accts; print_r($Accts); global $from_brand; echo " $from_brand "; global $to_brand ; echo " $to_brand "; global $fBrandList; print_r($fBrandList);
- exit("300 k6 call to $url: ". $reply ." --$fbrand-- $data ");
- }
-
- return $Reply;
- }
-
- ?>