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;
        }