/// <summary> /// Recursive tree traverse used in complete search /// </summary> /// <param name="si">SeatInfo contains seating information</param> /// <param name="temp">current (can be incomplete) temporary seating chart</param> /// <param name="p">current position in chart</param> private static void CompleteSearchChart(SeatInfo si, int[] temp, int p) { if (p > si.size) { if (si.Score(temp) > score) { score = si.Score(temp); chart = new int[temp.Length]; for (int i = 0; i < temp.Length; ++i) { chart[i] = temp[i]; } } return; } for (int i = 1; i <= si.size; ++i) { if (Check(temp, p, i)) { temp[p] = i; CompleteSearchChart(si, temp, p + 1); } } }
public void InitializeChart() { for (int i = 1; i <= size; ++i) { chart[i] = i; } score = seatInfo.Score(chart); }
/// <summary> /// Perform a local search with random move 50% of the time /// </summary> /// <param name="si">Seating info used to grade the seating scheme</param> static void StochasticSearch(SeatInfo si) { DateTime due = DateTime.Now.AddMinutes(1); System.IO.StreamWriter debug = new System.IO.StreamWriter(@"..\..\debug.txt"); int[] temp = AssignRandomSeat(si.size); int tempScore = si.Score(temp); DateTime t = DateTime.Now; int n = 0; //how many time a move results in a suboptimal score / no good move is found while (t <= due) { if (n == 0 || t.Millisecond % 2 == 0) // perform the "good" move if the last good-move attempt wasn't stuck { GoodMove(si, ref temp, ref tempScore); if (tempScore > score) { Array.Copy(temp, chart, si.size + 1); score = tempScore; n = 0; } else { ++n; } } else { RandomMove(si, ref temp, ref tempScore); if (tempScore > score) { Array.Copy(temp, chart, si.size + 1); score = tempScore; n = 0; } else { ++n; } } if (n > 100) // stuck for the last 100 moves then restart { temp = AssignRandomSeat(si.size); tempScore = si.Score(temp); debug.WriteLine("Resetted!"); } t = DateTime.Now; } debug.Close(); }
/// <summary> /// Perform a random move /// </summary> /// <param name="si">Seating info to grade the new scheme</param> /// <param name="temp">current seating scheme</param> /// <param name="tempScore">current score</param> private static void RandomMove(SeatInfo si, ref int[] temp, ref int tempScore) { Random rand = new Random(); int i = rand.Next(si.size) + 1; int j; do { j = rand.Next(si.size) + 1; } while (i == j); Swap(ref temp, i, j); tempScore = si.Score(temp); }
/// <summary> /// Perform a good move: look for the neighbour with the highest score /// </summary> /// <param name="si">seating info to grade the scheme</param> /// <param name="temp">current seating scheme</param> /// <param name="tempScore">current score</param> private static void GoodMove(SeatInfo si, ref int[] temp, ref int tempScore) { int seatToSwap1 = 0, seatToSwap2 = 0; for (int i = 1; i <= si.size; ++i) { for (int j = i + 1; j <= si.size; ++j) { Swap(ref temp, i, j); if (si.Score(temp) > tempScore) { seatToSwap1 = i; seatToSwap2 = j; tempScore = si.Score(temp); } Swap(ref temp, i, j); } } if (seatToSwap1 != 0 && seatToSwap2 != 0) { Swap(ref temp, seatToSwap1, seatToSwap2); } tempScore = si.Score(temp); }