private void OnFinalState(State state) { if (state != null) { // We have a solution for this puzzle // Backtrac to the root of the path in the tree Stack <State> path = new Stack <State>(); while (state != null) { path.Push(state); state = state.GetParent(); } while (path.Count > 0) { // Move one by one down the path OnStateChanged(path.Pop().GetState(), path.Count == 0); } } else { // No solution OnStateChanged(null, true); } }
private void PuzzleSolved(State state, int states) { int steps = -1; while (state != null) { state = state.GetParent(); steps++; } if (OnPuzzleSolved != null) { OnPuzzleSolved(steps, (int)mStopWatch.ElapsedMilliseconds, states); } }
private void Start(int[] nodes, Heuristic heuristic, CsvWriter csv, int problemType) { int openStateIndex; int stateCount = -1; State currentState = null; List <State> nextStates = new List <State>(); HashSet <String> openStates = new HashSet <string>(); MinPriorityQueue <State> openStateQueue = new MinPriorityQueue <State>(nodes.Length * 3); Dictionary <String, State> closedQueue = new Dictionary <string, State>(nodes.Length * 3); var endProcess = false; var levelCountGenerated = new int[problemType + 1]; var levelCountExpanded = new int[problemType + 1]; var levelCountEvaluated = new int[problemType + 1]; State state = new State(null, nodes, heuristic); openStateQueue.Enqueue(state); openStates.Add(state.GetStateCode()); StartMeasure(); while (!openStateQueue.IsEmpty()) { if (endProcess) { break; } currentState = openStateQueue.Dequeue(); openStates.Remove(currentState.GetStateCode()); stateCount++; if (currentState.GetParent() == null) { currentState.level = 0; } else { levelCountExpanded[currentState.GetParent().level]++; } // Look into next state currentState.GetNextStates(ref nextStates); if (nextStates.Count > 0) { State closedState; State openState; State nextState; for (int i = 0; i < nextStates.Count; i++) { closedState = null; openState = null; nextState = nextStates[i]; if (currentState.level > levelCountGenerated.Length - 1) { Array.Resize(ref levelCountGenerated, currentState.level + 1); Array.Resize(ref levelCountExpanded, currentState.level + 1); Array.Resize(ref levelCountEvaluated, currentState.level + 1); } nextState.level = currentState.level + 1; levelCountGenerated[currentState.level]++; if (nextState.IsFinalState()) { EndMeasure(stateCount); endProcess = true; break; } if (openStates.Contains(nextState.GetStateCode())) { // We already have same state in the open queue. openState = openStateQueue.Find(nextState, out openStateIndex); if (openState.IsCostlierThan(nextState)) { // We have found a better way to reach at this state. Discard the costlier one openStateQueue.Remove(openStateIndex); openStateQueue.Enqueue(nextState); } } else { // Check if state is in closed queue String stateCode = nextState.GetStateCode(); if (closedQueue.TryGetValue(stateCode, out closedState)) { // We have found a better way to reach at this state. Discard the costlier one if (closedState.IsCostlierThan(nextState)) { closedQueue.Remove(stateCode); closedQueue[stateCode] = nextState; } } } // Either this is a new state, or better than previous one. if (openState == null && closedState == null) { levelCountEvaluated[currentState.level]++; openStateQueue.Enqueue(nextState); openStates.Add(nextState.GetStateCode()); } } closedQueue[currentState.GetStateCode()] = currentState; } } var steps = PuzzleSolved(currentState, stateCount); var goalState = "1*2*3*4*5*6*7*8*-1"; var levelCountGeneratedString = levelCountGenerated.Aggregate("", (current, item) => current + (item + "|")); var levelCountEvaluatedString = levelCountEvaluated.Aggregate("", (current, item) => current + (item + "|")); var levelCountExpandedString = levelCountExpanded.Aggregate("", (current, item) => current + (item + "|")); var totalGenerated = levelCountGenerated.Sum(); var totalEvaluated = levelCountEvaluated.Sum(); var totalExpanded = levelCountExpanded.Sum(); var record = new { Time = mStopWatch.ElapsedTicks / 10000.0, State = "\"" + state.GetStateCode() + "\"", GoalState = goalState, Step = steps }; csv.WriteRecord(record); csv.WriteField(levelCountGeneratedString); csv.WriteField(levelCountEvaluatedString); csv.WriteField(levelCountExpandedString); csv.WriteField(totalGenerated); csv.WriteField(totalEvaluated); csv.WriteField(totalExpanded); csv.NextRecord(); //OnFinalState(currentState); }