/// <summary> /// losowo wygenerowanie nowego chromosoma /// </summary> /// <returns></returns> public Schedule MakeNewFromPrototype(List <Egzaminy> courseList, List <Egzaminatorzy> egzaminatorzy) { // ilość przestrzeni czasowwej int size = slots.Capacity; // tworzenie nowego chromosomu, kopiowanie struktury(ustawień) chromosomu // Zgodnie z obecnym chromosomem skopiować nowy chromosom, ponieważ wartość setupOnly jest true, więc o to nowa generacja chromosomów Schedule newChromosome = new Schedule(this, true); // miejsce egzaminu w losowej pozycji // Egzaminator w losowej lokalizacji List <Egzaminy> c = courseList;// Pobierz wszystkie Exams, przechowaj w c liście List <Egzaminatorzy> eg = egzaminatorzy; foreach (Egzaminy it in c)// Use of iterators,C traverses { // okreslamy losową pozycje egzaminów int nr = NUM_EXAMS; int dur = it.CzasTrwania; int day = RandomNbr.GetRandomNbr() % NUM_DAYS; int center = RandomNbr.GetRandomNbr() % nr; int time = RandomNbr.GetRandomNbr() % (NUM_DAYS + 1 - dur); //pos numer slotu czyli konkretny dzien sesji egzaminacyjnej int pos = day - time; //day * center + time; if (pos < 1) { pos = day; } else if ((pos + dur) > NUM_DAYS) { pos = NUM_DAYS - dur; } // wypełnić szczeliny przestrzeni czasu, dla każdego dnia for (int i = dur - 1; i >= 0; i--) { newChromosome.slots[pos + i].Add(it); } it.EgzaminatorzyList.Clear(); for (int k = 0; k < it.LiczbaEgzaminatorow; k++) { int losowy = RandomNbr.GetRandomNbr() % eg.Count; Egzaminatorzy egzaminator_losowy = eg[losowy]; //eg.RemoveAt(losowy); it.EgzaminatorzyList.Add(egzaminator_losowy); } newChromosome.mapExam.Add(it, pos); } newChromosome.CalculateFitness(); // return smart pointer return(newChromosome); }
/// <summary> /// Wykonuje mutacji na chromosomie /// </summary> public void Mutation() { // sprawdzenie prawdopodobieństwa mutacji // decision was not random mutation operation if (RandomNbr.GetRandomNbr() % 100 > mutationProbability) { return; } // number of classes int numberOfClasses = mapExam.Count; // number of time-space slots int size = slots.Capacity; // przenieść wybraną liczbę klas w dowolnej pozycji // mutationSize zróżnicowanie odnosi się do liczby punktów, aby ilość lekcji zmienności for (int i = mutationSize; i > 0; i--) { // wybierz losowo chromosom dla przemieszczenia int mpos = RandomNbr.GetRandomNbr() % numberOfClasses; int pos1 = 0; IDictionaryEnumerator it = mapExam.GetEnumerator(); // Według mpos weź i it // W celu uzyskania wymaganych kursów i punktów zmiany pozycji w przestrzeni czasowej if (it.MoveNext()) { for (; mpos > 0; it.MoveNext(), mpos--) { ; } } // Aktualna przestrzeń czasowa używana przez klase pos1 = (int)it.Value; // Get the information you need variation points Exams Egzaminy cc1 = it.Key as Egzaminy; // określa pozycję klasy losowo int nr = NUM_EXAMS; int dur = cc1.CzasTrwania; int day = RandomNbr.GetRandomNbr() % NUM_DAYS; int center = RandomNbr.GetRandomNbr() % nr; int time = RandomNbr.GetRandomNbr() % (NUM_DAYS + 1 - dur); int pos2 = (day * nr * NUM_DAYS + center * NUM_DAYS + time) % NUM_DAYS; //day-time; // przenieść wszystkie przestrzenie czasowe for (int j = dur - 1; j >= 0; j--) { // usuń class hour z bieżącej przestrzeni czasowj foreach (Egzaminy it2 in slots[pos1 + j]) { if (it2 == cc1) //(it2.QualificationId == cc1.QualificationId) { slots[pos1 + j].Remove(it2); break; } } // przedz do class hour nowej przestrzeni czasowj slots[pos2 + j].Add(cc1); } // change entry of class table to point to new time-space slots mapExam[cc1] = pos2; } // Mutated chromosome fitness value is calculated this.CalculateFitness(); }
/// <summary> /// Wykonanie krzyżowania używająć chromosomów i zwraca wskaźnik do potomstwa /// </summary> /// <param name="parent2"></param> /// <returns></returns> public Schedule Crossover(Schedule parent2) { // sprawdzenie prawdopodobieństwa krzyżowania if (RandomNbr.GetRandomNbr() % 100 > crossoverProbability) { //nie krzyżowanie, wystarczy skopiować pierwszego rodzica return(new Schedule(this, false)); } // nowy obiekt chromosomu, kopiuj struktury(ustawień) chromosomu // n jest nowy chromosom Schedule n = new Schedule(this, true); // liczba egzaminów int size = mapExam.Count; List <bool> cp = new List <bool>(); cp.Capacity = size; for (int c = 0; c < cp.Capacity; c++) { cp.Add(false); } // określić punkt krzyżowania (losowo) for (int i = numberOfCrossoverPoints; i > 0; i--) { while (true) { int p = RandomNbr.GetRandomNbr() % size; if (!cp[p]) { cp[p] = true; break; } } } // Get pierwsze iteracje były potrzebne do skrzyżowania z harmonogramem dwa IDictionaryEnumerator it1 = this.mapExam.GetEnumerator(); IDictionaryEnumerator it2 = parent2.mapExam.GetEnumerator(); bool first = RandomNbr.GetRandomNbr() % 2 == 0; for (int i = 0; i < size; i++) { it1.MoveNext(); it2.MoveNext(); // punkt krzyżowania if (cp[i]) { // zmiana żródła chromosomu first = !first; } if (first) { // wstawienie egzaminu z pierwszego rodzica do nowej chromosome's class table if (n.mapExam.ContainsKey(it1.Key as Egzaminy)) { n.mapExam.Remove(it1.Key as Egzaminy); n.mapExam.Add(it1.Key as Egzaminy, (int)it1.Value); } else { n.mapExam.Add(it1.Key as Egzaminy, (int)it1.Value); } // wszystkie slots czaso-przestrzenne egzaminu są kopiowane for (int j = (it1.Key as Egzaminy).CzasTrwania - 1; j >= 0; j--) { n.slots[(int)it1.Value + j].Add(it1.Key as Egzaminy); } } else { // wstawienie egzaminu z drugiego rodzica do nowego chromosome's calss table if (n.mapExam.ContainsKey(it2.Key as Egzaminy)) { n.mapExam.Remove(it2.Key as Egzaminy); n.mapExam.Add(it2.Key as Egzaminy, (int)it2.Value); } else { n.mapExam.Add(it2.Key as Egzaminy, (int)it2.Value); } // wszystkie slots czaso-przestrzenne egzaminu są kopiowane for (int j = (it2.Key as Egzaminy).CzasTrwania - 1; j >= 0; j--) { n.slots[(int)it2.Value + j].Add(it2.Key as Egzaminy); } } } // Wartośc fitness jest przeliczana po krzyżowaniu chromosomów n.CalculateFitness(); // return smart pointer to offspring return(n); }