public static TimeTable LoadFromXml(TimeTableData appropriateData, string filename) { var data = XDocument.Load(filename); var mainNode = data.Element("TimeTable"); var id = mainNode.Attribute("time_table_id").Value; if (id != appropriateData.Id) { throw new IdMismatchException(); } var infoQuery = from e in mainNode.Elements("Event") let ev = appropriateData.Events .FirstOrDefault(ev => ev.Id == int.Parse(e.Attribute("id").Value)) select new EventAssignment(ev) { FirstWeekAssignment = ParseWeeklyAssignment(appropriateData, e, ev, 1), SecondWeekAssignment = ParseWeeklyAssignment(appropriateData, e, ev, 2), }; return new TimeTable(appropriateData) { Name = mainNode.Attribute("name").Value, assignments = infoQuery.ToDictionary(a => a.Event, a => a) }; }
public static TimeTable Schedule(TimeTableData problemData) { problemData.PrepareHelpers(); var sw = System.Diagnostics.Stopwatch.StartNew(); Solution firstWeekSolution = Schedule(problemData, 1); sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds + " ms"); var firstWeekAssignments = firstWeekSolution.ScheduledWeeklyAssignments; DEFAULT_MAX_STEPS = 600; sw.Start(); // try to partially apply the first week solution to the second one Solution secondWeekSolution = Schedule(problemData, 2, firstWeekAssignments); sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds + " ms"); var secondWeekAssignments = secondWeekSolution.ScheduledWeeklyAssignments; var result = new TimeTable(problemData); foreach (var assignment in firstWeekAssignments) result.AddAssignment(assignment); foreach (var assignment in secondWeekAssignments) result.AddAssignment(assignment); return result; }
public Ant(TimeTableData problemData, MMASData mmasData, int week) { // memeber variables initialization data = problemData; solution = new Solution(problemData, week); events = data.GetWeekEvents(week); eventsCount = events.Length; this.mmasData = mmasData; totalTimeSlots = data.TotalTimeSlots; }
public MMASData(TimeTableData problemData, int week, double evaporation, double minPher) { //member variables initialization data = problemData; events = data.GetWeekEvents(week); eventesNumber = events.Length; timeslotsNumber = problemData.TotalTimeSlots; Pheromones = new double[eventesNumber, timeslotsNumber]; EvaporationRate = evaporation; MinPherLevel = minPher; if (EvaporationRate < 1.0) { MaxPherLevel = 10.0 / (1.0 - EvaporationRate); } else { MaxPherLevel = int.MaxValue; } // creating a set of pre-sorted event lists // sorting events based on level of correlations int[] event_correlation = new int[eventesNumber]; for (int i = 0; i < eventesNumber; i++) { // summing up the correlations for each event event_correlation[i] = 0; for (int j = 0; j < eventesNumber; j++) { if (problemData.ConflictingEvents(events[i].Id, events[j].Id)) event_correlation[i] += 1; } } SortedEventList = new int[eventesNumber]; for (int i = 0; i < eventesNumber; i++) { // sorting the list int max_correlation = -1; int event_index = -1; for (int j = 0; j < eventesNumber; j++) { if (event_correlation[j] > max_correlation) { max_correlation = event_correlation[j]; event_index = j; } } event_correlation[event_index] = -2; SortedEventList[i] = event_index; } }
public TimeTable(TimeTableData data) { Data = data; }
public string ToString(TimeTableData data) { var subject = data.Subjects.First(s => s.Id == Event.SubjectId).ToString(); // TODO: add an event property indicating such way of displaying if (subject == "Військова підготовка" || subject == "Фізична підготовка" || subject == "Фізичне виховання") return subject; var lecturer = data.Lecturers.First(l => l.Id == Event.LecturerId); return subject + "\n" + lecturer + "\n" + (Room == null ? "Комната не назначена" : Room.ToString()); }
static WeeklyEventAssignment ParseWeeklyAssignment(TimeTableData appropriateData, XElement elem, Event ev, int week) { if (elem != null) { var weekTag = string.Empty; switch (week) { case 1: weekTag = "FirstWeek"; break; case 2: weekTag = "SecondWeek"; break; default: throw new ArgumentException("week"); } var weekNode = elem.Elements(weekTag).FirstOrDefault(); if (weekNode == null) return null; var room = appropriateData.Rooms.FirstOrDefault(r => r.Id == int.Parse(weekNode.Attribute("room").Value)); var timeSlot = new TimeSlot(int.Parse(weekNode.Attribute("day").Value), int.Parse(weekNode.Attribute("slot").Value)); return new WeeklyEventAssignment(ev, room, timeSlot, week); } return null; }
static Solution Schedule(TimeTableData problemData, int week, WeeklyEventAssignment[] guidingAssignments = null) { TimeTableData timeTable = problemData; problemData.PrepareSuitableTimeSlots(false); MMASData mmasData = new MMASData(timeTable, week, EVAPORATION, MIN_PHERAMONE); bool secondWeek = guidingAssignments != null; if (secondWeek) mmasData.SetPheromoneFromExistingAssignments(guidingAssignments); else mmasData.ResetPheromone(); Solution bestSoFarSolution = new Solution(problemData, week); bestSoFarSolution.RandomInitialSolution(); bestSoFarSolution.ComputeFeasibility(); bestSoFarSolution.ComputeHcv(); int currIter = 0; int lastImprIter = 0; while (currIter - lastImprIter < 200) { Solution bestIterSolution = Enumerable.Range(0, ANTS_NUMBER) .AsParallel() .Select(_ => { var ant = new Ant(timeTable, mmasData, week); return !secondWeek ? ant.GetSolution() : ant.GetSolution(guidingAssignments); }) .Min(); // apply local search until local optimum is reached or a steps limit reached if (secondWeek) { DEFAULT_MAX_STEPS = Math.Min(DEFAULT_MAX_STEPS + 50, 5000); bestIterSolution.ResolveOnlyWeekSpecificConflicts = true; } bestIterSolution.LocalSearch(bestIterSolution.IsFeasible ? 3000 : DEFAULT_MAX_STEPS); // output the new best solution, if found if (bestIterSolution.CompareTo(bestSoFarSolution) < 0) { bestIterSolution.CopyTo(bestSoFarSolution); lastImprIter = currIter; } // update pheromones mmasData.EvaporatePheromone(); mmasData.SetPheromoneLimits(); if (bestIterSolution.ResolveOnlyWeekSpecificConflicts) mmasData.DepositPheromone(bestIterSolution); else mmasData.DepositPheromone(bestSoFarSolution); currIter++; Console.WriteLine("iter: {0}, HCV: {1}, SCV: {2}", currIter, bestSoFarSolution.Hcv, bestSoFarSolution.Scv); } bestSoFarSolution.ComputeHcv(); bestSoFarSolution.ComputeScv(); Console.WriteLine("RAW: HCV: {0}, SCV: {1}", bestSoFarSolution.Hcv, bestSoFarSolution.Scv); problemData.PrepareSuitableTimeSlots(true); bestSoFarSolution.TryResolveHcv(); bestSoFarSolution.ComputeHcv(); bestSoFarSolution.ComputeScv(); Console.WriteLine("RESOLVE: HCV: {0}, SCV: {1}", bestSoFarSolution.Hcv, bestSoFarSolution.Scv); bestSoFarSolution.LocalSearch(10000, 1, 1); //try to resolve scv bestSoFarSolution.ComputeHcv(); bestSoFarSolution.ComputeScv(); Console.WriteLine("RESULT: HCV: {0}, SCV: {1}", bestSoFarSolution.Hcv, bestSoFarSolution.Scv); return bestSoFarSolution; }