// Parse experience graph for shortcuts and private void CalculateShortcuts() { var timer = new ResettableStopwatchExecutionTimer(); // Floyd-Warshall // Initialize Matrix var size = experienceGraph.Count; var graph = new double[size, size]; var actionList = new List <ExperienceAction> [size, size]; for (var i = 0; i < size; i++) { for (var j = 0; j < size; j++) { var initialAction = InitializeExperienceGraphMatrixNode(i, j); var initialActionList = new List <ExperienceAction>(); double initialCost; if (initialAction != null) { initialActionList.Add(initialAction); initialCost = initialAction.Cost; } else { initialCost = double.PositiveInfinity; } graph[i, j] = initialCost; actionList[i, j] = initialActionList; } } // Calculate shortcuts for (var k = 0; k < size; k++) { for (var i = 0; i < size; i++) { for (var j = 0; j < size; j++) { if (graph[i, k] + graph[k, j] < graph[i, j]) { graph[i, j] = graph[i, k] + graph[k, j]; actionList[i, j] = actionList[i, k]; actionList[i, j].AddRange(new List <ExperienceAction>(actionList[k, j])); } } } } for (var i = 0; i < size; i++) { for (var j = 0; j < size; j++) { if (graph[i, j] < double.PositiveInfinity) { var nextAct = actionList[i, j]; var baseActionList = new List <PlanningAction>(); foreach (var expAction in nextAct) { baseActionList.AddRange(expAction.Actions); } var shortcut = new ExperienceAction(nextAct.First().StartState, baseActionList.ToArray()); // if (experienceActions.Add(shortcut)) // UnityEngine.Debug.LogWarning("New shortcut action: " + shortcut); experienceActions.Add(shortcut); } } } UnityEngine.Debug.Log($"Time calculating shortcuts: {timer.ElapsedSeconds}"); }
protected static void RunTests(IPlanner planner) { try { var currentWorldState = GetInitialWorldState(); var availableActions = GetAvailableActions(); var buildHouseGoal = new Goal( "BuildHouse", new List <IPrecondition> { new IsTrue(new SymbolId("HouseBuilt")) } ); var buildHousePlusGoal = new Goal( "BuildHousePlus", new List <IPrecondition> { new IsTrue(new SymbolId("HouseBuilt")), new IsNotSmaller(new SymbolId("Iron"), 5), new IsNotSmaller(new SymbolId("Wood"), 2) } ); var getRichGoal = new Goal( "GetRich", new List <IPrecondition> { new IsNotSmaller(new SymbolId("Money"), 10), new IsNotSmaller(new SymbolId("Iron"), 15), } ); var farGoal = new Goal( "FarGoal", new List <IPrecondition> { new IsTrue(new SymbolId("HouseBuilt")), new IsNotSmaller(new SymbolId("Iron"), 50), new IsNotSmaller(new SymbolId("Money"), 200) } ); var timer = new ResettableStopwatchExecutionTimer(); SingleRun("DEFAULT PLAN", planner, currentWorldState, availableActions, buildHouseGoal, timer); SingleRun("IDENTICAL PLAN", planner, currentWorldState, availableActions, buildHouseGoal, timer); SingleRun("PARTIAL REUSE PLAN", planner, currentWorldState, availableActions, buildHousePlusGoal, timer); SingleRun("COMPLETELY DIFFERENT PLAN", planner, currentWorldState, availableActions, getRichGoal, timer); SingleRun("COMPLETELY DIFFERENT PLAN FRESH", planner, currentWorldState, availableActions, getRichGoal, timer, true); SingleRun("PARTIAL REUSE PLAN FRESH", planner, currentWorldState, availableActions, buildHousePlusGoal, timer, true); SingleRun("DEEP PLAN", planner, currentWorldState, availableActions, farGoal, timer); SingleRun("DEEP PLAN AGAIN", planner, currentWorldState, availableActions, farGoal, timer); availableActions.UnionWith(GetManyActions()); SingleRun("WIDE PLAN", planner, currentWorldState, availableActions, getRichGoal, timer, true); SingleRun("WIDE PLAN AGAIN", planner, currentWorldState, availableActions, getRichGoal, timer); SingleRun("DEEP WIDE PLAN", planner, currentWorldState, availableActions, farGoal, timer, true); SingleRun("DEEP WIDE PLAN AGAIN", planner, currentWorldState, availableActions, farGoal, timer); } catch (PlanNotFoundException e) { Debug.LogWarningFormat("{0}: {1}", e.Message, e.InnerException?.Message); } }