private double PathfindingHeuristic(RegressiveNode sourceNode, RegressiveNode targetNode) { DebugUtils.Assert(!sourceNode.IsTarget, "sourceNode must not be a target {0}", typeof(RegressiveNode)); DebugUtils.Assert(targetNode.IsTarget, "targetNode must be a target {0}", typeof(RegressiveNode)); return(sourceNode.CurrentConstraints .Sum(kvp => kvp.Value.AbsDistanceFrom(targetNode.InitialState[kvp.Key]) * experienceWeight)); }
public Plan FormulatePlan( IKnowledgeProvider knowledgeProvider, IEnumerable <PlanningAction> availableActions, Goal goal ) { // TODO: Ideally, world state should be populated lazily, not in advance, like here. // Some symbols may not be needed at all to build a plan! // (also see comments on IPrecondition and IEffect RelevantActions property) var initialWorldState = new RelevantSymbolsPopulator(availableActions, goal) .PopulateWorldState(knowledgeProvider); // TODO: After lazy population is implemented, the following part of the method is the only thing // that must remain. var goalConstraints = new RegressiveStatePopulator().Populate(goal); try { var path = this.pathfinder.FindPath( RegressiveNode.MakeRegular( goalConstraints, initialWorldState, new RegressiveNodeExpander(availableActions) ), RegressiveNode.MakeTarget(initialWorldState) ); // UnityEngine.Debug.Log("Regressive path:"); // for(int i = 0; i < path.Edges.Count(); i++) // { // if(i == 0) // { // UnityEngine.Debug.LogFormat("Initial: {0}", path.Edges.ElementAt(i).SourceNode); // } // UnityEngine.Debug.LogFormat("After {0}: {1}", ((RegressiveEdge)path.Edges.ElementAt(i)).Action.Name, path.Edges.ElementAt(i).TargetNode); // // if(i > 0) // { // DebugUtils.Assert(path.Edges.ElementAt(i - 1).TargetNode == path.Edges.ElementAt(i).SourceNode, "path must be consistent"); // } // } // FIXME: Downcasting to RegressiveNode - may be fixed by adding another generic parameter to IPathfinder. //return new Plan(SortActions(from edge in path.Edges.Reverse() select ((RegressiveEdge)edge).Action, initialWorldState)); return(new Plan(from edge in path.Edges.Reverse() select((RegressiveEdge)edge).Action, goal)); } catch (PathNotFoundException e) { throw new PlanNotFoundException(this, maxPlanLength, goal, e); } }
public Plan FormulatePlan( IKnowledgeProvider knowledgeProvider, HashSet <PlanningAction> availableActions, Goal goal ) { var timer = new StopwatchExecutionTimer(); var allActions = new HashSet <PlanningAction>(); allActions.UnionWith(availableActions); allActions.UnionWith(experienceActions.Where(experienceAction => availableActions.IsSupersetOf(experienceAction.Actions))); var initialWorldState = new RelevantSymbolsPopulator(allActions, goal) .PopulateWorldState(knowledgeProvider); var goalConstraints = new RegressiveStatePopulator().Populate(goal); try { var path = pathfinder.FindPath( RegressiveNode.MakeRegular( goalConstraints, initialWorldState, new RegressiveNodeExpander(allActions) ), RegressiveNode.MakeTarget(initialWorldState) ); if (learning) { var beforeLearning = timer.ElapsedSeconds; Learn(path, initialWorldState); UnityEngine.Debug.Log( $"Learning time: {timer.ElapsedSeconds-beforeLearning}"); } return(new Plan(from edge in path.Edges.Reverse() select((RegressiveEdge)edge).Action, goal)); } catch (PathNotFoundException e) { throw new PlanNotFoundException(this, maxPlanLength, goal, e); } }
private static double PathfindingHeuristic(RegressiveNode sourceNode, RegressiveNode targetNode) { DebugUtils.Assert(!sourceNode.IsTarget, "sourceNode must not be a target {0}", typeof(RegressiveNode)); DebugUtils.Assert(targetNode.IsTarget, "targetNode must be a target {0}", typeof(RegressiveNode)); // Heuristic value is the sum of distances between // constraint ranges and corresponding values in the initial state. return(sourceNode.CurrentConstraints .Sum((kvp) => kvp.Value.AbsDistanceFrom(targetNode.InitialState[kvp.Key]))); // var result = sourceNode.CurrentConstraints // .Sum((kvp) => kvp.Value.AbsDistanceFrom(targetNode.InitialState[kvp.Key])); // UnityEngine.Debug.LogFormat( // "h = {0} for node w/ {1} constraints. ({2}) and initial state {3} ", // result, // sourceNode.CurrentConstraints.Count(), // sourceNode.CurrentConstraints, // targetNode.InitialState // ); // return result; }