Advertisement
petrabarus

Untitled

Sep 3rd, 2011
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 13.27 KB | None | 0 0
  1. class Run {
  2.     function run(){
  3.         $databook = DataBook::load('book1.xlsx');
  4.         $orders = $databook->orders;
  5.         $workCenters = $databook->workCenters;
  6.         $countOperations = $databook->countOperations;
  7.         $countPeriods = $databook->countPeriods;
  8.         $loadPercentage = $databook->loadPercentage;
  9.         $initialTable = array(
  10.             'ordersTable' => $this->renderPartial('_orders', array(
  11.                 'orders' => $orders,
  12.                 'countOperations' => $countOperations,
  13.                 'releaseCode' => false,
  14.                 'tableId' => 'initialOrders'
  15.                     ), true),
  16.             'workCentersTable' => $this->renderPartial('_workCenters', array(
  17.                 'workCenters' => $workCenters,
  18.                 'countPeriods' => $countPeriods,
  19.                 'tableId' => 'initialWorkCenters'
  20.                     ), true),
  21.         );
  22.  
  23.         $pool = new Pool();
  24.         $pool->init($workCenters);
  25.         $periods = array();
  26.         $stop = false;
  27.         $totalCountPeriods = 0;
  28.         Order::initAllLoadPercentage($orders, $loadPercentage);
  29.         while (!$stop) {
  30.             $totalCountPeriods++;
  31.             //Start working
  32.             $loadLimits = $databook->getLoadLimitsAtPeriod($totalCountPeriods - 1);
  33.             $capacityLimits = $databook->getCapacityLimitsAtPeriod($totalCountPeriods - 1, true);
  34.             Order::reinitTaskStatus($orders);
  35.             $snapshot = '';
  36.             $pool->checkRelease($orders, $loadLimits, $capacityLimits, $totalCountPeriods);
  37.  
  38.             $periods[] = array(
  39.                 'orderTable' => $this->renderPartial('_orders', array(
  40.                     'orders' => $orders,
  41.                     'countOperations' => $countOperations,
  42.                     'releaseCode' => true,
  43.                     'tableId' => 'period' . $totalCountPeriods,
  44.                         ), true),
  45.                 'poolTable' => $this->renderPartial('_pool', array(
  46.                     'pool' => $pool,
  47.                     'tableId' => 'pool' . $totalCountPeriods,
  48.                     'loadLimits' => $databook->getLoadLimitsAtPeriod($totalCountPeriods - 1),
  49.                     'capacityLimits' => $databook->getCapacityLimitsAtPeriod($totalCountPeriods - 1),
  50.                         ), true),
  51.             );
  52.             $pool->pullDownTasks($orders, $loadLimits, $capacityLimits, $totalCountPeriods);
  53.  
  54.             $stop = $totalCountPeriods == 3;
  55.             $capacityLimits = $databook->getCapacityLimitsAtPeriod($totalCountPeriods - 1, false);
  56.             $pool->forwardTimeLine($capacityLimits);
  57.             //echo "$totalCountPeriods <<< =====================================\n";
  58.             //print_r($orders);
  59.             $pool->releaseAvailableFirsTask($orders, $loadPercentage);
  60.            
  61.         }
  62.         //
  63.         $this->render('run', array(
  64.             'initialTables' => $initialTable,
  65.             'periods' => $periods,
  66.             'countOperations' => $countOperations,
  67.             'countPeriods' => $countPeriods,
  68.             'totalCountPeriods' => $totalCountPeriods,
  69.         ));
  70.     }
  71. }
  72.  
  73. class Order {
  74.     const RELEASE_CODE_NOT_RELEASE = 'X';
  75.     const RELEASE_CODE_RELEASE = 'R';
  76.     const RELEASE_CODE_OPEN = 'O';
  77.  
  78.     public $name;
  79.     public $plannedStartDate;
  80.     public $tasks;
  81.     public $releaseCode;
  82.  
  83.     public function getTask($idx) {
  84.         return (isset($this->tasks[$idx])) ? $this->tasks[$idx] : NULL;
  85.     }
  86.  
  87.     public function getTaskByWCName($name) {
  88.         foreach ($this->tasks as &$task) {
  89.             if ($task->workCenter == $name) {
  90.                 return $task;
  91.             }
  92.         }
  93.         return NULL;
  94.     }
  95.  
  96.     public function attributeNames() {
  97.         return array();
  98.     }
  99.  
  100.     public function popFront() {
  101.         array_shift($this->tasks);
  102.     }
  103.  
  104.     public static function flatten($orders, $countOperations) {
  105.         $array = array();
  106.         foreach ($orders as $order) {
  107.             $arorder = array();
  108.             $arorder['name'] = $order->name;
  109.             $arorder['plannedStartDate'] = $order->plannedStartDate;
  110.             for ($i = 0; $i < $countOperations; $i++) {
  111.                 if (($task = $order->getTask($i)) !== NULL) {
  112.                     $arorder['tasks'][] = array(
  113.                         'hours' => $task->hours,
  114.                         'workCenter' => $task->workCenter,
  115.                     );
  116.                 } else {
  117.                     $arorder['tasks'][] = array(
  118.                         'hours' => '',
  119.                         'workCenter' => '',
  120.                     );
  121.                 }
  122.             }
  123.             $array[] = $arorder;
  124.         }
  125.         return $array;
  126.     }
  127.  
  128.     public function initLoadPercentage($loadPercentage) {
  129.         foreach ($this->tasks as $i => &$task) {
  130.             $ii = (($i + 1) * 2) + 1;
  131.             $task->hours = $task->hours * pow((100 / $loadPercentage), (($ii + 1) / 2) - 2);
  132.         }
  133.     }
  134.  
  135.     public function isEmpty() {
  136.         return count($this->tasks) == 0;
  137.     }
  138.  
  139.     public function getCssClass() {
  140.         if (isset($this->releaseCode)) {
  141.             switch ($this->releaseCode) {
  142.                 case self::RELEASE_CODE_RELEASE:
  143.                     return 'release';
  144.                 case self::RELEASE_CODE_NOT_RELEASE:
  145.                     return 'not_release';
  146.                 case self::RELEASE_CODE_OPEN:
  147.                     return 'open';
  148.                 default:
  149.                     return '';
  150.             }
  151.         } else {
  152.             return '';
  153.         }
  154.     }
  155.  
  156.     public static function initAllLoadPercentage(&$orders, $loadPercentage) {
  157.         foreach ($orders as &$order) {
  158.             $order->initLoadPercentage($loadPercentage);
  159.         }
  160.     }
  161.  
  162.     public static function sortByDate(&$orders) {
  163.         uasort($orders, function($a, $b) {
  164.                     return (($a->plannedStartDate == $b->plannedStartDate) ? 0 : (($a->plannedStartDate > $b->plannedStartDate) ? +1 : -1));
  165.                 });
  166.     }
  167.  
  168.     public static function reinitTaskStatus(&$orders) {
  169.         foreach ($orders as &$order) {
  170.             foreach ($order->tasks as &$task) {
  171.                 $task->status = NULL;
  172.             }
  173.         }
  174.     }
  175.  
  176. }
  177.  
  178. class Pool {
  179.  
  180.     public $workCenters = array();
  181.  
  182.     public function init($workCenters) {
  183.         $this->workCenters = array();
  184.         foreach ($workCenters as $workCenter) {
  185.             $ws = new PoolWorkCenter();
  186.             $ws->name = $workCenter->name;
  187.             //adding leftover
  188.             $leftOver = new PoolTask($workCenter->name, 0, $workCenter->leftOver);
  189.             $leftOver->type = PoolTask::TYPE_LEFTOVER;
  190.             $ws->putTask($leftOver);
  191.             $this->workCenters[] = $ws;
  192.         }
  193.     }
  194.  
  195.     public function getWorkCenterByName($name) {
  196.         foreach ($this->workCenters as &$workcenter) {
  197.             if ($workcenter->name == $name) {
  198.                 return $workcenter;
  199.             }
  200.         }
  201.     }
  202.  
  203.     public function getTaskByTID($tId) {
  204.         foreach ($this->workCenters as &$workcenter) {
  205.             foreach ($workcenter->tasks as &$p) {
  206.                 if ($p->tId == $tId) {
  207.                     return $p;
  208.                 }
  209.             }
  210.         }
  211.         return NULL;
  212.     }
  213.  
  214.     public function getMaximumTaskCount() {
  215.         $max = 0;
  216.         foreach ($this->workCenters as $ws) {
  217.             $max = ($max < $ws->getTaskCount()) ? $ws->getTaskCount() : $max;
  218.         }
  219.         return $max;
  220.     }
  221.  
  222.     public function getWorkCenterCount() {
  223.         return count($this->workCenters);
  224.     }
  225.  
  226.     public function forwardTimeLine($arCapacity) {
  227.         foreach ($this->workCenters as $i => $ws) {
  228.             $time = isset($arCapacity[$i]) ? $arCapacity[$i] : 0;
  229.             $ws->forwardTimeLine($time);
  230.         }
  231.     }
  232.  
  233.     public function checkRelease(&$orders, $loadLimits, $capacityLimits, $period) {
  234.         $loads = array();
  235.         $loads2 = array();
  236.         $loads3 = array();
  237.         foreach ($this->workCenters as $m => $pws) {
  238.             $loads[$m] = $pws->getEndTime();
  239.             $loads2[$pws->name] = $pws->getLoad();
  240.             $loads3[$pws->name] = $pws->getLoad();
  241.         }
  242.         foreach ($orders as $k => &$order) {
  243.             if (!$order->isEmpty() && ($order->releaseCode == Order::RELEASE_CODE_RELEASE || $order->releaseCode == Order::RELEASE_CODE_OPEN)) {
  244.                 $order->releaseCode = Order::RELEASE_CODE_OPEN;
  245.                 continue;
  246.             }
  247.             $flag = true;
  248.             //echo $order->name . '   ';
  249.             foreach ($this->workCenters as $m => $pws) {
  250.                 $ptask = $order->getTaskByWCName($pws->name);
  251.                 if ($ptask != NULL) {
  252.                     $load = $loads[$m];
  253.                     //echo $ptask->hours . ' ' . $load . ' ' . $loadLimits[$m] . " -- ";
  254.                     $flag = $flag && ($load < $loadLimits[$m]);
  255.                 } else {
  256.                     $load = $loads[$m];
  257.                     //echo 0 . ' ' . $load . ' ' . $loadLimits[$m] . " -- ";
  258.                 }
  259.             }
  260.  
  261.             //echo $flag . ' -- ';
  262.             //echo "\n";
  263.  
  264.             foreach ($this->workCenters as $m => $pws) {
  265.                 if ($flag) {
  266.                     $otask = $order->getTaskByWCName($pws->name);
  267.                     if ($otask != NULL) {
  268.                         $newTask = new PoolTask($pws->name, $loads[$m], $otask->hours, $order->name);
  269.                         $newTask->tId = $otask->tId;
  270.                         $pws->putTask($newTask);
  271.                         $loads[$m] = $loads[$m] + $otask->hours;
  272.                     } else {
  273.                         $loads[$m] = $loads[$m] + 0;
  274.                     }
  275.                     $order->releaseCode = Order::RELEASE_CODE_RELEASE;
  276.                 } else {
  277.                     $order->releaseCode = Order::RELEASE_CODE_NOT_RELEASE;
  278.                 }
  279.             }
  280.         }
  281.         $idx = 0;
  282.         foreach ($orders as &$order) {
  283.             if ($order->releaseCode == Order::RELEASE_CODE_RELEASE || $order->releaseCode == Order::RELEASE_CODE_OPEN) {
  284.                 $task = $order->getTask(0);
  285.                 if ($task != NULL) {
  286.                     //echo $task->workCenter . ") " . $loads2[$task->workCenter] . ' ' . $task->hours . ' ' . $capacityLimits[$task->workCenter] . "\n";
  287.                     if ($loads2[$task->workCenter] < $capacityLimits[$task->workCenter]) {
  288.                         $task->status = Task::STATUS_PHYSICALLY_AVAILABLE;
  289.                         if ($loads3[$task->workCenter] < $capacityLimits[$task->workCenter]) {
  290.                             $task->status = Task::STATUS_WORKABLE;
  291.                             $loads3[$task->workCenter] += $task->hours;
  292.                         }
  293.                     }
  294.                 }
  295.             }
  296.         }
  297.  
  298.         //$this->pullDownTasks($orders, $loadLimits, $capacityLimits, $period);
  299.     }
  300.  
  301.     public function evaluate(&$orders, $loadLimits, $capacityLimits, $period) {
  302.         //evaluate
  303.     }
  304.  
  305.     public function pullDownTasks(&$orders, $loadLimits, $capacityLimits, $period) {
  306.         foreach ($orders as &$order) {
  307.             foreach ($order->tasks as $task) {
  308.                 if ($task->status == TASK::STATUS_WORKABLE) {
  309.                     $pws = $this->getWorkCenterByName($task->workCenter);
  310.                     $pws->pullDownTask($task);
  311.                 }
  312.             }
  313.         }
  314.     }
  315.  
  316.     public function releaseAvailableFirsTask(&$orders, $loadPercentage) {
  317.         $tIds = array();
  318.         foreach ($orders as &$order) {
  319.             $idx = 0;
  320.             $task = $order->getTask($idx);
  321.             if (isset($task) && $task->status == Task::STATUS_WORKABLE) {
  322.                 $ptask = $this->getTaskByTID($task->tId);
  323.                 if (isset($ptask) && $ptask->end <= 0) {
  324.                     array_shift($order->tasks);
  325.                     foreach ($order->tasks as $i => &$tt) {
  326.                         $ii = (($i + 1) * 2) + 1;
  327.                         $tt->hours = $tt->hours * pow(($loadPercentage / 100), (($ii + 1) / 2) - 1);
  328.                         $ii = (($i + 1) * 2) + 1;
  329.                         $tt->hours = $tt->hours * pow((100 / $loadPercentage), (($ii + 1) / 2) - 2);
  330.                         $tIds[] = array(
  331.                             'id' => $tt->tId,
  332.                             'newHours' => $tt->hours,
  333.                         );
  334.                     }
  335.                 }
  336.             }
  337.         }
  338.         $this->resyncTasks($tIds);
  339.     }
  340.  
  341.     public function resyncTasks($tIds) {
  342.         foreach ($tIds as $tId) {
  343.             $ptask = $this->getTaskByTID($tId['id']);
  344.             if ($ptask != NULL) {
  345.                 $ptask->hours = $tId['newHours'];
  346.             }
  347.         }
  348.         $this->fixTimeLine();
  349.     }
  350.  
  351.     public function fixTimeLine() {
  352.         foreach ($this->workCenters as &$ws) {
  353.             $ws->fixTaskTimeline();
  354.         }
  355.     }
  356.  
  357. }
  358.  
  359. class PoolTask {
  360.     const TYPE_TASK = 0;
  361.     const TYPE_LEFTOVER = 1;
  362.     const TYPE_IDLE = 2;
  363.  
  364.     public $orderName = NULL;
  365.     public $hours = '';
  366.     public $workCenterName = '';
  367.     public $start = 0;
  368.     public $end = 0;
  369.     public $type = self::TYPE_TASK;
  370.     public $tId;
  371.  
  372.     public function __construct($workCenterName, $start, $hours, $orderName = NULL) {
  373.         $this->workCenterName = $workCenterName;
  374.         $this->start = $start;
  375.         $this->hours = $hours;
  376.         $this->end = $this->start + $hours;
  377.         $this->orderName = $orderName;
  378.     }
  379.  
  380. }
  381.  
  382. class PoolWorkCenter {
  383.  
  384.     public $name;
  385.     public $tasks = array();
  386.  
  387.     public function putTask($task) {
  388.         $this->tasks[] = $task;
  389.     }
  390.  
  391.     public function getTask($idx) {
  392.         return (isset($this->tasks[$idx])) ? $this->tasks[$idx] : NULL;
  393.     }
  394.  
  395.     public function hasTaskAt($idx) {
  396.         return (isset($this->tasks[$idx]));
  397.     }
  398.  
  399.     public function getTaskCount() {
  400.         return count($this->tasks);
  401.     }
  402.  
  403.     public function getEndTime() {
  404.         $endTask = $this->tasks[count($this->tasks) - 1];
  405.         return $endTask->end;
  406.     }
  407.  
  408.     public function getLoad() {
  409.         $stop = false;
  410.         $i = 0;
  411.         while (!$stop) {
  412.             $retval = $this->tasks[$i]->end;
  413.             if ($retval > 0) {
  414.                 $stop = true;
  415.             } else {
  416.                 $i++;
  417.             }
  418.         }
  419.         return $retval;
  420.     }
  421.  
  422.     public function forwardTimeLine($time) {
  423.         foreach ($this->tasks as $task) {
  424.             $task->start -= $time;
  425.             $task->end -= $time;
  426.         }
  427.     }
  428.  
  429.     public function pullDownTask($task) {
  430.         $tId = $task->tId;
  431.         $idx = 0;
  432.         for ($i = 0; $i < count($this->tasks); $i++) {
  433.             $ttask = $this->tasks[$i];
  434.             if ($ttask->tId == $tId) {
  435.                 $idx = $i;
  436.                 break;
  437.             }
  438.         }
  439.         while ($idx > 0 && $this->getTask($idx - 1)->start > 0) {
  440.             $temp = $this->tasks[$idx - 1];
  441.             $this->tasks[$idx - 1] = $this->tasks[$idx];
  442.             $this->tasks[$idx] = $temp;
  443.             $idx--;
  444.         }
  445.         //fixing
  446.         $this->fixTaskTimeline();
  447.     }
  448.  
  449.     public function fixTaskTimeline() {
  450.         $ttask = $this->tasks[0];
  451.         $ttask->end = $ttask->start + $ttask->hours;
  452.         for ($i = 1; $i < count($this->tasks); $i++) {
  453.             $curtask = $this->tasks[$i];
  454.             $lasttask = $this->tasks[$i - 1];
  455.             $curtask->start = $lasttask->end;
  456.             $curtask->end = $curtask->start + $curtask->hours;
  457.         }
  458.     }
  459.  
  460. }
  461.  
  462. class Task {
  463.     const STATUS_PHYSICALLY_AVAILABLE = 'P';
  464.     const STATUS_WORKABLE = 'W';
  465.  
  466.  
  467.     public $hours;
  468.     public $workCenter;
  469.     public $tId;
  470.     public $status = NULL;
  471.     public static $count;
  472.  
  473.     public function __construct() {
  474.         $this->tId = ++self::$count;
  475.     }
  476.  
  477.     public function getCssClass() {
  478.         if ($this->status != NULL) {
  479.             switch ($this->status) {
  480.                 case self::STATUS_PHYSICALLY_AVAILABLE:
  481.                     return 'tp';
  482.                 case self::STATUS_WORKABLE:
  483.                     return 'tw';
  484.             }
  485.         }
  486.     }
  487.  
  488. }
  489.  
  490. class WorkCenter {
  491.  
  492.     public $name;
  493.     public $leftOver;
  494.     public $periods;
  495.  
  496.     public function getPeriod($idx) {
  497.         return (isset($this->periods[$idx])) ? $this->periods[$idx] : NULL;
  498.     }
  499.  
  500.     public function getCapacityLimitAtPeriod($idx) {
  501.         return isset($this->periods[$idx]) ? $this->getPeriod($idx)->capacityLimit : 0;
  502.     }
  503.  
  504.     public function getLoadLimitAtPeriod($idx) {
  505.         return isset($this->periods[$idx]) ? $this->getPeriod($idx)->loadLimit : 0;
  506.     }
  507.  
  508. }
  509.  
  510. class WorkCenterPeriod {
  511.  
  512.     public $capacityLimit;
  513.     public $loadLimit;
  514.  
  515. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement