public function canLoadObserver($event) { if (!($current_tuple = $event->getPointSequence())) { throw new Exception('Event ' . $event->getName() . 'does not have "point_sequence" param!'); } if (!($candidate = $event->getPoint())) { throw new Exception('Event ' . $event->getName() . 'does not have "point_sequence" param!'); } $pointSequence = array_merge(Helper::getPointSequenceFromTuple($current_tuple), [$candidate]); $checkLoading = $this->getPrecise() == 100 ? false : rand(0, 100) < $this->getData('check_transitional_loading_probability') && $this->_lastPointIsPickup($pointSequence); // if needed, check 3D constraints $event->getResultContainer()->result = $checkLoading ? $this->canLoad($pointSequence) : true; }
protected function _generateNestedPointSequences($node) { $pointSequence = $node->getContent()->getPoints(); $generator = new Generator(['tuple_length' => Point::getPointCount($this->getPoints()), 'generating_elements' => Helper::getGeneratorDataFromPoints($this->getPoints()), 'current_path' => $node->getContent(), 'weight_capacity' => $this->getWeightCapacity(), 'load_area' => $this->getLoadArea()]); // $generator->validate(); $points = Helper::getGeneratorDataFromPoints($pointSequence); $result = Helper::getPointSequencesFromGeneratorData($generator->generateNextObjects($points)); if ($result) { // hack: if all PDP points except of depot are present, add depot $nodeHasAllPointsExceptOfDepot = Helper::pointSequenceIncludesAllPickupsAndDeliveries(reset($result), $this->getPoints()); if ($nodeHasAllPointsExceptOfDepot) { foreach ($result as &$resultPointSequence) { $resultPointSequence = array_merge($resultPointSequence, [$this->getDepot()]); } } } return $result; }
protected function _getSuccessiveElements($tuple) { $result = []; // we assume that tuple contain \Litvinenko\Combinatorics\Pdp\Point objects $currentPath = $this->_getCurrentPath($tuple); foreach ($this->getGeneratingElements() as $element) { $point = $element['value']; // if current path does not contain this point if (!$currentPath->doesContain($point)) { // add pickup point if whether vehicle can take box at this point if ($point->isPickup() && $currentPath->getCurrentWeight() + $point->getBoxWeight() <= $this->getWeightCapacity() && $currentPath->getCurrentVolume() + $point->getBoxVolume() <= Helper::getLoadAreaVolume($this->getLoadArea()) || $point->isDelivery() && $currentPath->doesContain($point->getPairId())) { $resultContainer = new \stdClass(); // event observers will write info to this object App::dispatchEvent('point_add_before', ['point' => $point, 'point_sequence' => $tuple, 'result_container' => $resultContainer]); if (!isset($resultContainer->result) || isset($resultContainer->result) && $resultContainer->result !== false) { $result[] = $element; } } } } return $result; }