/// <summary> /// Initialization of the search procedure. Should be done before every search! /// </summary> /// <param name="type">Search type.</param> protected override void InitSearch(SearchType type) { base.InitSearch(type); ProcessedStatesCount = 0; SolutionCost = 0.0; SolutionPlan = new SolutionPlan(Problem.GetInitialNode()); }
/// <summary> /// Gets the solution plan (i.e. a concrete sequence of applied operators). /// </summary> /// <returns>Solution plan.</returns> public override ISolutionPlan GetSolutionPlan() { if (ResultStatus != ResultStatus.SolutionFound) { return(null); } var predecessor = GetPredecessor(GoalNode); bool isStatesSpecific = (predecessor != null && predecessor.Item2 == null); if (isStatesSpecific) // no operators involved { SolutionPlanViaStates solution = new SolutionPlanViaStates { GoalNode }; while (predecessor != null) { solution.Add(predecessor.Item1); predecessor = GetPredecessor(predecessor.Item1); } if (SearchType == SearchType.Forward) { solution.Reverse(); } return(solution); } else { SolutionPlan solution = new SolutionPlan(Problem.GetInitialNode()); while (predecessor != null) { solution.Add(predecessor.Item2); predecessor = GetPredecessor(predecessor.Item1); } if (SearchType == SearchType.Forward) { solution.Reverse(); } return(solution); } }
/// <summary> /// Starts the search procedure. /// </summary> /// <param name="type">Type of search.</param> /// <returns>Result of the search.</returns> public override ResultStatus Start(SearchType type = SearchType.Forward) { InitSearch(type); List <IOperator> transitionCandidates = new List <IOperator>(); ISearchNode currentNode = GetInitialNode(); while (!Problem.IsGoalNode(currentNode)) { if (IsTimeLimitExceeded()) { return(FinishSearch(ResultStatus.TimeLimitExceeded)); } if (IsMemoryLimitExceeded()) { return(FinishSearch(ResultStatus.MemoryLimitExceeded)); } LogSearchStatistics(); transitionCandidates.Clear(); double bestCost = double.MaxValue; IOperator bestCostOperator; foreach (var transition in Problem.GetTransitions(currentNode)) { IOperator appliedOperator = transition.GetAppliedOperator(); ISearchNode node = transition.GetTransitionResult(); double transitionCost = appliedOperator.GetCost() + Heuristic.GetValue(node); if (transitionCost < bestCost) { bestCost = transitionCost; transitionCandidates.Clear(); transitionCandidates.Add(appliedOperator); } else if (transitionCost.Equals(bestCost)) { transitionCandidates.Add(appliedOperator); } } if (transitionCandidates.Count == 0) { return(FinishSearch(ResultStatus.NoSolutionFound)); // dead-end reached } else if (transitionCandidates.Count == 1) { bestCostOperator = transitionCandidates[0]; } else { bestCostOperator = transitionCandidates[RandomNumberGenerator.Next(transitionCandidates.Count)]; } SolutionPlan.Add(bestCostOperator); SolutionCost += bestCostOperator.GetCost(); currentNode = Apply(currentNode, bestCostOperator); ++ProcessedStatesCount; } if (SearchType != SearchType.Forward) { SolutionPlan.Reverse(); } return(FinishSearch(ResultStatus.SolutionFound, currentNode)); }