/// <summary> /// Implements the Min_Conflicts algorithm for CSP by local search /// InitialState is generated randomly and it is assigned to current /// If all the constraints are satisfied in current then it is returned /// else a random conflicted variable is taken and /// its value is chosen such that it minimizes the number of conflicts /// Variable in current is set to that value /// maxsteps parameter determines the number of steps allowed before giving up /// returns the goal state if successful or null if failure /// </summary> /// <param name="intitialState"></param> /// <param name="maxSteps"></param> /// <returns></returns> public static NQueensProblem MinConlicts(NQueensProblem intitialState, int maxSteps) { NQueensProblem current = intitialState; for (int i = 1; i < maxSteps; i++) { int conflicts; int var = CheckConstraints(current, out conflicts); if (var == 0) { return(current); } else { NQueensProblem tempState = new NQueensProblem(current.Size); for (int j = 0; j < current.Size; j++) { tempState.QueenPositions[j] = current.QueenPositions[j]; for (int k = 0; k < current.Size; k++) { tempState.BoardConfig[j, k] = current.BoardConfig[j, k]; } } int hcost = 0; bool flag = true; List <int> value = new List <int>();; for (int j = 0; j < current.Size; j++) { if (j != current.QueenPositions[var]) { tempState.QueenPositions[var] = j; if (flag) { CheckConstraints(tempState, out hcost); value.Add(j); flag = false; continue; } CheckConstraints(tempState, out conflicts); if (conflicts == hcost) { value.Add(j); } else if (conflicts < hcost) { value.Clear(); hcost = conflicts; value.Add(j); } } } Random rand = new Random(); tempState.QueenPositions[var] = value[rand.Next(value.Count)]; current = tempState; Program.numberOfSteps++; } } return(null); }
/// <summary> /// Implements the Min_Conflicts algorithm for CSP by local search /// InitialState is generated randomly and it is assigned to current /// If all the constraints are satisfied in current then it is returned /// else a random conflicted variable is taken and /// its value is chosen such that it minimizes the number of conflicts /// Variable in current is set to that value /// maxsteps parameter determines the number of steps allowed before giving up /// returns the goal state if successful or null if failure /// </summary> /// <param name="intitialState"></param> /// <param name="maxSteps"></param> /// <returns></returns> public static NQueensProblem MinConlicts(NQueensProblem intitialState, int maxSteps) { NQueensProblem current = intitialState; for (int i = 1; i < maxSteps; i++) { int conflicts; int var = CheckConstraints(current,out conflicts); if (var == 0) return current; else { NQueensProblem tempState = new NQueensProblem(current.Size); for (int j = 0; j < current.Size; j++) { tempState.QueenPositions[j] = current.QueenPositions[j]; for (int k = 0; k < current.Size; k++) tempState.BoardConfig[j, k] = current.BoardConfig[j, k]; } int hcost=0; bool flag=true; List<int> value = new List<int>(); ; for (int j = 0; j < current.Size; j++) { if (j != current.QueenPositions[var]) { tempState.QueenPositions[var] = j; if (flag) { CheckConstraints (tempState ,out hcost); value.Add(j); flag = false; continue; } CheckConstraints(tempState, out conflicts); if (conflicts == hcost) { value.Add (j); } else if(conflicts < hcost ) { value.Clear(); hcost = conflicts; value.Add(j); } } } Random rand= new Random (); tempState.QueenPositions[var] = value[rand.Next (value.Count )]; current = tempState; Program.numberOfSteps++; } } return null; }
/// <summary> /// Main method from where the execution starts /// Accepts the input from user /// </summary> /// <param name="args"></param> static void Main(string[] args) { int input; Console.Write("Enter the size of board: "); while (true) { if (Int32.TryParse(Console.ReadLine(), out input)) { break; } else { Console.WriteLine("Enter a valid number: "); } } NQueensProblem nqueens; bool flag = true; //initialize the object until a solution is found for CSP do { nqueens = new NQueensProblem(input); nqueens.InitializeBoard(); if (flag) { Console.WriteLine("Initial State"); nqueens.PrintState(); Console.WriteLine("======HILL CLIMBING======"); //Call the HillClimbing method NQueensProblem result = HillClimbingProblem.HillClimbing(nqueens); result.PrintState(); Console.WriteLine("Number of Random Initializations are {0}", numberOfInits); Console.WriteLine("Number of State changes are {0}", numberOfSteps); flag = false; numberOfInits = 0; Console.WriteLine("\n=========CSP==========="); } numberOfInits++; numberOfSteps = 0; nqueens = CSP.MinConlicts(nqueens, 100); } while (nqueens == null); nqueens.PrintState(); Console.WriteLine("Number of Random Initializations are {0}", numberOfInits); Console.WriteLine("Number of State changes are {0}", numberOfSteps); Console.Read(); }
/// <summary> /// Checks if the 'state' satisfies the constraints /// returns 0 if all the constraints are satisfied /// returns a random conflicted Variable if one or more constraints are violated /// count parameter is used to track the number of constraint violations /// </summary> /// <param name="state"></param> /// <param name="count"></param> /// <returns></returns> public static int CheckConstraints(NQueensProblem state, out int count) { List <int> index = new List <int>(); Random rand = new Random(); //Constraing 1: Every row must have a queen for (int i = 0; i < state.Size; i++) { for (int j = i + 1; j < state.Size; j++) { if (state.QueenPositions [i] == state.QueenPositions [j]) { index.Add(j); } } } for (int i = 0; i < state.Size; i++) { for (int j = 0; j < state.Size; j++) { if (j == state.QueenPositions[i]) { for (int k = 0; k < i; k++) { if (j == state.QueenPositions[k] || (j > state.QueenPositions[k] && k + j == i + state.QueenPositions[k]) || (j < state.QueenPositions[k] && (k + state.QueenPositions[k]) == (i + j))) { index.Add(i); } } } } } //Constraint 2: No conflicts between the queens if (index.Count != 0) { count = index.Count; return(index[rand.Next(index.Count)]); } else { count = 0; } return(0); }
/// <summary> /// Takes the initialState as the parameter /// generates its successors and select the best successor based on heuristic /// </summary> /// <param name="initialState"></param> /// <returns></returns> public static NQueensProblem HillClimbing(NQueensProblem initialState) { NQueensProblem current = initialState; while (true) { if (Program.numberOfSteps < 100) { //Generate the successors List <NQueensProblem> successors = current.Successors(); List <NQueensProblem> bestSuccessor = new List <NQueensProblem>(); bestSuccessor.Add(successors[0]); //Select the best successor foreach (NQueensProblem successor in successors) { if (successor.Conflicts == bestSuccessor[0].Conflicts) { bestSuccessor.Add(successor); } else if (successor.Conflicts < bestSuccessor[0].Conflicts) { bestSuccessor.Clear(); bestSuccessor.Add(successor); } } Program.numberOfSteps++; Random random = new Random(); int chooseOneSuccessor = random.Next(bestSuccessor.Count); //if current better than best successor return current if (bestSuccessor[chooseOneSuccessor].Conflicts > current.Conflicts) { return(current); } //else set current to best successor current = bestSuccessor[chooseOneSuccessor]; } else { //enters here if the Hill-Climbing is stuck due to local maximum or plateau or ridge Program.numberOfInits++; Program.numberOfSteps = 0; initialState.InitializeBoard(); return(HillClimbing(initialState)); } } }
/// <summary> /// Generate a new NQueensProblem based on parameters row, column and pos /// and returns it /// </summary> /// <param name="row"></param> /// <param name="column"></param> /// <param name="pos"></param> /// <returns></returns> public NQueensProblem Operation(int row, int column, int pos) { NQueensProblem tempState = new NQueensProblem(Size); for (int i = 0; i < Size; i++) { tempState.QueenPositions[i] = this.QueenPositions[i]; for (int j = 0; j < Size; j++) { tempState.BoardConfig[i, j] = this.BoardConfig[i, j]; } } tempState.BoardConfig[row, column] = 1; tempState.BoardConfig[row, pos] = 0; tempState.QueenPositions[row] = column; return(tempState); }
/// <summary> /// Main method from where the execution starts /// Accepts the input from user /// </summary> /// <param name="args"></param> static void Main(string[] args) { int input; Console.Write("Enter the size of board: "); while(true) { if (Int32.TryParse(Console.ReadLine(), out input)) break; else Console.WriteLine("Enter a valid number: "); } NQueensProblem nqueens ; bool flag = true; //initialize the object until a solution is found for CSP do { nqueens = new NQueensProblem(input); nqueens.InitializeBoard(); if(flag) { Console.WriteLine("Initial State"); nqueens.PrintState(); Console.WriteLine("======HILL CLIMBING======"); //Call the HillClimbing method NQueensProblem result = HillClimbingProblem.HillClimbing(nqueens); result.PrintState(); Console.WriteLine("Number of Random Initializations are {0}", numberOfInits); Console.WriteLine("Number of State changes are {0}", numberOfSteps); flag = false; numberOfInits = 0; Console.WriteLine("\n=========CSP==========="); } numberOfInits++; numberOfSteps = 0; nqueens = CSP.MinConlicts(nqueens, 100); } while (nqueens == null); nqueens.PrintState(); Console.WriteLine("Number of Random Initializations are {0}", numberOfInits); Console.WriteLine("Number of State changes are {0}", numberOfSteps); Console.Read(); }
/// <summary> /// Takes the initialState as the parameter /// generates its successors and select the best successor based on heuristic /// </summary> /// <param name="initialState"></param> /// <returns></returns> public static NQueensProblem HillClimbing(NQueensProblem initialState) { NQueensProblem current = initialState ; while(true) { if (Program.numberOfSteps < 100) { //Generate the successors List<NQueensProblem> successors = current.Successors(); List<NQueensProblem> bestSuccessor= new List<NQueensProblem>() ; bestSuccessor.Add(successors[0]); //Select the best successor foreach (NQueensProblem successor in successors) { if (successor.Conflicts == bestSuccessor[0].Conflicts) bestSuccessor.Add(successor); else if (successor.Conflicts < bestSuccessor[0].Conflicts) { bestSuccessor.Clear(); bestSuccessor.Add ( successor); } } Program.numberOfSteps++; Random random = new Random(); int chooseOneSuccessor = random.Next (bestSuccessor .Count ); //if current better than best successor return current if (bestSuccessor[chooseOneSuccessor].Conflicts > current.Conflicts) return current; //else set current to best successor current = bestSuccessor[chooseOneSuccessor]; } else { //enters here if the Hill-Climbing is stuck due to local maximum or plateau or ridge Program.numberOfInits++; Program.numberOfSteps = 0; initialState.InitializeBoard(); return HillClimbing(initialState); } } }
/// <summary> /// Checks if the 'state' satisfies the constraints /// returns 0 if all the constraints are satisfied /// returns a random conflicted Variable if one or more constraints are violated /// count parameter is used to track the number of constraint violations /// </summary> /// <param name="state"></param> /// <param name="count"></param> /// <returns></returns> public static int CheckConstraints(NQueensProblem state,out int count) { List<int> index = new List<int>(); Random rand = new Random(); //Constraing 1: Every row must have a queen for (int i = 0; i < state.Size; i++) { for (int j = i+1; j < state.Size;j++ ) if( state .QueenPositions [i] == state.QueenPositions [j]) { index .Add (j); } } for (int i = 0; i < state.Size; i++) { for (int j = 0; j < state.Size; j++) { if (j == state.QueenPositions[i]) { for (int k = 0; k < i; k++) if (j == state.QueenPositions[k] || (j > state.QueenPositions[k] && k + j == i + state.QueenPositions[k]) || (j < state.QueenPositions[k] && (k + state.QueenPositions[k]) == (i + j))) { index.Add(i); } } } } //Constraint 2: No conflicts between the queens if (index.Count != 0) { count = index.Count; return index[rand.Next(index.Count)]; } else count = 0; return 0; }
/// <summary> /// Generate a new NQueensProblem based on parameters row, column and pos /// and returns it /// </summary> /// <param name="row"></param> /// <param name="column"></param> /// <param name="pos"></param> /// <returns></returns> public NQueensProblem Operation(int row, int column, int pos) { NQueensProblem tempState = new NQueensProblem(Size); for (int i = 0; i < Size; i++) { tempState.QueenPositions[i] = this.QueenPositions[i]; for (int j = 0; j < Size; j++) tempState.BoardConfig[i, j] = this.BoardConfig[i, j]; } tempState.BoardConfig[row, column] = 1; tempState.BoardConfig[row, pos] = 0; tempState.QueenPositions[row] = column; return tempState; }