ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ АВТОНОМНОЕ ОБРАЗОВАТЕЛЬНОЕУЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ «БЕЛГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ» (НИУ «БелГУ») ИНСТИТУТ ИНЖЕНЕРНЫХ И ЦИФРОВЫХ ТЕХНОЛОГИЙ КАФЕДРА ИНФОРМАЦИОННЫХ И РОБОТОТЕХНИЧЕСКИХ СИСТЕМ Отчет по лабораторной работе №1 Тема работы «Алгоритм отжига» по дисциплине «Знаниеориентированные интеллектуальные системы и технологии» студента очного отделения 4 курса группы 12001608 Зеленюка Дмитрия Олеговича Проверил: доц. Жихарев А.Г. Белгород 2019 Цель работы: разработка и исследование алгоритма отжига при решении числовой задачи оптимизации. Рисунок 1 – Решение задачи на 8 ферзей Рисунок 2 – Решение задачи на 15 ферзей Рисунок 3 – Решение задачи на 30 ферзей Листинг программы на С++: #pragma endregion // начальная инициализация dataGridView1 // N - количество ферзей void InitDataGridView(int N) { int i; dataGridView1->Columns->Clear(); // сформировать dataGridView1 - добавить столбцы for (i = 1; i <= N; i++) { dataGridView1->Columns->Add("i" + i.ToString(), i.ToString()); // ширина столбца в пикселах dataGridView1->Columns[i - 1]->Width = 30; } // добавить строки dataGridView1->Rows->Add(N); // вывести номера строк for (i = 1; i <= N; i++) dataGridView1->Rows[i - 1]->HeaderCell->Value = i.ToString(); // забирает последнюю строку, чтобы нельзя было добавлять строки в режиме выполнения dataGridView1->AllowUserToAddRows = false; // выравнивание по центру во всех строках dataGridView1->RowsDefaultCellStyle->Alignment = DataGridViewContentAlignment::MiddleCenter; } void random(int N, int V[]) { for (int i = 0; i < N; i++) { V[i] = i + 1; // инициализация диапозоном от 0 до N } // инициализация генератора случайных чисел } void ShowDataGridView(int V[], int N) //отрисовка доски с ферзями { // сначала очистить dataGridView1 for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) dataGridView1->Rows[i]->Cells[j]->Value = ""; for (int i = 0; i < N; i++) dataGridView1->Rows[i]->Cells[V[i]-1]->Value = "Q"; } // Проверка, бъются ли 2 ферзя int computeEnergy(int x1, int y1, int x2, int y2) { int conflict = 0; // 1. Главная диагональ int tx, ty; // дополнительные переменные // 1.1. Влево-вверх tx = x1 - 1; ty = y1 - 1; while ((tx >= 1) && (ty >= 1)) { if ((tx == x2) && (ty == y2)) return true; tx--; ty--; } // 1.2. Вправо-вниз tx = x1 + 1; ty = y1 + 1; while ((tx <= N) && (ty <= N)) { if ((tx == x2) && (ty == y2)) return true; tx++; ty++; } // 2. Дополнительная диагональ // 2.1. Вправо-вверх tx = x1 + 1; ty = y1 - 1; while ((tx <= N) && (ty >= 1)) { if ((tx == x2) && (ty == y2)) return true; tx++; ty--; } // 2.2. Влево-вниз tx = x1 - 1; ty = y1 + 1; while ((tx >= 1) && (ty <= N)) { if ((tx == x2) && (ty == y2)) return true; tx--; ty++; } return conflict; } void refr(int V[]) { int q1 = rand() % N + 1; int q2; while(1) { q2 = rand() % N + 1; if (q2 == q1) q2 = rand() % N + 1; else break; } swap(V[q1-1], V[q2-1]); } private: System::Void Button1_Click(System::Object^ sender, System::EventArgs^ e) { N = Convert::ToInt16(textBox1->Text); double INITIAL_TEMPERATURE = 100.0; double FINAL_TEMPERATURE = 0.5; double ALPHA = 0.99; double STEPS_PER_CHANGE = 30; double P; double stat_T = INITIAL_TEMPERATURE; double Max_P = 0, nice_T; int* V = new int[N]; int* W = new int[N]; float test, p; srand(time(NULL)); random(N, V); int C1 = 0; int C2; for (int i = 0; i < N; i++) { W[i] = V[i]; } InitDataGridView(N); for (int i = 0; i < N; i++) { textBox4->Text += Convert::ToString(V[i]) + " "; } //поиск энергии for (int i = 0; i < N; i++) { for (int j = 1; j < N; j++) { C1+=computeEnergy(i,V[i],j,V[j]); } } C2 = C1; textBox4->Text += " "+C2; textBox4->Text += "\r\n"; //меняем случайным образом два элемента массива V[N] do { for (int t = 0; t < STEPS_PER_CHANGE; t++) { refr(V); C1 = 0; // поиск энергии следующего решения for (int i = 0; i < N; i++) { for (int j = 1; j < N; j++) { C1 += computeEnergy(i, V[i], j, V[j]); } } if (C2 <= C1) { test = rand() % 10; test /= 10.; p = -exp(-((C2 - C1) / stat_T)); if (test > p) { for (int i = 0; i < N; i++) { V[i] = W[i]; } stat_T = stat_T * ALPHA; } else { for (int i = 0; i < N; i++) { textBox4->Text += Convert::ToString(V[i]) + " "; } textBox4->Text += " " + C2; textBox4->Text += "\r\n"; } } else { for (int i = 0; i < N; i++) { W[i] = V[i]; C2 = C1; } for (int i = 0; i < N; i++) { textBox4->Text += Convert::ToString(V[i]) + " "; } textBox4->Text += " " + C2; textBox4->Text += "\r\n"; } } } while (C2 != 0 && stat_T>=FINAL_TEMPERATURE); textBox3->Text = Convert::ToString(stat_T); textBox4->Text += "\r\n"; ShowDataGridView(V, N); delete V; delete W; }