public function getSolution() { $rootNode = new Node(); $initialNode = new Node(['active' => true, 'content' => $this->getInitialNodeContent(), 'optimistic_bound' => $this->getInitialNodeOptimisticBound(), 'pessimistic_bound' => $this->getInitialNodePessimisticBound()]); $rootNode->addChild($initialNode); $activeNodes = [$initialNode]; $currentBestFullNode = $initialNode; $i = 0; while ($activeNodes) { $i++; if ($i == 202) { $a = 2; } $this->_logEvent('step_begin', ['root_node' => $rootNode, 'active_nodes' => $activeNodes, 'current_best_full_node' => $currentBestFullNode]); $branchingNode = $this->_getBestNodeFrom($activeNodes); $branchingNode->setActive(false); $this->_logEvent('step_branching_begin', ['root_node' => $rootNode, 'branching_node' => $branchingNode]); $children = $this->_generateChildrenOf($branchingNode); $branchingNode->setChildren($children); $this->_logEvent('step_branching_children_generated', ['root_node' => $rootNode, 'branching_node' => $branchingNode, 'children_generated' => $children]); foreach ($branchingNode->getChildren() as $newNode) { // if new node is better (or has better evaluation) than current best node if ($this->_compareNodes($newNode, $currentBestFullNode) > -1 && $this->_nodeIsCorrect($newNode)) { if ($this->_nodeIsCompleteSolution($newNode)) { $currentBestFullNode = $newNode; } else { $newNode->setActive(true); } } else { $newNode->setActive(false); } } // get active nodes // taking into account that nodes that were activated on previous steps (when they had best evaluation that solution on that step) // CAN BECAME INACTIVE (due to solution on this step is better than their evaluations) // // also we deactivate them if they don't satisfy some special node limitations (for PDP they are 3D loading constraints) $activeNodes = []; foreach ($rootNode->getActiveChildrenRecursive() as $node) { if ($this->_compareNodes($node, $currentBestFullNode) === 1) { $activeNodes[] = $node; } else { $newNode->setActive(false); } } $this->_logEvent('step_end', ['root_node' => $rootNode, 'active_nodes' => $activeNodes, 'children' => $children, 'current_best_full_node' => $currentBestFullNode]); } return $currentBestFullNode; }
protected function _generateChildrenOf($node) { $result = []; if (!$this->_nodeIsCompleteSolution($node)) { $newPointSequences = $this->_generateNestedPointSequences($node); foreach ($newPointSequences as $newPointSequence) { if ($this->canLoad($newPointSequence)) { $path = new Path(['points' => $newPointSequence]); $newNode = new Node(['content' => $path]); $newNode->setOptimisticBound($this->getEvaluator()->getBound($path, Evaluator::BOUND_TYPE_OPTIMISTIC)); $result[] = $newNode; } } } return $result; }