Locus No Pilotus
Project of four first grade MIPT DAFE/RSE students (for engineering practical work in the second semester) in Qt C++
Loading...
Searching...
No Matches
math::TravellingSalesmansProblem Class Reference

Решение задачи коммивояжера More...

#include <travelling_salesmans_problem.h>

Collaboration diagram for math::TravellingSalesmansProblem:

Public Member Functions

 TravellingSalesmansProblem (AdjacencyMatrix &matrix, std::size_t num_of_flyers=1)
 Инициализирует новый экземпляр TravellingSalesmansProblem для нескольких коммивояжеров
 
std::vector< std::size_t > GetTrajectory ()
 
double GetTrajLength () const
 

Private Member Functions

std::vector< std::size_t > CalculateTrajectory ()
 Просчитывает оптимальную маршрут
 
void CompleteEdgePath (std::shared_ptr< TSPNode > node)
 Замыкает Гамильтонов цикл обхода контрольных точек
 
std::vector< std::size_t > ConvertToVertexPath ()
 Переводит ребра, содержащихся в пути в последовательность обхода контрольных точек
 
AdjacencyMatrixDeleteEdge (AdjacencyMatrix &matrix, std::size_t start_num, std::size_t end_num)
 Удаляет ребро из матрицы смежности
 
void ExpandStack ()
 Заменяет вершину графа в path_stack_ на её детей, без нарушения порядка
 
std::size_t FindIndex (double eval) const
 Находит место для вставки вершины для соблюдения порядка
 

Private Attributes

std::vector< Edgeedge_path_
 
std::size_t num_of_flyers_ {1}
 
double paths_len_
 
std::vector< std::shared_ptr< TSPNode > > paths_stack_
 

Detailed Description

Решение задачи коммивояжера

Constructor & Destructor Documentation

◆ TravellingSalesmansProblem()

math::TravellingSalesmansProblem::TravellingSalesmansProblem ( AdjacencyMatrix & matrix,
std::size_t num_of_flyers = 1 )

Инициализирует новый экземпляр TravellingSalesmansProblem для нескольких коммивояжеров

Parameters
matrixматрица смежности графа
num_of_flyersколичество коммивояжеров
11 : num_of_flyers_{num_of_flyers} {
12 if (num_of_flyers > 1) m.ExtendTo(num_of_flyers);
13 paths_stack_.push_back(std::make_shared<TSPNode>(m));
14 if (m.GetSize() == 2) CompleteEdgePath(paths_stack_[0]);
15}
std::size_t num_of_flyers_
Definition travelling_salesmans_problem.h:31
std::vector< std::shared_ptr< TSPNode > > paths_stack_
Definition travelling_salesmans_problem.h:35
void CompleteEdgePath(std::shared_ptr< TSPNode > node)
Замыкает Гамильтонов цикл обхода контрольных точек
Definition travelling_salesmans_problem.cpp:134
Here is the call graph for this function:

Member Function Documentation

◆ CalculateTrajectory()

std::vector< std::size_t > math::TravellingSalesmansProblem::CalculateTrajectory ( )
private

Просчитывает оптимальную маршрут

Returns
std::vector<std::size_t>: порядок следования вершин
174 {
175 while (paths_stack_[0]->matrix.GetSize() > 2) ExpandStack();
176 paths_len_ = paths_stack_[0]->evaluation;
177 edge_path_ = paths_stack_[0]->path;
178 return ConvertToVertexPath();
179}
std::vector< Edge > edge_path_
Definition travelling_salesmans_problem.h:41
void ExpandStack()
Заменяет вершину графа в path_stack_ на её детей, без нарушения порядка
Definition travelling_salesmans_problem.cpp:17
double paths_len_
Definition travelling_salesmans_problem.h:38
std::vector< std::size_t > ConvertToVertexPath()
Переводит ребра, содержащихся в пути в последовательность обхода контрольных точек
Definition travelling_salesmans_problem.cpp:157
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CompleteEdgePath()

void math::TravellingSalesmansProblem::CompleteEdgePath ( std::shared_ptr< TSPNode > node)
private

Замыкает Гамильтонов цикл обхода контрольных точек

