public override QState Run(QState currentState, int trialNum, decimal learn, decimal discount, decimal explore) { QSearch qsearch = new QSearch(this); QSearchResult actions = qsearch.Depth_First(currentState, true); if (actions != null) { foreach (QAction action in actions.actionsList) { if (!currentState.IsEnd() && isRunning && currentState.GetActions().Contains(action)) { WriteOutput(currentState + ": " + action); QState newState = currentState.GetNewState(action); newState.Inherit(currentState); newState.Step(); currentState = newState; } } if (currentState.IsEnd()) { WriteOutput(currentState + ": End"); } else { WriteOutput("Existing solution no longer applicable. Re-solving..."); return(Run(currentState, trialNum, learn, discount, explore)); } } else { WriteOutput("No solution found.", true); } return(currentState); }
} // solveMaze public static void Main(String[] args) { QSearch qs = new QSearch(); qs.SolveMaze(); Console.Read(); } // Main
private async Task GetRecords() { if (QSearch == null) { var task = Task.Run(new Action(() => { try { SetBusy(true); StockList = new List <Stocky.Data.Interfaces.IDataModel>(skStock.GetStockList()); QSearch = new QuickSearch(StockList); SetBusy(false); } catch (Exception e) { App.Current.Dispatcher.BeginInvoke((Action) delegate { ExepionLogger.Logger.LogException(e); ExepionLogger.Logger.Show(e); }); } } )); await task; } else { var task = Task.Run((() => { try { SetBusy(true); StockList.Clear(); foreach (var Item in skStock.GetStockList(SearchFilter)) { StockList.Add(Item); } SetBusy(false); } catch (Exception e) { App.Current.Dispatcher.BeginInvoke((Action) delegate { ExepionLogger.Logger.LogException(e); ExepionLogger.Logger.Show(e); }); } } )); await task; await App.Current.Dispatcher.BeginInvoke((Action) delegate { QSearch.updatelist(StockList); }); } }
public override Dictionary <QFeature, decimal> GetFeatures(QAction action) { Point self = ((Maze_With_No_Walls)GetNewState(action)).self; QSearch qsearch = new QSearch(this); Maze_With_No_Walls simpleMaze = new Maze_With_No_Walls() { maze = maze, self = self, goal = goal, width = width, height = height }; QSearchResult bestPath = qsearch.AStar(simpleMaze); return(QFeature_String.FromStringDecimalDictionary(new Dictionary <string, decimal>() { //{this.GetHashCode().ToString()+"_"+action, 1}, // Identity to convert this back to QLearning { "Goal", goal == self? 1:0 }, { "Distance_To_Goal", bestPath == null? 1:(decimal)bestPath.Count / (decimal)(width * height) }, })); }
private async Task GetRecords() { if (QSearch == null) { var task = Task.Run(new Action(() => { SetBusy(true); SourceList = new List <Stocky.Data.Interfaces.IDataModel>(skCategory.CategoryList()); QSearch = new QuickSearch(SourceList); SetBusy(false); } )); await task; } else { var task = Task.Run(new Action(() => { SetBusy(true); SourceList.Clear(); foreach (var Item in skCategory.CategoryList(SearchFileter)) { SourceList.Add(Item); } SetBusy(false); } )); await task; await App.Current.Dispatcher.BeginInvoke((Action) delegate { QSearch.updatelist(SourceList); }); } }
public override Dictionary <QFeature, decimal> GetFeatures(QAction action) { Point self = ((Maze)GetNewState(action)).self; QSearch qsearch = new QSearch(this); Maze simpleMaze = new Maze() { maze = maze, self = self, goal = goal, width = width, height = height, walls = walls.ToArray() }; QSearchResult bestPath = qsearch.AStar(simpleMaze); List <Point> bestOppMoves = new List <Point>(); foreach (Point o in opponent) { bestOppMoves.Add(o); bestOppMoves.Add(new Point(o.X + 1, o.Y)); bestOppMoves.Add(new Point(o.X - 1, o.Y)); bestOppMoves.Add(new Point(o.X, o.Y + 1)); bestOppMoves.Add(new Point(o.X, o.Y - 1)); } foreach (Point o in bestOppMoves.ToArray()) { bestOppMoves.Add(new Point(o.X + 1, o.Y)); bestOppMoves.Add(new Point(o.X - 1, o.Y)); bestOppMoves.Add(new Point(o.X, o.Y + 1)); bestOppMoves.Add(new Point(o.X, o.Y - 1)); } Maze safeMaze = new Maze() { maze = maze, self = self, goal = goal, width = width, height = height, walls = walls.Concat(bestOppMoves).ToArray() }; QSearchResult safePath = qsearch.AStar(safeMaze); Dictionary <string, decimal> features = new Dictionary <string, decimal>() { //{this.GetHashCode().ToString()+"_"+action, 1}, // Identity to convert this back to QLearning { "Goal", goal == self? 1:0 }, { "Direct_Distance_To_Goal", bestPath == null? 1:(decimal)bestPath.Count / (decimal)(width * height) }, { "Safe_Distance_To_Goal", (safePath == null? 1: (decimal)safePath.Count / (decimal)(width * height)) } }; decimal distanceToOpponent = decimal.MaxValue; if (opponent.Any()) { features["Opponent"] = goal != self && opponent.Where(p => (Math.Abs(p.X - self.X) <= 1 && p.Y == self.Y) || (Math.Abs(p.Y - self.Y) <= 1 && p.X == self.X)).Any() ? 1 : 0; distanceToOpponent = opponent.Select(o => qsearch.AStar(new Maze() { maze = maze, self = self, goal = o, width = width, height = height, walls = walls })).Select(x => x == null? width * height:x.Count).Min(); features["Distance_To_Opponent"] = distanceToOpponent >= 5? 1:distanceToOpponent / (decimal)(width * height); if (goal != self) { Maze deadEnd = new Maze() { maze = maze, self = self, goal = goal, width = width, height = height, walls = walls.Concat(new Point[] { new Point(this.self.X - 1, this.self.Y), new Point(this.self.X + 1, this.self.Y), new Point(this.self.X, this.self.Y - 1), new Point(this.self.X, this.self.Y + 1) }).ToArray() }; QSearchResult deadPath = qsearch.Depth_First(deadEnd); if (deadPath == null) { features["Dead_End"] = 1; } } } return(QFeature_String.FromStringDecimalDictionary(features)); }
public override QState Initialize() { WriteOutput("Dimensions: " + width + "x" + height); self = new Point(start.X, start.Y); score = 0; walls = new Point[] { }; // Generate Walls Randomly if (wallDensity > 0) { HashSet <Point> bestPathSoFar = new HashSet <Point>(); WriteOutput("Generating walls randomly with density target of " + wallDensity + "..."); for (int w = 0; w < width; w++) { for (int h = 0; h < height; h++) { double r = random.NextDouble(); //WriteOutput("Wall Probability for " + w + "x" + h + ": " + r+" vs threshold "+walls); if (r < wallDensity) { //WriteOutput("Wall created at " + w + "x" + h); Point newWall = new Point(w, h); if (start == newWall || goal == newWall) { continue; } Point[] tempWalls = walls.Concat(new Point[] { newWall }).ToArray(); QState tempState = new Maze() { maze = maze, self = self, goal = goal, width = width, height = height, walls = tempWalls }; if (!bestPathSoFar.Any() || bestPathSoFar.Contains(newWall)) { QSearchResult path = new QSearch().AStar(tempState); if (path != null) { bestPathSoFar.Clear(); foreach (QState q in path.QStatesList) { bestPathSoFar.Add(((Maze)q).self); } walls = tempWalls; } } else { walls = tempWalls; } } } } WriteOutput("Maze generation complete."); } opponent = new List <Point>(); for (int i = 0; i < opponents; i++) { opponent.Add(new Point(goal.X, goal.Y)); } if (!HideOutput) { ManualResetEvent wait = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem(new WaitCallback(CreateGUI), new object[] { width, height, self.X, self.Y, goal.X, goal.Y, walls, this, wait }); wait.WaitOne(); } return(new Maze() { width = width, height = height, self = self, goal = goal, walls = walls, wallDensity = wallDensity, opponent = opponent, opponentDifficulty = opponentDifficulty, random = random, maze = maze, start = start, opponents = opponents, bestOpponentPath = bestOpponentPath, score = score }); }
public override void Step() { if (!HideOutput && maze != null) { try { maze.SetSelf(self.X, self.Y); } catch (Exception e) { WriteOutput("" + e, true); } } if (opponent.Any() && goal != self) { for (int i = 0; i < opponent.Count; i++) { QState tempState = new Maze() { maze = maze, self = opponent[i], goal = self, width = width, height = height, walls = walls }; QSearchResult opponentPath; if (bestOpponentPath.ContainsKey(tempState)) { opponentPath = bestOpponentPath[tempState]; } else { opponentPath = new QSearch().AStar(tempState); bestOpponentPath[tempState] = opponentPath; } if (opponentPath != null && opponentPath.Any()) { int newX = opponent[i].X, newY = opponent[i].Y; QAction action = opponentPath.actionsList.First(); if (random.NextDouble() > opponentDifficulty) { QAction[] allActions = tempState.GetActions(); action = allActions.ElementAt(random.Next(allActions.Length)); } // Translate decision to new coordinate if (action.ToString() == "up") { newY--; } else if (action.ToString() == "down") { newY++; } else if (action.ToString() == "left") { newX--; } else if (action.ToString() == "right") { newX++; } //WriteOutput("Moving adversary at " + opponent[i] + " " + action + " to "+newX+", "+newY+"..."); opponent[i] = new Point(newX, newY); if (!HideOutput && maze != null) { maze.SetOpponent(i, newX, newY); } } } } if (goal == self) { score += 100; } else if (opponent.Contains(self)) { score -= 100; } if (!HideOutput && CurrentMode == AWAKEN) { Thread.Sleep(100); } }