Генетический алгоритм для составления расписания школы на C#

Заказать уникальную курсовую работу
Тип работы: Курсовая работа
Предмет: C#
  • 41 41 страница
  • 6 + 6 источников
  • Добавлена 24.05.2023
1 496 руб.
  • Содержание
  • Часть работы
  • Список литературы
ОГЛАВЛЕНИЕ

ВВЕДЕНИЕ 4
1. ТЕХНИЧЕСКОЕ ЗАДАНИЕ 5
1.1. Основание для разработки 5
1.2. Назначение разработки 6
1.3. Требования к программе или программному изделию 6
1.3.1. Описание предметной области 7
1.3.2. Требования к функциональным характеристикам 7
1.3.3. Требования к входным и выходным данным 7
1.3.4. Требования пользователя к интерфейсу 7
1.3.5. Требования к надежности 8
1.3.6. Условия эксплуатации 9
1.3.7. Требования к составу и параметрам технических средств 9
1.3.8. Требования к информационной и программной совместимости 9
1.4. Требования к программной документации 10
1.5. Стадии и этапы разработки 10
1.6. Порядок контроля и приемки 10
2. ТЕХНИЧЕСКИЙ ПРОЕКТ 11
2.1. Словарь предметной области программного изделия 11
2.2. Моделирование вариантов использования 12
2.3. Описание структур и форматов данных 12
2.3.1. Входные данные 12
2.3.2. Рабочие данные 15
2.3.3. Выходные данные 15
2.4. Алгоритмы 15
2.4.1. Пояснения алгоритма оценивания варианта 16
2.4.2. Генетический алгоритм поиска решения 16
3. РАБОЧИЙ ПРОЕКТ 18
3.1. Спецификация компонентов и классов программ 18
3.1.1. Описание объектов интерфейса программы 20
3.2. Тестирование программной системы 21
ЗАКЛЮЧЕНИЕ 24
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ 25
ПРИЛОЖЕНИЕ А. Текст разработанного модуля Form1.cs 26

Фрагмент для ознакомления

