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
std::vector< std::size_t > ConvertToVertexPath_()
Переводит ребра, содержащихся в пути в последовательность обхода контрольных точек
Definition travelling_salesmans_problem.cpp:157
void ExpandStack_()
Заменяет вершину графа в path_stack_ на её детей, без нарушения порядка
Definition travelling_salesmans_problem.cpp:17
double paths_len_
Definition travelling_salesmans_problem.h:38
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 =
25 DeleteEdge_(with_edge_matrix, edge.end_num, edge.start_num);
26
27 // Исключение возможности цикла
28 std::map<std::size_t, std::size_t> prev_chains = paths_stack_[0]->chains;
29 std::map<std::size_t, std::size_t> new_chains = paths_stack_[0]->chains;
30 bool is_new = true;
31 for (const auto& [start, end] : prev_chains) {
32 if (start == edge.end_num) {
33 new_chains.erase(start);
34 new_chains[edge.start_num] = end;
35 is_new = false;
36 break;
37 } else if (end == edge.start_num) {
38 new_chains[start] = edge.end_num;
39 is_new = false;
40 break;
41 }
42 }
43 if (is_new) new_chains[edge.start_num] = edge.end_num;
44 for (const auto& [start, end] : new_chains) {
45 for (const auto& [start2, end2] : new_chains) {
46 if (end2 == start) {
47 new_chains[start2] = end;
48 new_chains.erase(start);
49 }
50 if (end == start2) {
51 new_chains[start] = end2;
52 new_chains.erase(start2);
53 }
54 }
55 }
56 for (const auto& [start, end] : new_chains) {
57 with_edge_matrix = DeleteEdge_(with_edge_matrix, end, start);
58 }
59 // Исключение возможности цикла
60
61 with_edge_matrix = with_edge_matrix.Minor(value.first, value.second);
62 paths_stack_[0]->with_edge = std::make_shared<TSPNode>(
63 with_edge_matrix, paths_stack_[0], edge, new_chains);
64 if (paths_stack_[0]->with_edge->matrix.GetSize() == 2)
65 CompleteEdgePath_(paths_stack_[0]->with_edge);
66
67 // Второй ребенок, c исключением edge
68 AdjacencyMatrix without_edge_matrix = paths_stack_[0]->matrix.Reducted();
69 without_edge_matrix =
70 DeleteEdge_(without_edge_matrix, edge.start_num, edge.end_num);
71 paths_stack_[0]->without_edge =
72 std::make_shared<TSPNode>(without_edge_matrix, paths_stack_[0]);
73
74 // Добавляем детей в стек вершин,удаляем их родителя
75 double with_eval = paths_stack_[0]->with_edge->evaluation;
76 double without_eval = paths_stack_[0]->without_edge->evaluation;
77 if (!std::isinf(without_eval)) {
78 if (FindIndex_(without_eval) < paths_stack_.size())
79 paths_stack_.insert(paths_stack_.begin() + FindIndex_(without_eval),
80 paths_stack_[0]->without_edge);
81 else
82 paths_stack_.push_back(paths_stack_[0]->without_edge);
83 }
84 if (!std::isinf(with_eval)) {
85 if (FindIndex_(with_eval) < paths_stack_.size())
86 paths_stack_.insert(paths_stack_.begin() + FindIndex_(with_eval),
87 paths_stack_[0]->with_edge);
88 else
89 paths_stack_.push_back(paths_stack_[0]->with_edge);
90 }
91 paths_stack_.erase(paths_stack_.begin());
92}
AdjacencyMatrix & DeleteEdge_(AdjacencyMatrix &matrix, std::size_t start_num, std::size_t end_num)
Удаляет ребро из матрицы смежности
Definition travelling_salesmans_problem.cpp:94
std::size_t FindIndex_(double eval) const
Находит место для вставки вершины для соблюдения порядка
Definition travelling_salesmans_problem.cpp:110
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: