1 /* Template class for Dijkstra's algorithm on directed graphs.
2 Copyright (C) 2019-2020 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #ifndef GCC_SHORTEST_PATHS_H
22 #define GCC_SHORTEST_PATHS_H
26 /* A record of the shortest path to each node in an graph
28 The constructor runs Dijkstra's algorithm, and the results are
29 stored in this class. */
31 template <typename GraphTraits
, typename Path_t
>
35 typedef typename
GraphTraits::graph_t graph_t
;
36 typedef typename
GraphTraits::node_t node_t
;
37 typedef typename
GraphTraits::edge_t edge_t
;
38 typedef Path_t path_t
;
40 shortest_paths (const graph_t
&graph
, const node_t
*origin
);
42 path_t
get_shortest_path (const node_t
*to
) const;
45 const graph_t
&m_graph
;
47 /* For each node (by index), the minimal distance to that node from the
51 /* For each exploded_node (by index), the previous edge in the shortest
52 path from the origin. */
53 auto_vec
<const edge_t
*> m_prev
;
56 /* shortest_paths's constructor.
58 Use Dijkstra's algorithm relative to ORIGIN to populate m_dist and
59 m_prev with enough information to be able to generate Path_t instances
60 to give the shortest path to any node in GRAPH from ORIGIN. */
62 template <typename GraphTraits
, typename Path_t
>
64 shortest_paths
<GraphTraits
, Path_t
>::shortest_paths (const graph_t
&graph
,
67 m_dist (graph
.m_nodes
.length ()),
68 m_prev (graph
.m_nodes
.length ())
70 auto_timevar
tv (TV_ANALYZER_SHORTEST_PATHS
);
72 auto_vec
<int> queue (graph
.m_nodes
.length ());
74 for (unsigned i
= 0; i
< graph
.m_nodes
.length (); i
++)
76 m_dist
.quick_push (INT_MAX
);
77 m_prev
.quick_push (NULL
);
80 m_dist
[origin
->m_index
] = 0;
82 while (queue
.length () > 0)
84 /* Get minimal distance in queue.
85 FIXME: this is O(N^2); replace with a priority queue. */
86 int idx_with_min_dist
= -1;
87 int idx_in_queue_with_min_dist
= -1;
88 int min_dist
= INT_MAX
;
89 for (unsigned i
= 0; i
< queue
.length (); i
++)
92 if (m_dist
[queue
[i
]] < min_dist
)
94 min_dist
= m_dist
[idx
];
95 idx_with_min_dist
= idx
;
96 idx_in_queue_with_min_dist
= i
;
99 gcc_assert (idx_with_min_dist
!= -1);
100 gcc_assert (idx_in_queue_with_min_dist
!= -1);
102 // FIXME: this is confusing: there are two indices here
104 queue
.unordered_remove (idx_in_queue_with_min_dist
);
107 = static_cast <node_t
*> (m_graph
.m_nodes
[idx_with_min_dist
]);
111 FOR_EACH_VEC_ELT (n
->m_succs
, i
, succ
)
113 // TODO: only for dest still in queue
114 node_t
*dest
= succ
->m_dest
;
115 int alt
= m_dist
[n
->m_index
] + 1;
116 if (alt
< m_dist
[dest
->m_index
])
118 m_dist
[dest
->m_index
] = alt
;
119 m_prev
[dest
->m_index
] = succ
;
125 /* Generate an Path_t instance giving the shortest path to the node
126 TO from the origin node. */
128 template <typename GraphTraits
, typename Path_t
>
130 shortest_paths
<GraphTraits
, Path_t
>::get_shortest_path (const node_t
*to
) const
134 while (m_prev
[to
->m_index
])
136 result
.m_edges
.safe_push (m_prev
[to
->m_index
]);
137 to
= m_prev
[to
->m_index
]->m_src
;
140 result
.m_edges
.reverse ();
145 #endif /* GCC_SHORTEST_PATHS_H */