яз.", "1", "инд.пр", "1", "астрономия", "1" },newstring[] { "матем", "5", "русск", "2", "литер", "3", "ф-ра", "3", "англ", "3", "история", "2", "физика", "3", "химия", "2", "геогр", "1", "биол", "2", "общест", "1", "ИВТ", "1", "ОБЖ", "1", "род.яз.", "1", "инд.пр", "1", "МХК", "1" }};private string[][] Synonims = new string[][] { // Таблицасинонимовnew string[] { "МХК", "ИЗО" },new string[] { "ОПК", "ОРКСЭ", "ОДНК" }};privatestring[][] DeniedAfter = newstring[][] { // Запреты некоторых предметов после указанного первымnewstring[] { "ф-ра", "русск", "матем" } };privatestring[] DeniedFirst = newstring[] { "русск", "матем" }; // Предметы, запрещенные первымиprivatestring[] DeniedLast = newstring[] { "русск", "матем" }; // Предметы, запрещенные последнимиprivatestring[] DeniedSimult_1to4_5to11 = newstring[] { "англ", "ф-ра" }; // Предметы, по которым запрещены совпадения между 1_4 и 5_11 классамиprivate Random rnd = new Random();privatebool stopped = false; // Флагпрерываниярасчетаprivate Dictionary Cache = new Dictionary();publicintAntiQuality(string[] variant) { // Вычислениенекачественностиintresult = 0; // Здесь будет результатinthash = 0;intnn = 0;foreach (string s in variant) {if (s == "") {hash ^= ((int)'|') << (nn % 24);nn++; }elseforeach (char c in s) {hash ^= ((int)c) << (nn % 24);nn++; } }if (Cache.ContainsKey(hash))return Cache[hash];// Проверяем первый урок в понедельник для всех классовfor (int c = 0; c < nClasses; c++){if (variant[c] != "") // Он должен быть свободным, потом заменим его на AlwaysFirstOnMondayresult++; }for (inti = 0; i < Days; i++) { // Циклподнямintj = i == 0 ? 1 : 0; // Индекс первого "настраиваемого" урока для данного дня // Проверяем наличие "дыр" и начало с первого урока в расписании каждого класса // Проверяем первый и последний уроки и сочетания уроковfor (int c = 0; c < nClasses; c++) {int first = i * MaxPerDay * nClasses + c;int k1 = j;while (k1 < MaxPerDay-1 && variant[first + nClasses*k1] == "") {result++;k1++; }int k2 = MaxPerDay-1;while (k2 >= k1 && variant[first + nClasses * k2] == "") {k2--; } // Проверяемпервыйурокif (k1 >= 0 && k1 < MaxPerDay)foreach (string s in DeniedFirst)if (variant[first + nClasses * k1] == s)result++; // Проверяемпоследнийурокif (k2 >= 0 && k2 >= k1 && k2 < MaxPerDay)foreach (string s in DeniedLast)if (variant[first + nClasses * k2] == s)result++; // Проверяем "дыры" // Проверяем число уроковintntot = 0;for (int k = k1; k <= k2; k++)if (variant[first + nClasses * k] == "")result += 3;elsentot++;if (ntot < 2) result += 2 - ntot;// Проверяем отсутствие одинаковых предметов в один деньHashSet D = new HashSet();for (int k = k1; k <= k2; k++)if (variant[first + nClasses * k] != "")if (D.Contains(variant[first + nClasses * k]))result++;elseD.Add(variant[first + nClasses * k]);// Проверяем запрещенные сочетанияfor (intk = k1 + 1; k <= k2; k++){foreach (string[] st in DeniedAfter)if (variant[first + nClasses * (k - 1)] == st[0])for (int p = 1; p < st.Length; p++)if (variant[first + nClasses * k] == st[p])result++; } }/**/ // Проверяем наличие дополнительной перемены для 1 класса в положенное времяif (variant[i * MaxPerDay * nClasses + (nAdditionalForClass1 - 1) * nClasses] != AdditionalForClass1)result++; // Совпадения 1_4 и 5_11foreach (string s in DeniedSimult_1to4_5to11) {for (intjj = j; jj < MaxPerDay; jj++) {int similar = 0;int first = i * MaxPerDay * nClasses + jj * nClasses;for (intc = 0; c < 4; c++){ // Проверяем совпаденияif (variant[first + c] == s)similar++; }if (similar > 1) result += similar;similar = 0;for (int c = 4; c < nClasses; c++){ // Проверяемсовпаденияif (variant[first + c] == s)similar++; }if (similar > 1) result += similar; } } // Совпадения 5_11for (intjj = j; jj < MaxPerDay; jj++) {HashSet D = new HashSet();int first = i * MaxPerDay * nClasses + jj * nClasses;for (int c = 4; c < nClasses; c++){ // Проверяемсовпаденияif (variant[first + c] != "") {if (D.Contains(variant[first + c]))result++;else{ // Синонимыforeach (string[] st in Synonims) {foreach (string s in st)if (variant[first + c] == s) {foreach (string s1 in st)if (D.Contains(s1))result++;break; } }D.Add(variant[first + c]); } } } }/**/ }Cache.Add(hash, result);return result;} // Создание случайного варианта расписанияpublicstring[] CreateVariant() {string[] result = new string[Days*MaxPerDay*nClasses];for (inti = 0; i < result.Length; i++)result[i] = "";for (int c = 0; c < nClasses; c++) { Dictionary D = new Dictionary();int n = 0;for (int k = 0; k < Lessons[c].Length; k += 2) {D.Add(Lessons[c][k], int.Parse(Lessons[c][k + 1])); n += int.Parse(Lessons[c][k + 1]); }for (int p = 1; p <= n; p++) {KeyValuePair K = D.ElementAt(rnd.Next(0, D.Count));intidx = (p % Days) * MaxPerDay * nClasses + (p / Days) * nClasses + c;result[idx] = K.Key;D[K.Key]--;if (D[K.Key] == 0) D.Remove(K.Key);} }returnresult; } // Скрещивание двух расписаний (по типу многоточечного кроссинговера по какому либо классу)public void CrossingOver(string[] parent1, string[] parent2, out string[] child1, out string[] child2) { child1 = new string[parent1.Length]; child2 = new string[parent1.Length];for (int p = 0; p < parent1.Length; p++) {child1[p] = parent1[p];child2[p] = parent2[p]; }intnn = rnd.Next(1, 4);for (int q = 0; q < nn; q++) {int k = 1 + rnd.Next(0, MaxPerDay * Days - 1);int c = rnd.Next(0, nClasses);for (int p = 1; p < MaxPerDay * Days; p++) {if (child2[p] == child1[k]) {stringbuf = child1[c + p * nClasses]; child1[c + p * nClasses] = child1[c + k * nClasses]; child1[c + k * nClasses] = buf;break; } }for (int p = 1; p < MaxPerDay * Days; p++) {if (child1[p] == child2[k]) {stringbuf = child2[c + p * nClasses]; child2[c + p * nClasses] = child2[c + k * nClasses]; child2[c + k * nClasses] = buf;break; } } } } // Мутация (перестановка по каким-либо классам)public string[] Mutate(string[] variant) {string[] result = new string[variant.Length];for (int p = 0; p < variant.Length; p++) {result[p] = variant[p]; }intnn = rnd.Next(1, 4);for (inti = 0; i < nn; i++) {int c = rnd.Next(0, nClasses);int day1 = rnd.Next(0, Days);int day2 = rnd.Next(0, Days);int k1 = rnd.Next(1, MaxPerDay);int k2 = rnd.Next(1, MaxPerDay);for (; k1 < MaxPerDay && k2 < MaxPerDay; k1++, k2++) {stringbuf = result[c + day1 * MaxPerDay * nClasses + k1 * nClasses];result[c + day1 * MaxPerDay * nClasses + k1 * nClasses] = result[c + day2 * MaxPerDay * nClasses + k2 * nClasses];result[c + day2 * MaxPerDay * nClasses + k2 * nClasses] = buf;} }returnresult; } // Сортируем популяцию по возрастанию Антикачестваpublic void Sort(List Population) { // Сортировкаfor (inti = 0; i < Population.Count; i++)AntiQuality(Population[i]);Population.Sort((x, y) => AntiQuality(x).CompareTo(AntiQuality(y))); }public Form1() {InitializeComponent(); } // Обработканажатиянакнопкурешенияprivate void btSolve_Click(object sender, EventArgs e) { List Population = new List(); // Популяцияif (btSolve.Text != "Решение") {stopped = true;btSolve.Text = "Решение"; }else {btSolve.Text = "Прервать";stopped = false;Cache.Clear();nInits = Decimal.ToInt16(edPopulSize.Value);lbSolution.BackColor = Color.Aqua; // Создаемпервичнуюпопуляциюfor (inti = 0; i < nInits; i++){Population.Add(CreateVariant()); } // Сортируем по возрастанию антикачестваSort(Population);string[] Best = null; // ЛучшийвариантintBestQ = 10000; // Антикачестволучшеговариантаfor (inti = 0; i < nEpochs && BestQ > 0 && !stopped; i++){ // Циклэтаповэволюции List NewPopulation = new List(); // Новаяпопуляция// Первая четверть лучших хромосом переходит в новую популяцию (первая четверть).for (int j = 0; j < nInits / 4; j++)NewPopulation.Add(Population[j]); // Первая 0..1/8 лучших хромосом скрещивается с прочими и дает потомство (1/4).for (int j = 0; j < nInits / 8; j++) {string[] child1;string[] child2;CrossingOver(Population[j], Population[rnd.Next(0, Population.Count/4)], out child1, out child2);NewPopulation.Add(child1);NewPopulation.Add(child2);} // Первая четверть лучших хромосом мутирует и переходят в новую популяцию (четвертаячетверть)for (int j = 0; j < 3*nInits / 8; j++)NewPopulation.Add(Mutate(Population[j])); // Добавляем 1/8 новыхпредставителейfor (int j = NewPopulation.Count; j < Population.Count; j++)NewPopulation.Add(CreateVariant()); // Новаяпопуляциястановитсятекущей Population = NewPopulation; // Сортируем по возрастанию антикачестваSort(Population); // Проверяемлучшийвариантint Q = AntiQuality(Population.First());if (Q < BestQ) {BestQ = Q; Best = Population.First();lbQuality.Text = "Показательантикачества: " + BestQ.ToString("F3");lbSolution.Items.Clear();lbSolution.Items.Add("| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |");int q = 0;for (int d = 0; d < Days; d++) {for (int j = 0; j < MaxPerDay; j++) {string line = "";for (int c = 0; c < nClasses; c++) {string s = "|";if (q < nClasses) s += "разг.оваж.";else s += Best[q];if (s.Length < 12) s += new string(' ', 12 - s.Length);line += s;q++; }lbSolution.Items.Add(line + "|"); }lbSolution.Items.Add("+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+"); }Application.DoEvents(); } }if (BestQ == 0) {lbSolution.BackColor = Color.Gold; }stopped = true;btSolve.Text = "Решение";} } // Вызывается при нажатии на кнопку сохранения результатовprivate void btSave_Click(object sender, EventArgs e) {if (saveFileDialog.ShowDialog() == DialogResult.OK) {StreamWriter writer = new StreamWriter(saveFileDialog.FileName, false);foreach (String s in lbSolution.Items) // Циклсохранениястрокwriter.WriteLine(s);writer.Close(); } } }}

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

1. Рутковская, Д., Пилиньский, М., Рутковский, Л. Нейронные сети, генетические алгоритмы и нечеткие системы. М.: Горячая линия – Телеком, 2013.
2. C# documentation. URL: https://learn.microsoft.com/en-us/dotnet/csharp/
3. Албахари Б., Албахари Дж. C# 7.0. Справочник. Полное описание языка. М.: Диалектика; СПб.: Альфа-книга, 2018. – 1023 с.
4. Вагнер Б. Эффективное программирование на C# : 50 способов улучшения кода: [рассматривается C# 6.0]. – М. [и др.] : Диалектика, 2018. – 224 с.
5. Горелов, С. В. Современные технологии программирования: разработка Windows-приложений на языке С#. В 2 томах. Т.I: учебник / С.В. Горелов; под ред. П.Б. Лукьянова. – М.: Прометей, 2019. – 362 c.
6. Троелсен Э., Джепикс Ф. Язык программирования C# 7 и платформы .NET и .NET Core. СПб: ООО «Диалектика», 2018. – 1328 с.