Parameters
nodeвершина графа поиска оптимального пути
135 {
136 Edge first_missed_edge(std::pair(node->matrix.GetMatrixValue(0, 2), 0));
137 Edge second_missed_edge(std::pair(node->matrix.GetMatrixValue(1, 2), 0));
138 for (std::size_t i = 0; i < 2; ++i) {
139 if ((node->matrix.GetMatrixValue(0, 0) + node->matrix.GetMatrixValue(1, 1) <
140 node->matrix.GetMatrixValue(0, 1) +
141 node->matrix.GetMatrixValue(1, 0))) {
142 first_missed_edge.end_num =
143 (std::size_t)node->matrix.GetMatrixValue(2, 0);
144 second_missed_edge.end_num =
145 (std::size_t)node->matrix.GetMatrixValue(2, 1);
146 } else {
147 first_missed_edge.end_num =
148 (std::size_t)node->matrix.GetMatrixValue(2, 1);
149 second_missed_edge.end_num =
150 (std::size_t)node->matrix.GetMatrixValue(2, 0);
151 }
152 }
153 node->path.push_back(first_missed_edge);
154 node->path.push_back(second_missed_edge);
155}
Here is the caller graph for this function:

◆ ConvertToVertexPath()

std::vector< std::size_t > math::TravellingSalesmansProblem::ConvertToVertexPath ( )
private

Переводит ребра, содержащихся в пути в последовательность обхода контрольных точек

Returns
std::vector<std::size_t>: последовательность обхода контрольных точек
157 {
158 std::map<std::size_t, std::size_t> aux_path;
159 for (std::size_t i = 0; i < edge_path_.size(); ++i) {
160 aux_path[edge_path_[i].start_num] = edge_path_[i].end_num;
161 }
162 std::vector<std::size_t> final_path;
163 final_path.push_back(0);
164 std::size_t key = 0;
165 while (aux_path[key] != 0) {
166 final_path.push_back(aux_path[key]);
167 key = aux_path[key];
168 }
169 for (std::size_t i = 0; i < final_path.size(); ++i)
170 if (final_path[i] > final_path.size() - num_of_flyers_) final_path[i] = 0;
171 return final_path;
172}
Here is the caller graph for this function:

◆ DeleteEdge()

AdjacencyMatrix & math::TravellingSalesmansProblem::DeleteEdge ( AdjacencyMatrix & matrix,
std::size_t start_num,
std::size_t end_num )
private

Удаляет ребро из матрицы смежности

Parameters
matrixматрица смежности
start_numначало ребра
end_numконец ребра
Returns
AdjacencyMatrix: матрица с удалённым ребром
95 {
96 for (std::size_t i = 0; i < matrix.GetSize(); ++i) {
97 if (std::abs(matrix.GetMatrixValue(i, matrix.GetSize()) -
98 (double)start_num) > precision)
99 continue;
100 for (std::size_t j = 0; j < matrix.GetSize(); ++j) {
101 if (std::abs(matrix.GetMatrixValue(matrix.GetSize(), j) -
102 (double)end_num) > precision)
103 continue;
104 matrix.SetMatrixValue(i, j, inf);
105 }
106 }
107 return matrix;
108}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ExpandStack()

void math::TravellingSalesmansProblem::ExpandStack ( )
private

Заменяет вершину графа в path_stack_ на её детей, без нарушения порядка

