/// <summary> /// Generates all neighbors of the current. /// </summary> /// <param name = "current">The current.</param> /// <param name = "IncludingParent">if set to <c>true</c> [including parent].</param> /// <param name = "MaxNumber">The max number.</param> /// <returns></returns> public static List <candidate> GenerateAllNeighbors(candidate current, IList <ruleSet> Rulesets, Boolean IncludingParent = false, bool InParallel = false, bool includeStopCondition = false, int MaxNumber = int.MaxValue) { var rand = new Random(); var neighbors = new List <candidate>(); var ruleset = Rulesets[current.activeRuleSetIndex]; var options = ruleset.recognize(current.graph, InParallel); if (options.Count == 0) { var noRuleCandidate = current.copy(); noRuleCandidate.activeRuleSetIndex = ruleset.nextRuleSet(GenerationStatuses.NoRules); neighbors.Add(noRuleCandidate); return(neighbors); } while (MaxNumber < options.Count) { var i = rand.Next(options.Count); options.RemoveAt(i); } if (IncludingParent) { var parent = current.copy(); parent.undoLastRule(); neighbors.Add(parent); } if (InParallel) { Parallel.ForEach(options, opt => { var child = current.copy(); SearchProcess.transferLmappingToChild(child.graph, current.graph, opt); opt.apply(child.graph, null); child.addToRecipe(opt); neighbors.Add(child); }); } else { foreach (var opt in options) { var child = current.copy(); SearchProcess.transferLmappingToChild(child.graph, current.graph, opt); opt.apply(child.graph, null); child.addToRecipe(opt); neighbors.Add(child); if (opt.ruleNumber == ruleset.TriggerRuleNum) { child.activeRuleSetIndex = ruleset.nextRuleSet(GenerationStatuses.TriggerRule); } else { child.activeRuleSetIndex = ruleset.nextRuleSet(GenerationStatuses.Normal); } } } var stopCandidate = current.copy(); stopCandidate.activeRuleSetIndex = ruleset.nextRuleSet(GenerationStatuses.Choice); neighbors.Add(stopCandidate); return(neighbors); }