/// <summary> /// Apply the option to the candidate and store the agent's evaluation. /// </summary> public void ApplyOption(option opt, candidate cand, bool doMinimize) { cand.graph.globalVariables.Add(cand.f0); // track fitness values of previous states opt.apply(cand.graph, null); cand.addToRecipe(opt); if (doMinimize) { cand.graph = Minimize(cand.graph); } cand.graph = OBFunctions.tagconvexhullpoints(cand.graph); }
/// <summary> /// Apply the option to the candidate and store the agent's evaluation. /// </summary> public void ApplyOption(option opt, candidate cand, bool doMinimize, bool doEvaluate = false) { cand.graph.globalVariables.Add(cand.f0); // track fitness values of previous states // Minimize and evaluate opt.apply(cand.graph, null); cand.addToRecipe(opt); if (doMinimize) { cand.graph = Minimize(cand.graph); } if (doEvaluate) { cand.f0 = Evaluate(cand); } // MC Is this like line 64? by the way, tracking fitness here is better than in cand.graph }
protected override void Run() { Stack <candidate> candidates = new Stack <candidate>(); candidate current = null; Boolean found = false; candidates.Push(seedCandidate); while (!found && (candidates.Count != 0) && !SearchIO.terminateRequest) { current = candidates.Pop(); SearchIO.iteration = current.recipe.Count; SearchIO.miscObject = candidates.Count; if (isCurrentTheGoal(current)) { found = true; } else { int rsIndex = current.activeRuleSetIndex; List <option> ruleChoices = rulesets[rsIndex].recognize(current.graph); foreach (option opt in ruleChoices) { candidate child = current.copy(); transferLmappingToChild(child.graph, current.graph, opt.location); opt.apply(child.graph, null); child.addToRecipe(opt); candidates.Push(child); } } } SearchIO.addAndShowGraphWindow(current.graph, "cand1"); Save(settings.outputDirectory + "\\DFScandidate.xml", current); }
/// <summary> /// Recognizes the choose apply cycle. Here is the main Recognize, Choose, and /// Apply Generation Cycle. It accepts the host candidate (not graph), the index /// of what ruleSet to invoke, and an array of size equal to the number of ruleSets. /// At the end of the process, it returns the updated candidate. The three step /// process may, however exit at any of five places in the loop, these are described below. /// 1. the ruleSet invoked may not have any calls left. This will cause the GenerationStatus /// to be CycleLimit, and the process will execute what is stored in the 3rd position of /// generationSteps, ruleSet->nextGenerationStep[2], either Stop, Loop, GoToPrevious(ruleSet), /// GoToNext(ruleSet), or GoToRuleSet# /// 2. the choice operation has sent a STOP message, or more precisely a negative # or /// a number greater than the list of option. This results in a GenerationStatus of Choice /// and the execution of ruleSet->nextGenerationStep[1] (any of the options stated above). /// 3. there are no rules recognized for the graph. This results in a GenerationStatus of /// NoRules and the execution of ruleSet->nextGenerationStep[3] (any of the options above). /// 4. A trigger rule has been applied. This results in a GenerationStatus of TriggerRule /// and the execution of ruleSet->nextGenerationStep[4] (any of the options stated above). /// 5. the recognize, choose, and apply cycle performed as intended - no abnormal activites. /// This results in a GenerationStatus of Normal and the execution of /// ruleSet->nextGenerationStep[0] (any of the options stated above).*/ /// </summary> /// <param name = "host">The host.</param> /// <param name = "ruleSetIndex">Index of the rule set.</param> /// <param name = "numOfCallsLeft">The num of calls left.</param> protected void RecognizeChooseApplyCycle(candidate host, int ruleSetIndex, int[] numOfCallsLeft) { while ((ruleSetIndex >= 0) && (ruleSetIndex < NumOfRuleSets)) { host.activeRuleSetIndex = ruleSetIndex; SearchIO.output("Active Rule Set = " + ruleSetIndex, 4); #region terminate immediately if there are no cycles left if (numOfCallsLeft[ruleSetIndex] == 0) { /* it is possible that another ruleset intends to invoke this one, but your * number of calls for this set has hit its limit. */ host.GenerationStatus[ruleSetIndex] = GenerationStatuses.CycleLimit; ruleSetIndex = nextRuleSet(ruleSetIndex, GenerationStatuses.CycleLimit); SearchIO.output("cycle limit reached", 4); continue; } #endregion #region ***** RECOGNIZE ***** SearchIO.output("begin RCA loop for RuleSet #" + ruleSetIndex, 4); var options = Rulesets[ruleSetIndex].recognize(host.graph, InParallel); SearchIO.output("There are " + options.Count + " rule choices.", 4); if (options.Count == 0) { /* There are no rules to recognize, exit here. */ host.GenerationStatus[ruleSetIndex] = GenerationStatuses.NoRules; var newRSIndex = nextRuleSet(ruleSetIndex, GenerationStatuses.NoRules); if (newRSIndex == ruleSetIndex) { throw new Exception("Same ruleset chosen when no rules are recognized."); } ruleSetIndex = newRSIndex; continue; } if (SearchIO.GetTerminateRequest(Thread.CurrentThread.ManagedThreadId)) { return; } #endregion #region ***** CHOOSE ***** if (Rulesets[ruleSetIndex].choiceMethod == choiceMethods.Automatic) { choice = new[] { 0 } } ; else { choice = choose(options, host); } if (choice[0] == -1) { host.undoLastRule(); if (Display) { SearchIO.addAndShowGraphWindow(host.graph.copy(), "Revert to after calling " + host.numRulesCalled + " rules"); } continue; } if ((choice == null) || (choice[0] < 0) || (choice[0] >= options.Count)) { SearchIO.output("Choice = #" + IntCollectionConverter.Convert(choice), 4); /* the overloaded choice function may want to communicate to the loop that it * should finish the process. */ SearchIO.output("Choice received a STOP request", 4); host.GenerationStatus[ruleSetIndex] = GenerationStatuses.Choice; ruleSetIndex = nextRuleSet(ruleSetIndex, GenerationStatuses.Choice); continue; } if (SearchIO.GetTerminateRequest(Thread.CurrentThread.ManagedThreadId)) { return; } #endregion #region ***** APPLY ***** host.saveCurrent(); foreach (var c in choice) { options[c].apply(host.graph, choose(options[c], host)); host.addToRecipe(options[c]); SearchIO.output("Rule sucessfully applied", 4); } if (Display && Rulesets[ruleSetIndex].choiceMethod == choiceMethods.Design) { SearchIO.addAndShowGraphWindow(host.graph.copy(), "After calling " + host.numRulesCalled + " rules"); } if (SearchIO.GetTerminateRequest(Thread.CurrentThread.ManagedThreadId)) { return; } #endregion #region Check to see if loop is done /* First thing we do is reduce the number of calls left. Note that if you start with * a negative number, the process will continue to make it more negative - mimicking * no cycle limit. It is safer to use the globalvar, maxRulesToApply though.*/ if (this is LindenmayerChooseRCA) { numOfCallsLeft[ruleSetIndex]--; } else { numOfCallsLeft[ruleSetIndex] = numOfCallsLeft[ruleSetIndex] - choice.GetLength(0); } if (choice.Any(c => (options[c].ruleNumber == Rulesets[ruleSetIndex].TriggerRuleNum))) { /* your ruleset loops until a trigger rule and the trigger rule was just called. */ SearchIO.output("The trigger rule has been chosen.", 4); host.GenerationStatus[ruleSetIndex] = GenerationStatuses.TriggerRule; ruleSetIndex = nextRuleSet(ruleSetIndex, GenerationStatuses.TriggerRule); } else { /* Normal operation */ SearchIO.output("RCA loop executed normally.", 4); host.GenerationStatus[ruleSetIndex] = GenerationStatuses.Normal; ruleSetIndex = nextRuleSet(ruleSetIndex, GenerationStatuses.Normal); } #endregion } }
/* Here is the main Recognize, Choose, and Apply Generation Cycle. It accepts the host candidate * (not graph), the index of what ruleSet to invoke, and an array of size equal to the number * of ruleSets. At the end of the process, it returns the updated candidate. The three step * process may, however exit at any of five places in the loop, these are described below. * 1. the ruleSet invoked may not have any calls left. This will cause the GenerationStatus * to be CycleLimit, and the process will execute what is stored in the 3rd position of * generationSteps, ruleSet->nextGenerationStep[2], either Stop, Loop, GoToPrevious(ruleSet), * GoToNext(ruleSet), or GoToRuleSet# * 2. the choice operation has sent a STOP message, or more precisely a negative # or * a number greater than the list of option. This results in a GenerationStatus of Choice * and the execution of ruleSet->nextGenerationStep[1] (any of the options stated above). * 3. there are no rules recognized for the graph. This results in a GenerationStatus of * NoRules and the execution of ruleSet->nextGenerationStep[3] (any of the options above). * 4. A trigger rule has been applied. This results in a GenerationStatus of TriggerRule * and the execution of ruleSet->nextGenerationStep[4] (any of the options stated above). * 5. the recognize, choose, and apply cycle performed as intended - no abnormal activites. * This results in a GenerationStatus of Normal and the execution of * ruleSet->nextGenerationStep[0] (any of the options stated above).*/ public void RecognizeChooseApplyCycle(candidate host, int ruleSetIndex, int[] numOfCallsLeft) { while ((ruleSetIndex >= 0) && (ruleSetIndex < numOfRuleSets)) { host.activeRuleSetIndex = ruleSetIndex; SearchIO.output("Active Rule Set = " + ruleSetIndex.ToString(), 4); #region terminate immediately if there are no cycles left if (numOfCallsLeft[ruleSetIndex] == 0) { /* it is possible that another ruleset intends to invoke this one, but your * number of calls for this set has hit its limit. */ host.GenerationStatus[ruleSetIndex] = GenerationStatuses.CycleLimit; ruleSetIndex = nextRuleSet(ruleSetIndex, GenerationStatuses.CycleLimit); SearchIO.output("cycle limit reached", 4); continue; } #endregion #region ***** RECOGNIZE ***** SearchIO.output("begin RCA loop for RuleSet #" + ruleSetIndex.ToString(), 4); List <option> options = rulesets[ruleSetIndex].recognize(host.graph); SearchIO.output("There are " + options.Count.ToString() + " rule choices.", 4); if (options.Count == 0) { /* There are no rules to recognize, exit here. */ host.GenerationStatus[ruleSetIndex] = GenerationStatuses.NoRules; ruleSetIndex = nextRuleSet(ruleSetIndex, GenerationStatuses.NoRules); continue; } if (SearchIO.terminateRequest) { return; } #endregion #region ***** CHOOSE ***** if (rulesets[ruleSetIndex].choiceMethod == choiceMethods.Automatic) { choice = 0; } else { choice = choose(options, host); } SearchIO.output("Choice = #" + choice.ToString(), 4); if (choice == -1) { host.undoLastRule(); if (display) { SearchIO.addAndShowGraphDisplay(host.graph.copy(), "Revert to after calling " + host.numRulesCalled + " rules"); } continue; } if ((choice < 0) || (choice >= options.Count)) { /* the overloaded choice function may want to communicate to the loop that it * should finish the process. */ SearchIO.output("Choice received a STOP request", 4); host.GenerationStatus[ruleSetIndex] = GenerationStatuses.Choice; ruleSetIndex = nextRuleSet(ruleSetIndex, GenerationStatuses.Choice); continue; } if (SearchIO.terminateRequest) { return; } #endregion #region ***** APPLY ***** host.saveCurrent(); options[choice].apply(host.graph, choose(options[choice], host)); host.addToRecipe(options[choice]); SearchIO.output("Rule sucessfully applied", 4); /* display state? */ if (display) { SearchIO.addAndShowGraphDisplay(host.graph.copy(), "After calling " + host.numRulesCalled + " rules"); } if (SearchIO.terminateRequest) { return; } #endregion #region Check to see if loop is done /* First thing we do is reduce the number of calls left. Note that if you start with * a negative number, the process will continue to make it more negative - mimicking * no cycle limit. It is safer to use the globalvar, maxRulesToApply though.*/ numOfCallsLeft[ruleSetIndex]--; /* a significant change is made here in Version 1.1.2.0, it is actually the removal of * code. We were checking the numOfCallsLeft here as well as the top, but it has been decided * that it is ambiguous to check in both locations. Later, it may be determined that two * independent cycle limits need to be imposed, but in the mean time, the following code will be * commented out. * if (numOfCallsLeft[ruleSetIndex] == 0) * { /* there of no more calls on this ruleset allowed, the limit has been reached. * SearchIO.output("The maximum num of calls has been reached", 4); * host.GenerationStatus[ruleSetIndex] = GenerationStatuses.CycleLimit; * ruleSetIndex = nextRuleSet(ruleSetIndex, GenerationStatuses.CycleLimit); * } * else */ if (options[choice].ruleNumber == rulesets[ruleSetIndex].triggerRuleNum) { /* your ruleset loops until a trigger rule and the trigger rule was just called. */ SearchIO.output("The trigger rule has been chosen.", 4); host.GenerationStatus[ruleSetIndex] = GenerationStatuses.TriggerRule; ruleSetIndex = nextRuleSet(ruleSetIndex, GenerationStatuses.TriggerRule); } else { /* Normal operation */ SearchIO.output("RCA loop executed normally.", 4); host.GenerationStatus[ruleSetIndex] = GenerationStatuses.Normal; ruleSetIndex = nextRuleSet(ruleSetIndex, GenerationStatuses.Normal); } #endregion } }
public static void runSearchProcess() { userDefinedGoals udg = new userDefinedGoals(); Form2 inputBox = new Form2(udg); //inputBox.ShowDialog(); ruleSet.loadAndCompileSourceFiles(rulesets, Program.settings.recompileRules, Program.settings.compiledparamRules, Program.settings.execDir); List <candidate> candidates = new List <candidate>(); candidate current = null; candidate seedCandidate = new candidate(seed, Program.settings.numOfRuleSets); Boolean found = false; candidates.Add(seedCandidate); GearEvaluator ge = new GearEvaluator(udg); Guidance.PNormProportionalPopulationSelection GuidanceApproach = new Guidance.PNormProportionalPopulationSelection(0, Guidance.optimize.minimize, true, true, 1); int maxPop = 10000; while (!found && (candidates.Count != 0)) { current = candidates[0]; candidates.RemoveAt(0); SearchIO.iteration = current.recipe.Count; //RECOGNIZE List <option> ruleChoices = rulesets[0].recognize(current.graph); SearchIO.miscObject = candidates.Count; // if (current.recipe.Count >= 2) { found = isCurrentTheGoal(current, udg); if (found == true) { ge.evalGT(current); break; } } //else current.f0 = double.PositiveInfinity; for (int i = 0; i != ruleChoices.Count; i++) { candidate child = current.copy(); ruleChoices = rulesets[0].recognize(child.graph); ruleChoices[i].apply(child.graph, null); child.addToRecipe(ruleChoices[i]); child.f0 = double.NaN; child.f1 = double.NaN; child.f2 = double.NaN; ge.evalGT(child); child.f3 = (child.f0) / 100 + child.f1; //1 efficiency //2 mass //3 combination addChildToSortedCandList(candidates, child, 3); //candidates.Add(child); } } Program.addAndShowGraphDisplay(current.graph, "Here is your gear train!!!"); candidate.saveToXml(current, "testTuned", settings.outputDirectory); }