I am working on my master thesis and try to implement a new shortest path algorithm from the following paper: https://arxiv.org/abs/2203.03456
In some of the functions (for example ScaleDown), constant out-degree is required. The constant out-degree means that the out-degree of every vertex in a graph is the same.
The paper provides a method where you make zero-weight cycles of size in-degree + out-degree and replace the vertex with the cycle. The edges from the original vertex will be connected to the cycle. The shortest path does not get changed, because you can reach every in or outgoing vertex of the cycle with weight zero.
I tried it, but if you have more ingoing edges instead of outgoing not every vertex has the same degree. Than I tried only using the out-degree for the size of the cycle, but if a vertex has only ingoing edges, that does not work.
Here is my code for the described approach:
graph_t Shortest_path::make_constant_out_degree(graph_t graph, int num_vertices) {
// Create a new graph to store the augmented graph.
graph_t augmented_graph;
// Maps to keep track of the new vertices corresponding to the original vertices.
std::vector<std::vector<graph_t::vertex_descriptor>> vertex_cycles(boost::num_vertices(graph));
// Iterate over all vertices to create cycles.
graph_t::vertex_iterator vi, vi_end;
for (tie(vi, vi_end) = vertices(graph); vi != vi_end; ++vi) {
//auto in_degree = boost::in_degree(*vi, graph);
auto out_degree = boost::out_degree(*vi, graph);
// Size of the cycle is the sum of in_degree and out_degree.
//size_t cycle_size = in_degree + out_degree;
size_t cycle_size = out_degree;
// Create the cycle with zero-weight edges.
graph_t::vertex_descriptor prev_vertex = add_vertex(augmented_graph);
vertex_cycles[*vi].push_back(prev_vertex);
for (size_t i = 1; i < cycle_size; ++i) {
graph_t::vertex_descriptor new_vertex = add_vertex(augmented_graph);
vertex_cycles[*vi].push_back(new_vertex);
add_edge(prev_vertex, new_vertex, 0, augmented_graph);
prev_vertex = new_vertex;
}
// Connect the last vertex to the first to complete the cycle.
add_edge(prev_vertex, vertex_cycles[*vi][0], 0, augmented_graph);
}
print_graph(augmented_graph);
// Attach adjacent edges to their corresponding cycles.
graph_t::edge_iterator ei, ei_end;
for (tie(ei, ei_end) = edges(graph); ei != ei_end; ++ei) {
// Each edge connects between two cycles corresponding to the source and target.
vertex_descriptor src = source(*ei, graph);
vertex_descriptor tgt = target(*ei, graph);
int weight = get(edge_weight, graph, *ei);
// Attach the edge to any vertex in each of the two cycles. Remove vertex from list if it is used
add_edge(vertex_cycles[src].back(), vertex_cycles[tgt].front(), weight, augmented_graph);
vertex_cycles[src].erase(
std::remove(vertex_cycles[src].begin(), vertex_cycles[src].end(), vertex_cycles[src].back()),
vertex_cycles[src].end());
}
return augmented_graph;
}
Does anyone know another method to convert a given graph into one with constant out-degree or sees the mistake I am making?