static ScheduleState SimulatedAnnealing(ScheduleState incomeState, double initialTemperature, double endTemperature) { ScheduleState state = incomeState; int currentEnergy = state.CalculateEnergy(); int candidateEnergy; ScheduleState stateCandidate; double p; /* * 1 = not scheduled shift = shift exists here * 0 = scheduled shift = shift moved to schedule */ double temperature = initialTemperature; for (int iteration = 0; iteration < 10000; iteration++) { stateCandidate = GenerateStateCandidate(state); if (stateCandidate == null) { return(state); } candidateEnergy = stateCandidate.CalculateEnergy(); if (candidateEnergy > currentEnergy) { currentEnergy = candidateEnergy; state = stateCandidate; } else { p = GetTransitionProbability(currentEnergy - candidateEnergy, temperature); if (IsTransition(p)) { currentEnergy = candidateEnergy; state = stateCandidate; } else { //Console.WriteLine("Bad p: "+p); } } Console.WriteLine("Candidate energy: " + currentEnergy); temperature = DecreaseTemperature(initialTemperature, iteration); if (temperature <= endTemperature || (state.HasNotScheduledShifts == false)) { return(state); } } return(state); }
private static ShiftStructure SearchForShift(ScheduleState state) { Random random = new Random((int)DateTime.Now.Ticks); int dayMax = 14; int lineMax = 3; int timeMax = 2; ShiftStructure shift = new ShiftStructure() { IsLast = false }; shift.Day = random.Next(0, dayMax); shift.Line = random.Next(0, lineMax); shift.Time = random.Next(0, timeMax); while (state.IsShiftAlreadyScheduled(shift.Day, shift.Line, shift.Time)) { shift.Day = random.Next(0, dayMax); shift.Line = random.Next(0, lineMax); shift.Time = random.Next(0, timeMax); if (state.IsLeftLassFiveShift()) { shift = state.GetFirstAvaliable(); } } return(shift); }
private static ScheduleState GenerateStateCandidate(ScheduleState state) { ShiftStructure shift = SearchForShift(state); int day = shift.Day; int time = shift.Time; int lineNum = shift.Line; int?driver = SearchForDriver(state, day, lineNum); while (driver == null) { shift = SearchForShift(state); day = shift.Day; time = shift.Time; lineNum = shift.Line; driver = SearchForDriver(state, day, lineNum); if (driver == null && shift.IsLast == true) { return(null); } } state.SetLineToDriver(lineNum, driver.Value, day, time); return(state); }
static void Main(string[] args) { ScheduleState = new ScheduleState(); ScheduleState result = SimulatedAnnealing(ScheduleState, 10000.0, 1.0); /* * int topEnergy = -500; * * while (result.CurrentEnergy > topEnergy) * { * result = SimulatedAnnealing(ScheduleState, 10000.0, 1.0); * } */ PrintSchedule(result); PrintLeftShifts(result.AvailableShifts); }
static void PrintSchedule(ScheduleState state) { Console.WriteLine("Schedule"); for (int j = 0; j < 11; j++) { Console.Write("Driver " + (int)(j + 1) + ": "); if (j + 1 < 10) { Console.Write(" "); } for (int i = 0; i < 14; i++) { for (int k = 0; k < 2; k++) { if (state.IsTodayDayOff((byte)(j + 1), (byte)(i + 1))) { Console.BackgroundColor = ConsoleColor.Gray; Console.ForegroundColor = ConsoleColor.Black; Console.Write("x "); Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.Gray; } else { if (state.Schedule[i, j, k] != 0) { Console.ForegroundColor = ConsoleColor.White; } if (state.IsPrefToWork((byte)(j + 1), (byte)(i + 1), (byte)k)) { Console.BackgroundColor = ConsoleColor.Yellow; Console.ForegroundColor = ConsoleColor.Black; } Console.Write(state.Schedule[i, j, k] + " "); Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.Gray; } } Console.Write(" "); } Console.WriteLine(); } }
private static int?SearchForDriver(ScheduleState state, int day, int lineNum) { Random random = new Random((int)DateTime.Now.Ticks); int driverMax = 11; int driver = random.Next(0, driverMax); int iterationToFind = 0; while (( state.IsTodayDayOff((byte)(driver + 1), (byte)(day + 1)) == true || state.IsDriverCanDriveLine((byte)(driver + 1), (byte)(lineNum + 1)) == false || state.IsDriverBusyToday(day, driver) == true ) && iterationToFind < 1000 ) { driver = random.Next(0, driverMax); iterationToFind++; } if ( state.IsTodayDayOff((byte)(driver + 1), (byte)(day + 1)) == false && state.IsDriverCanDriveLine((byte)(driver + 1), (byte)(lineNum + 1)) == true && state.IsDriverBusyToday(day, driver) == false ) { return(driver); } else { return(null); } }