private void Start(int[] nodes, Heuristic heuristic) { 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); State state = new State(null, nodes, heuristic); openStateQueue.Enqueue(state); openStates.Add(state.GetStateCode()); StartMeasure(); while (!openStateQueue.IsEmpty()) { currentState = openStateQueue.Dequeue(); openStates.Remove(currentState.GetStateCode()); stateCount++; // Is this final state if (currentState.IsFinalState()) { EndMeasure(stateCount); break; } // 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 (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) { openStateQueue.Enqueue(nextState); openStates.Add(nextState.GetStateCode()); } } closedQueue[currentState.GetStateCode()] = currentState; } } if (currentState != null && !currentState.IsFinalState()) { // No solution currentState = null; } PuzzleSolved(currentState, stateCount); OnFinalState(currentState); }
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 levelIndicator = 0; 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()) { currentState = openStateQueue.Dequeue(); openStates.Remove(currentState.GetStateCode()); stateCount++; if (currentState.GetParent() == null) { currentState.level = 0; } else { levelCountExpanded[currentState.GetParent().level]++; } // Is this final state if (currentState.IsFinalState()) { EndMeasure(stateCount); break; } // 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 (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); }