/// <summary> /// Visits the inner node of the SAS+ operator decision tree. /// </summary> /// <param name="treeNode">Inner node of the tree.</param> /// <param name="sourceConditions">Source conditions being evaluated.</param> /// <param name="currentSubConditions">Currently evaluated sub-conditions.</param> /// <returns>List of predecessors.</returns> public IEnumerable <IPredecessor> Visit(OperatorDecisionTreeInnerNode treeNode, IConditions sourceConditions, ISimpleConditions currentSubConditions) { int value; if (currentSubConditions.IsVariableConstrained(treeNode.DecisionVariable, out value)) { // if constrained, collect the operators only in the corresponding subtree foreach (var predecessor in treeNode.OperatorsByDecisionVariableValue[value].Accept(this, sourceConditions, currentSubConditions)) { yield return(predecessor); } } else { // if not constrained, collect operators from all the subtrees foreach (var subTree in treeNode.OperatorsByDecisionVariableValue) { foreach (var predecessor in subTree.Accept(this, sourceConditions, currentSubConditions)) { yield return(predecessor); } } } // always search in the subtree with the value-independent operators foreach (var successor in treeNode.OperatorsIndependentOnDecisionVariable.Accept(this, sourceConditions, currentSubConditions)) { yield return(successor); } }
/// <summary> /// Generates all possible SAS+ states meeting conditions specified by the given conditions. Lazy generated via yield return. /// </summary> /// <param name="conditions">Reference conditions.</param> /// <param name="variables">Variables of the planning problem.</param> /// <returns>All possible SAS+ states meeting the conditions.</returns> public static IEnumerable <IState> EnumerateStates(ISimpleConditions conditions, Variables variables) { Func <int, int> checker = (variable) => { int value; if (conditions.IsVariableConstrained(variable, out value)) { return(value); } return(-1); }; return(EnumerateStates(0, new State(new int[variables.Count]), checker, variables)); }
/// <summary> /// Inserts all goal conditions of the corresponding pattern to fringe. I.e. fixes the goal values and generates all combinations /// for the rest of variables by the method divide-and-conquer. /// </summary> /// <param name="fringe">Fringe.</param> /// <param name="goalConditions">Goal conditions.</param> /// <param name="cost">Current cost.</param> /// <param name="pattern">Requested pattern.</param> /// <param name="currentVariableIndex">Current variable index.</param> /// <param name="values">Generated values.</param> private void InsertPatternConditions(IHeap <double, ISimpleConditions> fringe, ISimpleConditions goalConditions, double cost, int[] pattern, int currentVariableIndex, List <int> values) { if (values.Count == pattern.Length) { Conditions conditions = new Conditions(); int i = 0; foreach (var item in pattern) { conditions.Add(new Assignment(item, values[i])); i++; } fringe.Add(cost, conditions); return; } int currentVariable = pattern[currentVariableIndex]; int constrainedGoalValue; if (goalConditions.IsVariableConstrained(currentVariable, out constrainedGoalValue)) { values.Add(constrainedGoalValue); InsertPatternConditions(fringe, goalConditions, cost, pattern, currentVariableIndex + 1, values); values.RemoveAt(values.Count - 1); } else { for (int i = 0; i < Problem.Variables[currentVariable].GetDomainRange(); ++i) { values.Add(i); InsertPatternConditions(fringe, goalConditions, cost, pattern, currentVariableIndex + 1, values); values.RemoveAt(values.Count - 1); } } }