Вы находитесь на странице: 1из 8

МИНОБРНАУКИ РОССИИ

САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ
ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
«ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА)
Кафедра информационной безопасности

ОТЧЕТ
по лабораторной работе №6
по дисциплине «Алгоритмы и структуры данных»
Тема: Эвристические алгоритмы

Студент гр. 1363 Дао Н.Х.

Преподаватель Беляев А.В.

Санкт-Петербург
2022
Цель работы
Ознакомление с принципами работы эвристических алгоритмов при
решении NP-сложных задач.
Теоретические сведения
Эвристический алгоритм — это алгоритм, предназначенный для решения
проблемы значительно более быстрым и эффективным способом, чем
традиционные методы, за счет жертвования оптимальностью, точностью или
полнотой ради скорости.
Эвристические алгоритмы часто используются для решения NP-полных
задач. В этих задачах не существует известного эффективного способа
быстрого и точного нахождения решения; однако, при этом если решение
получено, то его можно проверить, в т.ч. в некоторых случаях оценить его
расхождение от оптимального.
В зависимости от задачи эвристические алгоритмы могут быть
использованы для получения итогового решения, либо же использоваться для
построения некоторого базового решения, которое в дальнейшем будет
улучшено другими алгоритмами оптимизации.
Next-Fit Decreasing Height
Алгоритм пытается разместить объект в самый верхний ряд (в данном
алгоритме он считается единственным доступным для заполнения). Когда
очередной объект не удается разместить в этот ряду (из-за своей ширины), ряд
считается закрытым и открывается новый ряд, высотой равный добавляемому
объекту, который становится самым левым в нем.

2
First-Fit Decreasing Height
В отличие от предыдущего алгоритма все ряды считаются доступными
для дополнения новыми объектами. Алгоритм пытается разместить очередной
объект в первый снизу ряд, в котором объекту окажется достаточно места по
ширине. Только если ни одного такого ряда не найдено, объект создает новый
ряд.

3
Практическая часть
Реализовать алгоритмы NFDH и FFDH для поиска решений упаковки
прямоугольных объектов, заданных в файле “ads_lab6_rnd.csv”, на ленте
шириной 1000 условных единиц. Оценить степень приближения решения к
оптимальному.
Результаты выполнения алгоритма NFDH.

Рис. 1 – NFDH

4
Результаты выполнения алгоритма FFDH.

Рис. 2 – FFDH

Выводы
В ходе работы были изучиены Эвристические алгоритмы, написаны
програмы на языке C++ для реализаии алгоритмы NFDH и FFDH для поиска
решений упаковки прямоугольных объектов. Все полученные результаты
выше оптимальных, но могут быть и на приемлемом уровне. Видно, что
алгоритм FFDH дает лучшие результаты, чем NFDH.

5
Исходный код
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

typedef struct Rectang {


int width;
int height;
} Rec;

void Sort(vector <Rec>& rectangle) {


for (int i = 0; i < rectangle.size(); i++) {
for (int j = i + 1; j < rectangle.size(); j++) {
if (rectangle[i].height < rectangle[j].height) {
Rec temp;
temp = rectangle[i];
rectangle[i] = rectangle[j];
rectangle[j] = temp;
}
}
}
}

// algorithm NFDH
void Next_Fit(vector <Rec>& rectangle, int width) {
int row = 1;
int h = rectangle[0].height;
int w_free = width - rectangle[0].width;
cout << "Row: 1" << endl;
cout << "Row height: " << rectangle[0].height << endl;
cout << "List the width of the objects in the row: " << rectangle[0].width;
for (int i = 1; i < rectangle.size(); i++) {
if (rectangle[i].width > w_free) {
cout << endl << "Remaining width of row: " << w_free << endl << endl;
row++;
h = h + rectangle[i].height;
w_free = width - rectangle[i].width;
cout << "Row: " << row << endl;
cout << "Row height: " << rectangle[i].height << endl;
cout << "List the width of the objects in the row: " << rectangle[i].width;
}
else {
w_free = w_free - rectangle[i].width;
cout << ", " << rectangle[i].width ;
}
}
cout << endl << endl << "The sum of the heights of all rows: " << h << endl;
}

//algorithm FFDH
void First_Fit(vector <Rec>& rectangle, int width) {
int row = 0;
int h = 0;
vector <int> h_row;
int* w_free = new int[rectangle.size()];
vector <int>* w_row = new vector <int>[rectangle.size()];
for (int i = 0; i < rectangle.size(); i++) {
int j;
for (j = 0; j < row; j++) {
if (rectangle[i].width <= w_free[j]) {
w_free[j] = w_free[j] - rectangle[i].width;
w_row[j].push_back(rectangle[i].width);
break;
}
}
if (j == row) {
h = h + rectangle[i].height;
w_free[row] = width - rectangle[i].width;
h_row.push_back(rectangle[i].height);
w_row[row].push_back(rectangle[i].width);
row++;
}
}
for (int i = 0; i < row; i++) {
cout << "Row: " << i + 1 << endl;
cout << "Row height: " << h_row[i] << endl;
cout << "List the width of the objects in the row: ";
for (int j = 0; j < w_row[i].size(); j++) {
cout << w_row[i][j] << ", ";
}
cout << endl << "Remaining width of row: " << w_free[i] << endl << endl;
}

7
cout << "The sum of the heights of all rows: " << h << endl;
delete[] w_free, w_row;
}
int main() {
ifstream file("C:\\ads_lab6_rnd.csv");
if (!file.is_open()) {
cout << "Could not open the file" << endl;
return 0;
}
vector<Rec> rectangle;
while (!file.eof()) {
Rec r;
char c;
file >> r.width >> c >> r.height;
rectangle.push_back(r);
}
int width = 1000;
Sort(rectangle);
Next_Fit(rectangle, width);
First_Fit(rectangle, width);
file.close();
return 0;
}

Вам также может понравиться