Uploaded by Артём Беленко

Otchet 1

advertisement
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ АВТОНОМНОЕ ОБРАЗОВАТЕЛЬНОЕУЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ
«БЕЛГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ НАЦИОНАЛЬНЫЙ
ИССЛЕДОВАТЕЛЬСКИЙ УНИВЕРСИТЕТ»
(НИУ «БелГУ»)
ИНСТИТУТ ИНЖЕНЕРНЫХ И ЦИФРОВЫХ ТЕХНОЛОГИЙ
КАФЕДРА ИНФОРМАЦИОННЫХ И РОБОТОТЕХНИЧЕСКИХ СИСТЕМ
Отчет по лабораторной работе №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;
}
Download