HAL
shortest_path.cpp
Go to the documentation of this file.
2 
5 
6 namespace hal
7 {
8  namespace graph_algorithm
9  {
11  {
12  if (graph == nullptr)
13  {
14  return ERR("graph is a nullptr");
15  }
16 
17  if (!from_gate)
18  {
19  return ERR("no source gate provided");
20  }
21 
22  if (to_gates.empty())
23  {
24  return ERR("no destination gates provided");
25  }
26 
27  u32 from_vertex;
28  if (auto res = graph->get_vertex_from_gate(from_gate); res.is_ok())
29  {
30  from_vertex = res.get();
31  }
32  else
33  {
34  return ERR(res.get_error());
35  }
36 
37  igraph_vector_int_t i_to_vertices;
38  if (auto res = graph->get_vertices_from_gates_igraph(to_gates); res.is_ok())
39  {
40  i_to_vertices = std::move(res.get());
41  }
42  else
43  {
44  return ERR(res.get_error());
45  }
46 
47  auto res = get_shortest_paths_igraph(graph, from_vertex, &i_to_vertices, direction);
48 
49  igraph_vector_int_destroy(&i_to_vertices);
50 
51  if (res.is_error())
52  {
53  return ERR(res.get_error());
54  }
55 
56  return res;
57  }
58 
59  Result<std::vector<std::vector<u32>>> get_shortest_paths(NetlistGraph* graph, u32 from_vertex, const std::vector<u32>& to_vertices, NetlistGraph::Direction direction)
60  {
61  if (graph == nullptr)
62  {
63  return ERR("graph is a nullptr");
64  }
65 
66  if (to_vertices.empty())
67  {
68  return ERR("no destination vertices provided");
69  }
70 
71  igraph_vector_int_t i_to_vertices;
72  if (auto res = igraph_vector_int_init(&i_to_vertices, to_vertices.size()); res != IGRAPH_SUCCESS)
73  {
74  return ERR(igraph_strerror(res));
75  }
76 
77  for (u32 i = 0; i < to_vertices.size(); i++)
78  {
79  VECTOR(i_to_vertices)[i] = to_vertices.at(i);
80  }
81 
82  auto res = get_shortest_paths_igraph(graph, from_vertex, &i_to_vertices, direction);
83 
84  igraph_vector_int_destroy(&i_to_vertices);
85 
86  if (res.is_error())
87  {
88  return ERR(res.get_error());
89  }
90 
91  return res;
92  }
93 
95  {
96  if (graph == nullptr)
97  {
98  return ERR("graph is a nullptr");
99  }
100 
101  igraph_neimode_t mode;
102  switch (direction)
103  {
105  mode = IGRAPH_IN;
106  break;
108  mode = IGRAPH_OUT;
109  break;
111  mode = IGRAPH_ALL;
112  break;
114  return ERR("invalid direction 'NONE'");
115  }
116 
117  igraph_vs_t v_sel = igraph_vss_vector(to_vertices);
118  igraph_vector_int_list_t paths_raw;
119  if (auto res = igraph_vector_int_list_init(&paths_raw, 1); res != IGRAPH_SUCCESS)
120  {
121  igraph_vs_destroy(&v_sel);
122  return ERR(igraph_strerror(res));
123  }
124 
125  if (auto res = igraph_get_shortest_paths(graph->get_graph(), &paths_raw, nullptr, from_vertex, v_sel, mode, nullptr, nullptr); res != IGRAPH_SUCCESS)
126  {
127  igraph_vs_destroy(&v_sel);
128  igraph_vector_int_list_destroy(&paths_raw);
129  return ERR(igraph_strerror(res));
130  }
131 
132  std::vector<std::vector<u32>> paths;
133  for (u32 i = 0; i < igraph_vector_int_list_size(&paths_raw); i++)
134  {
135  auto vec = igraph_vector_int_list_get_ptr(&paths_raw, i);
136 
137  u32 vec_size = igraph_vector_int_size(vec);
138  std::vector<u32> tmp(vec_size);
139  for (u32 j = 0; j < igraph_vector_int_size(vec); j++)
140  {
141  tmp[j] = VECTOR(*vec)[j];
142  }
143  paths.push_back(std::move(tmp));
144  }
145 
146  igraph_vs_destroy(&v_sel);
147  igraph_vector_int_list_destroy(&paths_raw);
148 
149  return OK(paths);
150  }
151 
153  {
154  if (graph == nullptr)
155  {
156  return ERR("graph is a nullptr");
157  }
158 
159  if (!from_gate)
160  {
161  return ERR("no source gate provided");
162  }
163 
164  if (to_gates.empty())
165  {
166  return ERR("no destination gates provided");
167  }
168 
169  u32 from_vertex;
170  if (auto res = graph->get_vertex_from_gate(from_gate); res.is_ok())
171  {
172  from_vertex = res.get();
173  }
174  else
175  {
176  return ERR(res.get_error());
177  }
178 
179  igraph_vector_int_t i_to_vertices;
180  if (auto res = graph->get_vertices_from_gates_igraph(to_gates); res.is_ok())
181  {
182  i_to_vertices = std::move(res.get());
183  }
184  else
185  {
186  return ERR(res.get_error());
187  }
188 
189  auto res = get_all_shortest_paths_igraph(graph, from_vertex, &i_to_vertices, direction);
190 
191  igraph_vector_int_destroy(&i_to_vertices);
192 
193  if (res.is_error())
194  {
195  return ERR(res.get_error());
196  }
197 
198  return res;
199  }
200 
202  {
203  if (graph == nullptr)
204  {
205  return ERR("graph is a nullptr");
206  }
207 
208  if (to_vertices.empty())
209  {
210  return ERR("no destination vertices provided");
211  }
212 
213  igraph_vector_int_t i_to_vertices;
214  if (auto res = igraph_vector_int_init(&i_to_vertices, to_vertices.size()); res != IGRAPH_SUCCESS)
215  {
216  return ERR(igraph_strerror(res));
217  }
218 
219  for (u32 i = 0; i < to_vertices.size(); i++)
220  {
221  VECTOR(i_to_vertices)[i] = to_vertices.at(i);
222  }
223 
224  auto res = get_all_shortest_paths_igraph(graph, from_vertex, &i_to_vertices, direction);
225 
226  igraph_vector_int_destroy(&i_to_vertices);
227 
228  if (res.is_error())
229  {
230  return ERR(res.get_error());
231  }
232 
233  return res;
234  }
235 
237  {
238  if (graph == nullptr)
239  {
240  return ERR("graph is a nullptr");
241  }
242 
243  igraph_neimode_t mode;
244  switch (direction)
245  {
247  mode = IGRAPH_IN;
248  break;
250  mode = IGRAPH_OUT;
251  break;
253  mode = IGRAPH_ALL;
254  break;
256  return ERR("invalid direction 'NONE'");
257  }
258 
259  igraph_vs_t v_sel = igraph_vss_vector(to_vertices);
260  igraph_vector_int_list_t paths_raw;
261  if (auto res = igraph_vector_int_list_init(&paths_raw, 1); res != IGRAPH_SUCCESS)
262  {
263  igraph_vs_destroy(&v_sel);
264  return ERR(igraph_strerror(res));
265  }
266 
267  if (auto res = igraph_get_all_shortest_paths(graph->get_graph(), &paths_raw, nullptr, nullptr, from_vertex, v_sel, mode); res != IGRAPH_SUCCESS)
268  {
269  igraph_vs_destroy(&v_sel);
270  igraph_vector_int_list_destroy(&paths_raw);
271  return ERR(igraph_strerror(res));
272  }
273 
274  std::vector<std::vector<u32>> paths;
275  const u32 paths_size = igraph_vector_int_list_size(&paths_raw);
276  for (u32 i = 0; i < paths_size; i++)
277  {
278  auto vec = igraph_vector_int_list_get_ptr(&paths_raw, i);
279 
280  const u32 vec_size = igraph_vector_int_size(vec);
281  std::vector<u32> tmp(vec_size);
282  for (u32 j = 0; j < vec_size; j++)
283  {
284  tmp[j] = VECTOR(*vec)[j];
285  }
286  paths.push_back(std::move(tmp));
287  }
288 
289  igraph_vs_destroy(&v_sel);
290  igraph_vector_int_list_destroy(&paths_raw);
291 
292  return OK(paths);
293  }
294  } // namespace graph_algorithm
295 } // namespace hal
Definition: gate.h:58
A directed graph corresponding to a netlist.
Definition: netlist_graph.h:57
Direction
The direction of exploration within the graph.
Definition: netlist_graph.h:64
@ ALL
Explore in both directions, i.e., treat the graph as undirected.
@ NONE
No direction, invalid default setting.
@ IN
Explore through the inputs of the current node, i.e., traverse backwards.
@ OUT
Explore through the outputs of the current node, i.e., traverse forwards.
Result< u32 > get_vertex_from_gate(Gate *g) const
Get the vertex corresponding to the specified gate.
Result< igraph_vector_int_t > get_vertices_from_gates_igraph(const std::vector< Gate * > &gates) const
Get the vertices corresponding to the specified gates.
igraph_t * get_graph() const
Get the graph object of the netlist graph.
#define ERR(message)
Definition: result.h:53
#define OK(...)
Definition: result.h:49
Result< std::vector< std::vector< u32 > > > get_all_shortest_paths(NetlistGraph *graph, Gate *from_gate, const std::vector< Gate * > &to_gates, NetlistGraph::Direction direction)
Compute shortest paths from the specified from_gate to each of the given to_gates by traversing in th...
Result< std::vector< std::vector< u32 > > > get_shortest_paths(NetlistGraph *graph, Gate *from_gate, const std::vector< Gate * > &to_gates, NetlistGraph::Direction direction)
Compute a shortest path from the specified from_gate to each of the given to_gates by traversing in t...
Result< std::vector< std::vector< u32 > > > get_all_shortest_paths_igraph(NetlistGraph *graph, u32 from_vertex, const igraph_vector_int_t *to_vertices, NetlistGraph::Direction direction)
Compute shortest paths from the specified from_vertex to each of the given to_vertices by traversing ...
Result< std::vector< std::vector< u32 > > > get_shortest_paths_igraph(NetlistGraph *graph, u32 from_vertex, const igraph_vector_int_t *to_vertices, NetlistGraph::Direction direction)
Compute a shortest path from the specified from_vertex to each of the given to_vertices by traversing...
quint32 u32
PinDirection direction
This file contains the class that holds a netlist graph.
This file contains functions related to shortest paths in graphs.