// Copy constructor public Schedule(Schedule c, bool setupOnly) { if (setupOnly) { // reserve space for time-space slots in chromosomes code _slots = new List<CourseClass>[(DAYS_NUM * DAY_HOURS * Configuration.GetInstance.GetNumberOfRooms())]; for (int ptr = 0; ptr < (DAYS_NUM * DAY_HOURS * Configuration.GetInstance.GetNumberOfRooms()); ptr++) _slots[ptr] = new List<CourseClass>(); // reserve space for flags of class requirements _criteria = new bool[(Configuration.GetInstance.GetNumberOfCourseClasses() * numberOfScores)]; } else { // copy code _slots = c._slots; _classes = c._classes; // copy flags of class requirements _criteria = c._criteria; // copy fitness _fitness = c._fitness; } // copy parameters _numberOfCrossoverPoints = c._numberOfCrossoverPoints; _mutationSize = c._mutationSize; _crossoverProbability = c._crossoverProbability; _mutationProbability = c._mutationProbability; }
public CreateDataGridViews(Dictionary<int, Room> rooms, Form rFrm) { _schedule = null; _running = false; _resultWindow = rFrm; roomList = rooms; LastDGV_Location = new Point(12, 25); LastLabel_Location = new Point(12, 7); Create_FristTime(); // // add DataGridView // foreach (KeyValuePair<int, DataGridView> kvp in DgvList) { _resultWindow.Controls["panelRoomDGV"].Controls.Add(kvp.Value); } // // add Label // foreach (KeyValuePair<int, Label> kvp in LblRoom) { _resultWindow.Controls["panelRoomDGV"].Controls.Add(kvp.Value); } }
// Initializes genetic algorithm public Algorithm(int numberOfChromosomes, int replaceByGeneration, int trackBest, Schedule prototype, Schedule.ScheduleObserver observer) { NumberOfChromosomes = numberOfChromosomes; TrackBest = trackBest; ReplaceByGeneration = replaceByGeneration; _currentBestSize = 0; _prototype = prototype; _observer = observer; _currentGeneration = 0; _state = AlgorithmState.AS_USER_STOPPED; // reserve space for population _chromosomes = new Schedule[NumberOfChromosomes]; _bestFlags = new bool[NumberOfChromosomes]; // reserve space for best chromosome group _bestChromosomes = new int[TrackBest]; // clear population for (int i = _chromosomes.Length - 1; i >= 0; --i) { _chromosomes[i] = null; _bestFlags[i] = false; } _instance = this; #region Find number of Active CPU or CPU core's for this Programs long Affinity_Dec = System.Diagnostics.Process.GetCurrentProcess().ProcessorAffinity.ToInt64(); string Affinity_Bin = Convert.ToString(Affinity_Dec, 2); // toBase 2 foreach (char anyOne in Affinity_Bin.ToCharArray()) if (anyOne == '1') numCore++; #endregion }
// new Thread for Start GA private void GA_Start(object Parallel_Mutex_On) { if ((Boolean)Parallel_Mutex_On) // Parallel Process Requirement's { #region GA for Mutex On while (true) //------------------------------------------------------------------------ { // user has stopped execution? if (_state == AlgorithmState.AS_CRITERIA_STOPPED || _state == AlgorithmState.AS_USER_STOPPED) { break; } else if (_state == AlgorithmState.AS_SUSPENDED) { if (Thread.CurrentThread.IsAlive) Thread.CurrentThread.Suspend(); } // Save a Elite Chromosome for protection in Mutation and etc. Schedule best = GetBestChromosome(); // algorithm has reached criteria? if (best.GetFitness() >= 1) { _state = AlgorithmState.AS_CRITERIA_STOPPED; break; } // produce offspring Schedule[] offspring; offspring = new Schedule[_replaceByGeneration]; Random rand = new Random(); for (int j = 0; j < _replaceByGeneration; j++) { Schedule p1; Schedule p2; // selects parent randomly lock (Locker1) { p1 = _chromosomes[(rand.Next() % _chromosomes.Length)].MakeCopy(false); } lock (Locker1) { p2 = _chromosomes[(rand.Next() % _chromosomes.Length)].MakeCopy(false); } offspring[j] = p1.Crossover(p2); lock (Locker1) { offspring[j].Mutation(); offspring[j].CalculateFitness(); } } // replace chromosomes of current operation with offspring for (int j = 0; j < _replaceByGeneration; j++) { int ci; do { // select chromosome for replacement randomly ci = rand.Next() % _chromosomes.Length; // protect best chromosomes from replacement } while (IsInBest(ci)); lock (Locker1) { // replace chromosomes _chromosomes[ci] = null; _chromosomes[ci] = offspring[j]; } // try to add new chromosomes in best chromosome group AddToBest_Parallel(ci); } // algorithm has found new best chromosome if (best != GetBestChromosome()) // notify observer { lock (Locker1) { _observer.NewBestChromosome(GetBestChromosome(), ResultControls.ResultForm._setting.Display_RealTime); } } _currentGeneration++; } // The GA job's is Complete! if (_observer != null) { lock (Locker0) { // notify observer that execution of algorithm has changed it state _observer.EvolutionStateChanged(_state); } } Thread.CurrentThread.Abort(); #endregion } else { #region GA for Mutex Off while (true) //------------------------------------------------------------------------ { // user has stopped execution? if (_state == AlgorithmState.AS_CRITERIA_STOPPED || _state == AlgorithmState.AS_USER_STOPPED) { break; } else if (_state == AlgorithmState.AS_SUSPENDED) { if (Thread.CurrentThread.IsAlive) Thread.CurrentThread.Suspend(); } // Save a Elite Chromosome for protection in Mutation and etc. Schedule best = GetBestChromosome(); // algorithm has reached criteria? if (best.GetFitness() >= 1) { _state = AlgorithmState.AS_CRITERIA_STOPPED; break; } // produce offspring Schedule[] offspring; offspring = new Schedule[_replaceByGeneration]; Random rand = new Random(); for (int j = 0; j < _replaceByGeneration; j++) { // selects parent randomly Schedule p1 = _chromosomes[(rand.Next() % _chromosomes.Length)]; Schedule p2 = _chromosomes[(rand.Next() % _chromosomes.Length)]; offspring[j] = p1.Crossover(p2); offspring[j].Mutation(); offspring[j].CalculateFitness(); } // replace chromosomes of current operation with offspring for (int j = 0; j < _replaceByGeneration; j++) { int ci; do { // select chromosome for replacement randomly ci = rand.Next() % _chromosomes.Length; // protect best chromosomes from replacement } while (IsInBest(ci)); // replace chromosomes _chromosomes[ci] = null; _chromosomes[ci] = offspring[j]; // try to add new chromosomes in best chromosome group AddToBest_Sequence(ci); } // algorithm has found new best chromosome if (best != GetBestChromosome()) // notify observer { _observer.NewBestChromosome(GetBestChromosome(), ResultControls.ResultForm._setting.Display_RealTime); } _currentGeneration++; } // The GA job's is Complete! if (_observer != null) { // notify observer that execution of algorithm has changed it state _observer.EvolutionStateChanged(_state); } Thread.CurrentThread.Abort(); #endregion } }
// Returns reference to global instance of algorithm public static Algorithm GetInstance() { // global instance doesn't exist? if (_instance == null) { // make prototype of chromosomes Schedule prototype = new Schedule(5, 5, 90, 10); // make new global instance of algorithm using chromosome prototype _instance = new Algorithm(1000, 180, 50, prototype, new Schedule.ScheduleObserver()); } return _instance; }
private void Save(Schedule schedule) { int numberOfRooms = Configuration.GetInstance.GetNumberOfRooms(); int daySize = schedule.day_Hours * numberOfRooms; var db = new LINQDataContext(); db.Classroom_TimeDeleteAll(); foreach (KeyValuePair<CourseClass, int> it in schedule.GetClasses().ToList()) { // coordinate of time-space slot int pos = it.Value; // int pos of _slot array int day = pos / daySize; int time = pos % daySize; // this is not time now! int room = time / schedule.day_Hours; time = time % schedule.day_Hours; // this is a time now! int dur = it.Key.GetDuration; CourseClass cc = it.Key; Algorithm.Room r = Configuration.GetInstance.GetRoomById(room); // // Save Classroom_Time // db.Classroom_TimeSave(r.Origin_ID_inDB, cc.Class_ID, cc.GetProfessor.GetId, time, dur, day); // // Save New_GroupsPerClassroom // foreach (var gs in cc.GetGroups) { db.New_GroupsPerClassSave(r.Origin_ID_inDB, cc.Class_ID, time, day, gs.GetId); } } }
private void ResultForm_Load(object sender, EventArgs e) { Configuration.GetInstance.ParseFile(new LINQDataContext()); btnPause.Enabled = false; btnStop.Enabled = false; if (Configuration.GetInstance.GetNumberOfRooms() > 0) { create_GridView = new CreateDataGridViews(Configuration.GetInstance.Rooms, this); Schedule prototype = new Schedule(5, 5, 90, 10); Schedule.ScheduleObserver sso = new Schedule.ScheduleObserver(); sso.SetWindow(create_GridView); AA = new MakeClassSchedule.Algorithm.Algorithm(1000, 180, 50, prototype, sso); state = ThreadState.Unstarted; timerWorkingSet.Start(); } else { MessageBox.Show("Number of rooms is less than the limit!", "Number of Rooms Error", MessageBoxButtons.OK, MessageBoxIcon.Error); timerWorkingSet.Stop(); AA = null; Dispose(); return; } if (Configuration.GetInstance.GetNumberOfCourseClasses() <= 0) { btnStart.Enabled = false; } }
public void SetSchedule(Schedule schedule, bool showGraphical) { _schedule = schedule.MakeCopy(false); if (Monitor.TryEnter(Locker, 500)) { //_resultWindow.Controls["lblFitness"].Text = schedule.GetFitness().ToString(); SetText("Fitness: " + schedule.GetFitness().ToString()); Monitor.Exit(Locker); } else return; if (showGraphical) { // // ReSet to New DataGridView // foreach (KeyValuePair<int, DataGridView> it in dgvList) { ClearDataGridView(it.Value); } // int numberOfRooms = Configuration.GetInstance.GetNumberOfRooms(); int daySize = schedule.day_Hours * numberOfRooms; Random rand = new Random(); foreach (KeyValuePair<CourseClass, int> it in schedule.GetClasses().ToList()) { // coordinate of time-space slot int pos = it.Value; // int pos of _slot array int day = pos / daySize; int time = pos % daySize; // this is not time now! int room = time / schedule.day_Hours; time = time % schedule.day_Hours; // this is a time now! int dur = it.Key.GetDuration; CourseClass cc = it.Key; Room r = Configuration.GetInstance.GetRoomById(room); string groups_Name = ""; foreach (var gs in cc.GetGroups) { groups_Name += gs.GetName + "\r\n"; } groups_Name = groups_Name.Trim(); ((DataGridViewTextBoxCellEx)dgvList[r.GetId][day + 1, time]).RowSpan = cc.GetDuration; dgvList[r.GetId][day + 1, time].Style.BackColor = Color.FromArgb(rand.Next(70, 250), rand.Next(70, 250), rand.Next(70, 250)); dgvList[r.GetId][day + 1, time].Value = string.Format(CultureInfo.CurrentCulture, "{0}\r\n{1}\r\n{2}\r\n{3}", cc.GetCourse.GetName, cc.GetProfessor.GetName, groups_Name, cc.Lab); //(cc.GetCourse.GetName + Environment.NewLine + // cc.GetProfessor.GetName + Environment.NewLine + // groups_Name + Environment.NewLine + cc.Lab); } } }
// Handles event that is raised when algorithm finds new best chromosome public void NewBestChromosome(Schedule newChromosome, bool showGraphical) { if (_window.DgvList.Count > 0) _window.SetSchedule(newChromosome, showGraphical); }
// Makes new chromosome with same setup but with randomly chosen code public Schedule MakeNewFromPrototype() { // number of time-space slots int size = _slots.Length; // make new chromosome, copy chromosome setup Schedule newChromosome = new Schedule(this, true); // place classes at random position List<CourseClass> cc = Configuration.GetInstance.GetCourseClasses(); foreach (CourseClass it in cc) { // determine random position of class int num_rooms = Configuration.GetInstance.GetNumberOfRooms(); int dur = it.GetDuration; Random rand = new Random(); int day = rand.Next() % DAYS_NUM; int room = rand.Next() % num_rooms; int time = rand.Next() % (DAY_HOURS + 1 - dur); int pos = (day * num_rooms * DAY_HOURS) + (room * DAY_HOURS + time); // (Base) + (offset) time's // fill time-space slots, for each hour of class for (int i = dur - 1; i >= 0; i--) newChromosome._slots[pos + i].Add(it); // insert in class table of chromosome newChromosome._classes.Add(it, pos); } newChromosome.CalculateFitness(); // return smart pointer return newChromosome; }
// Performed crossover operation using to chromosomes // and returns pointer to offspring public Schedule Crossover(Schedule parent2) { Random rand = new Random(); // check probability of crossover operation if (rand.Next() % 100 > _crossoverProbability) // no crossover, just copy first parent return new Schedule(this, false); // new chromosome object, copy chromosome setup Schedule n = new Schedule(this, true); // number of classes int size = _classes.Count; bool[] cp = new bool[size]; // determine crossover point (randomly) for (int i = _numberOfCrossoverPoints; i > 0; i--) { while (true) { int p = rand.Next() % size; if (!cp[p]) { cp[p] = true; break; } } } //Dictionary<CourseClass, int> it1 = _classes; List<KeyValuePair<CourseClass, int>> it1 = _classes.ToList<KeyValuePair<CourseClass, int>>(); //Dictionary<CourseClass, int> it2 = parent2._classes; List<KeyValuePair<CourseClass, int>> it2 = parent2._classes.ToList<KeyValuePair<CourseClass, int>>(); // make new code by combining parent codes bool first = (rand.Next() % 2 == 0); // for (int i = 0; i < size; i++) { if (first) { // insert class from first parent into new chromosome's class table n._classes.Add(it1[i].Key, it1[i].Value); // all time-space slots of class are copied for (int j = it1[i].Key.GetDuration - 1; j >= 0; j--) n._slots[it1[i].Value + j].Add(it1[i].Key); } else { // insert class from second parent into new chromosome's class table n._classes.Add(it2[i].Key, it2[i].Value); // all time-space slots of class are copied for (int j = it2[i].Key.GetDuration - 1; j >= 0; j--) n._slots[it2[i].Value + j].Add(it2[i].Key); } // crossover point if (cp[i]) // change source chromosome first = !first; } n.CalculateFitness(); // return smart pointer to offspring return n; }