17 {
18 std::pair<std::size_t, std::size_t> value =
19 paths_stack_[0]->matrix.GetSelectedValue();
20 Edge edge(paths_stack_[0]->matrix.GetSelectedEdge());
21
22 // Первый ребенок, c включением edge
23 AdjacencyMatrix with_edge_matrix = paths_stack_[0]->matrix.Reducted();
24 with_edge_matrix = DeleteEdge(with_edge_matrix, edge.end_num, edge.start_num);
25
26 // Исключение возможности цикла
27 std::map<std::size_t, std::size_t> prev_chains = paths_stack_[0]->chains;
28 std::map<std::size_t, std::size_t> new_chains = paths_stack_[0]->chains;
29 bool is_new = true;
30 for (const auto& [start, end] : prev_chains) {
31 if (start == edge.end_num) {
32 new_chains.erase(start);
33 new_chains[edge.start_num] = end;
34 is_new = false;
35 break;
36 } else if (end == edge.start_num) {
37 new_chains[start] = edge.end_num;
38 is_new = false;
39 break;
40 }
41 }
42 if (is_new) new_chains[edge.start_num] = edge.end_num;
43 for (const auto& [start, end] : new_chains) {
44 for (const auto& [start2, end2] : new_chains) {
45 if (end2 == start) {
46 new_chains[start2] = end;
47 new_chains.erase(start);
48 }
49 if (end == start2) {
50 new_chains[start] = end2;
51 new_chains.erase(start2);
52 }
53 }
54 }
55 for (const auto& [start, end] : new_chains) {
56 with_edge_matrix = DeleteEdge(with_edge_matrix, end, start);
57 }
58 // Исключение возможности цикла
59
60 with_edge_matrix = with_edge_matrix.Minor(value.first, value.second);
61 paths_stack_[0]->with_edge = std::make_shared<TSPNode>(
62 with_edge_matrix, paths_stack_[0], edge, new_chains);
63 if (paths_stack_[0]->with_edge->matrix.GetSize() == 2)
64 CompleteEdgePath(paths_stack_[0]->with_edge);
65
66 // Второй ребенок, c исключением edge
67 AdjacencyMatrix without_edge_matrix = paths_stack_[0]->matrix.Reducted();
68 without_edge_matrix =
69 DeleteEdge(without_edge_matrix, edge.start_num, edge.end_num);
70 paths_stack_[0]->without_edge =
71 std::make_shared<TSPNode>(without_edge_matrix, paths_stack_[0]);
72
73 // Добавляем детей в стек вершин,удаляем их родителя
74 double with_eval = paths_stack_[0]->with_edge->evaluation;
75 double without_eval = paths_stack_[0]->without_edge->evaluation;
76 if (!std::isinf(without_eval)) {
77 if (FindIndex(without_eval) < paths_stack_.size())
78 paths_stack_.insert(paths_stack_.begin() + FindIndex(without_eval),
79 paths_stack_[0]->without_edge);
80 else
81 paths_stack_.push_back(paths_stack_[0]->without_edge);
82 }
83 if (!std::isinf(with_eval)) {
84 if (FindIndex(with_eval) < paths_stack_.size())
85 paths_stack_.insert(paths_stack_.begin() + FindIndex(with_eval),
86 paths_stack_[0]->with_edge);
87 else
88 paths_stack_.push_back(paths_stack_[0]->with_edge);
89 }
90 paths_stack_.erase(paths_stack_.begin());
91}
std::size_t FindIndex(double eval) const
Находит место для вставки вершины для соблюдения порядка
Definition travelling_salesmans_problem.cpp:110
AdjacencyMatrix & DeleteEdge(AdjacencyMatrix &matrix, std::size_t start_num, std::size_t end_num)
Удаляет ребро из матрицы смежности
Definition travelling_salesmans_problem.cpp:93
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FindIndex()

std::size_t math::TravellingSalesmansProblem::FindIndex ( double eval) const
private

Находит место для вставки вершины для соблюдения порядка

Parameters
evalнижняя оценка матрицы
Returns
std::size_t: индекс вставки вершины
110 {
111 // Нижняя и верхняя границы
112 std::size_t start = 0;
113 std::size_t end = paths_stack_.size();
114 // Уменьшение области поиска
115 while (start < end) {
116 std::size_t mid = (start + end) / 2;
117 // Если eval нашлось
118 if (std::abs(paths_stack_[mid]->evaluation - eval) <= precision)
119 if (mid)
120 return mid;
121 else
122 return mid + 1;
123 else if (paths_stack_[mid]->evaluation < eval)
124 start = mid + 1;
125 else
126 end = mid;
127 }
128 if (end)
129 return end;
130 else
131 return end + 1;
132}
Here is the caller graph for this function:

◆ GetTrajectory()

std::vector< std::size_t > math::TravellingSalesmansProblem::GetTrajectory ( )
inline
25 {
26 return CalculateTrajectory();
27 }
std::vector< std::size_t > CalculateTrajectory()
Просчитывает оптимальную маршрут
Definition travelling_salesmans_problem.cpp:174
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetTrajLength()

double math::TravellingSalesmansProblem::GetTrajLength ( ) const
inline
22{ return paths_len_; }

Member Data Documentation

◆ edge_path_

std::vector<Edge> math::TravellingSalesmansProblem::edge_path_
private

◆ num_of_flyers_

std::size_t math::TravellingSalesmansProblem::num_of_flyers_ {1}
private
31{1};

◆ paths_len_

double math::TravellingSalesmansProblem::paths_len_
private

◆ paths_stack_

std::vector<std::shared_ptr<TSPNode> > math::TravellingSalesmansProblem::paths_stack_
private

The documentation for this class was generated from the following files: