static void DisplaySchedule(ScheduleOld s)
 {
     int daySize = Constants.HOURS_PER_DAY * Configuration.GetInstance().Rooms.Count;
     var classes = from v in s.Classes
                   let day = v.Value / daySize
                   let time = v.Value % daySize
                   let room = time / Constants.HOURS_PER_DAY
                   let finaltime = time % Constants.HOURS_PER_DAY
                   select new { Day = day, Professor = v.Key.ClassProfessor, Time = finaltime, Course = v.Key.ClassCourse, Duration = v.Key.Length, Room = Configuration.GetInstance().GetRoomByID(room), Group = v.Key.StudentGroups[0] };
     var sortedclasses = from c in classes
                         orderby c.Time ascending
                         orderby c.Day ascending
                         group c by c.Group into a
                         from e in a
                         group e by e.Day;
     Console.WriteLine("       {0, -12} {1, -7} {2, -15} {3, -15} {4,-4} {5, -4}", "Time", "Group", "Course", "Professor", "Room", "Lab");
     foreach (var day in sortedclasses)
     {
         Console.WriteLine("Day {0}:", day.Key);
         foreach(var c in day)
         {
             string line = string.Format("{0, -12} {1, -7} {2, -15} {3, -15} {4,-4} {5,-4}", TimeSpanToString(GetTime(c.Time)) + "-" + TimeSpanToString(GetTime(c.Time+c.Duration)), c.Group.Name, c.Course.Name, c.Professor.Name, c.Room.Name, c.Room.IsLab ? "Yes":"No");
             Console.WriteLine("       {0}", line);
         }
     }
 }
 public static Algorithm GetInstance() 
 {
     if (_instance == null)
     {
         ScheduleOld prototype = new ScheduleOld(2, 2, 40, 2);
         
         _instance = new Algorithm(100, 5, 5, prototype);
     }
     return _instance;
 }
 static void a_NewBestChromosome(object sender, ChromosomeEventArgs e)
 {
     LastBest = (sender as Algorithm).GetBestChromosome().Clone(false);
     Console.WriteLine("New best chromosome found: fitness {0}", (sender as Algorithm).GetBestChromosome().Fitness);
     DisplaySchedule(e.Chromosome);
     if (e.Chromosome.Fitness > 100.9)
     {
         LastBest = e.Chromosome;
         (sender as Algorithm).Stop();
     }
     //DisplaySchedule((sender as Algorithm).GetBestChromosome());
     //Console.ReadLine();
 }
 public ScheduleOld(ScheduleOld c, bool shallow)
 {
     InitializeListCapacities();
     if (!shallow)
     {
         for (int i = 0; i < c._timeslots.Length; i++)
         {
             foreach (var v in c._timeslots[i])
             {
                 _timeslots[i].Add(v.Clone());
             }
         }
         foreach (var k in c._classes)
         {
             _classes.Add(k.Key.Clone(), k.Value); 
         }
         _criteria = c._criteria;
         _fitness = c._fitness;
     }
     _numberOfCrossoverPoints = c._numberOfCrossoverPoints;
     _mutationSize = c._mutationSize;
     _crossoverProbability = c._crossoverProbability;
     _mutationProbability = c._mutationProbability;
 }
        public void Start()
        {
            if (_prototype==null) return;
            State = AlgorithmState.RUNNING;
            ClearBest();
            for (int i = 0; i < _numberOfChromosomes; i++)
            {
                _chromosomes.Add(_prototype.CreateNewFromPrototype());
                AddToBest(i);
            }
            _currentGeneration = 0;

            while (true)
            {
                if (_state != AlgorithmState.RUNNING)
                {
                    break;
                }
                ScheduleOld best = GetBestChromosome();
                if (best.Fitness >= 120)
                {
                    State = AlgorithmState.CRITERIA_STOPPED;
                    break;
                }
                
                ScheduleOld[] offspring = new ScheduleOld[_replaceByGeneration];
                for (int j = 0; j < _replaceByGeneration; j++)
                {
                    ScheduleOld p1 = _chromosomes[_random.Next(_chromosomes.Count)];
                    ScheduleOld p2 = _chromosomes[_random.Next(_chromosomes.Count)];
                    offspring[j] = p1.CrossOver(p2);
                    offspring[j].Mutation();
                    offspring[j].Repair();
                }
                for (int j = 0; j < _replaceByGeneration; j++)
                {
                    int ci=0;
                    do
                    {
                        ci = _random.Next(_chromosomes.Count);
                    }
                    while (IsInBest(ci));
                    _chromosomes[ci] = offspring[j];
                    AddToBest(ci);
                }
                var newbest = GetBestChromosome();

                if (best != newbest)
                {
                    OnNewBestChromosome(newbest);
                }
                _currentGeneration++;
                
                OnEvolutionStateChanged(EventArgs.Empty);
            }
        }
 void OnNewBestChromosome(ScheduleOld s)
 {
     NewBestChromosome(this, new ChromosomeEventArgs(s));
 }
 public ChromosomeEventArgs(ScheduleOld s)
     : base()
 {
     _chromosome = s;
 }
 public Algorithm(int numberOfChromosomes, int replaceByGeneration, int trackBest, ScheduleOld prototype) 
 {
     _replaceByGeneration = replaceByGeneration; 
     _prototype = prototype;
     
     if (numberOfChromosomes < 2)
         numberOfChromosomes = 2;
     if (trackBest < 1)
         trackBest = 1;
     if (_replaceByGeneration < 1)
         _replaceByGeneration = 1;
     else if (_replaceByGeneration > numberOfChromosomes - trackBest)
         _replaceByGeneration = numberOfChromosomes - trackBest;
     _numberOfChromosomes = numberOfChromosomes;
     _chromosomes = new List<ScheduleOld>(numberOfChromosomes);
     _bestFlags = new bool[numberOfChromosomes];
     _bestChromosomes = new int[trackBest];
 }
        public ScheduleOld CrossOver(ScheduleOld parent2) 
        {
            if (_random.Next(100) > _crossoverProbability)
                return new ScheduleOld(this, false);

            ScheduleOld s = new ScheduleOld(this, true);
            int numberOfClasses = _classes.Count;
            bool[] cp = new bool[numberOfClasses];
            for (int i = _numberOfCrossoverPoints; i > 0; i--)
            {
                while (true)
                {
                    int p = _random.Next(numberOfClasses);
                    if (!cp[p])
                    {
                        cp[p] = true;
                        break;
                    }
                }
            }
            var classes1 = _classes.GetEnumerator();
            var classes2 = parent2._classes.GetEnumerator();
            bool first = _random.Next(0,2)==0;
            for (int i = 0; i < numberOfClasses; i++)
            {
                classes1.MoveNext();
                classes2.MoveNext();
                if (first)
                {
                    s._classes.Add(classes1.Current.Key, classes1.Current.Value);
                    for (int j = classes1.Current.Key.Length - 1; j >= 0; j--)
                    {
                        s._timeslots[classes1.Current.Value + j].Add(classes1.Current.Key);
                    }
                }
                else
                {
                    s._classes.Add(classes2.Current.Key, classes2.Current.Value);
                    for (int j = classes2.Current.Key.Length - 1; j >= 0; j--)
                    {
                        s._timeslots[classes2.Current.Value + j].Add(classes2.Current.Key);
                    }
                }
                if (cp[i]) first = !first;
                
            }
            s.CalculateFitness();
            return s;
        }
        public ScheduleOld CreateNewFromPrototype() 
        {
            int size = _timeslots.Length;
            ScheduleOld newChromosome = new ScheduleOld(this, true);

            List<CourseClass> classes = Configuration.GetInstance().CourseClasses;
            int roomCount = Configuration.GetInstance().Rooms.Count;
            foreach (CourseClass c in classes)
            {
                int duration = c.Length;
                int day = _random.Next(Constants.DAYS);
                int room = c.RequiresLab ? Configuration.GetInstance().GetLabRoom().ID : Configuration.GetInstance().GetNonLabRoom().ID;
                int time = _random.Next(Constants.HOURS_PER_DAY + 1 - duration);
                int pos = day * roomCount * Constants.HOURS_PER_DAY + room * Constants.HOURS_PER_DAY + time;
                for(int i = duration-1;i>=0;i--)
                {
                    newChromosome._timeslots[pos+i].Add(c);
                }
                newChromosome._classes.Add(c, pos);
            }
            newChromosome.CalculateFitness();
            return newChromosome;
        }