//-------------------------------------------------------------------------------------------------------------- bool IStrategizer::LearningFromHumanDemonstration::SubplansDetection(vector<CookedPlan*>& p_cookedPlans) const { SubplansMap subplans; // Detecting the subplans and the matched nodes for (unsigned i = 0; i < p_cookedPlans.size(); ++i) { for (int j = i - 1; j >= 0; --j) { LogInfo("Checking if %d is supergraph of %d", i, j); OlcbpPlan::NodeSet matchedIds; if (IsSuperGraph(p_cookedPlans[i]->pPlan, p_cookedPlans[j]->pPlan, matchedIds)) { subplans[i].push_back(SubsetPlanData(j, matchedIds)); } } } if (subplans.empty()) { return false; } for (unsigned i = 0; i < p_cookedPlans.size(); ++i) { // Remove duplicated nodes between subplans for (unsigned j = 0; j < subplans[i].size(); ++j) { for (unsigned k = j + 1; k < subplans[i].size(); ++k) { for (OlcbpPlan::NodeID nodeId : subplans[i][j].Nodes) { subplans[i][k].Nodes.erase(nodeId); } } } for (SubsetPlanData subplanData : subplans[i]) { if (subplanData.Nodes.empty()) { continue; } unsigned subplanInx = subplanData.Index; unsigned subplanId = p_cookedPlans[subplanInx]->Goal->Id(); unsigned nodeOrder = subplanId; OlcbpPlan::NodeSet matchedIds = subplanData.Nodes; GoalEx* pGoalClone = (GoalEx*)p_cookedPlans[subplanInx]->Goal->Clone(); pGoalClone->Id(subplanId); if (p_cookedPlans[i]->pPlan->Contains(subplanId)) { subplanId = PlanStepEx::GenerateID(); pGoalClone->Id(subplanId); } // Substitute the detected subplans in the super plan _ASSERTE(subplanId == pGoalClone->Id()); p_cookedPlans[i]->pPlan->SubGraphSubstitution(matchedIds, pGoalClone, subplanId, nodeOrder); LogInfo("Subistituting %d/%d", i, subplanInx); } } return true; }
void OnlinePlanExpansionExecution::CoverFailedGoals() { IOlcbpPlan::NodeQueue Q; IOlcbpPlan::NodeID currNodeId; IOlcbpPlan::NodeSerializedSet planRoots; IOlcbpPlan::NodeSet visitedNodes; IOlcbpPlan::NodeSet toCover; _ASSERTE(m_planRootNodeId != IOlcbpPlan::NullNodeID); Q.push(m_planRootNodeId); visitedNodes.insert(m_planRootNodeId); while (!Q.empty()) { currNodeId = Q.front(); Q.pop(); if (!m_pOlcbpPlan->Contains(currNodeId)) { LogWarning("A non existing node was there in the update queue, skipping it"); continue; } for (auto childNodeId : m_pOlcbpPlan->GetAdjacentNodes(currNodeId)) { if (visitedNodes.count(childNodeId) == 0) { if (IsGoalNode(childNodeId) && IsNodeDone(childNodeId)) { auto goalNode = m_pOlcbpPlan->GetNode(childNodeId); if (m_coverGoals.count(childNodeId) == 0 && !goalNode->SuccessConditionsSatisfied(*g_Game) && m_backupNodes.count(childNodeId) == 0) { m_coverGoals.insert(childNodeId); toCover.insert(childNodeId); } } visitedNodes.insert(childNodeId); Q.push(childNodeId); } } } for (auto nodeId : toCover) { auto goalNode = m_pOlcbpPlan->GetNode(nodeId); GoalEx* backupNode = (GoalEx*)goalNode->Clone(); m_backupNodes.insert(MakePair(backupNode->Id(), nodeId)); backupNode->SetState(ESTATE_NotPrepared); m_pOlcbpPlan->AddNode(backupNode, backupNode->Id()); m_nodeData[backupNode->Id()] = OlcbpPlanNodeData(); m_nodeData[backupNode->Id()].ID = backupNode->Id(); SetNodeSatisfyingGoal(backupNode->Id(), m_planRootNodeId); LinkNodes(m_planRootNodeId, backupNode->Id()); auto& rootNodeData = GetNodeData(m_planRootNodeId); rootNodeData.SetWaitOnChildrenCount(rootNodeData.WaitOnChildrenCount + 1); } }