Enable just-before-contraction updates to edge weights. For small

datasets, this enables things like traffic-based updates in the
shortest possible processing turnaround time.
This commit is contained in:
Daniel Patterson
2015-10-14 15:08:22 -07:00
parent 578d947e2d
commit 6228412e61
13 changed files with 1597 additions and 27 deletions
+78 -4
View File
@@ -26,12 +26,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "edge_based_graph_factory.hpp"
#include "../algorithms/coordinate_calculation.hpp"
#include "../data_structures/percent.hpp"
#include "../util/compute_angle.hpp"
#include "../util/integer_range.hpp"
#include "../util/lua_util.hpp"
#include "../util/simple_logger.hpp"
#include "../util/timing_util.hpp"
#include "../util/osrm_exception.hpp"
#include <boost/assert.hpp>
@@ -221,7 +223,11 @@ void EdgeBasedGraphFactory::FlushVectorToStream(
}
void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
lua_State *lua_state)
lua_State *lua_state,
const std::string &edge_segment_lookup_filename,
const std::string &edge_penalty_filename,
const bool generate_edge_lookup
)
{
TIMER_START(renumber);
m_max_edge_id = RenumberEdges() - 1;
@@ -232,7 +238,9 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
TIMER_STOP(generate_nodes);
TIMER_START(generate_edges);
GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state);
GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state,
edge_segment_lookup_filename,edge_penalty_filename, generate_edge_lookup
);
TIMER_STOP(generate_edges);
SimpleLogger().Write() << "Timing statistics for edge-expanded graph:";
@@ -317,7 +325,11 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
/// Actually it also generates OriginalEdgeData and serializes them...
void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const std::string &original_edge_data_filename, lua_State *lua_state)
const std::string &original_edge_data_filename, lua_State *lua_state,
const std::string &edge_segment_lookup_filename,
const std::string &edge_fixed_penalties_filename,
const bool generate_edge_lookup
)
{
SimpleLogger().Write() << "generating edge-expanded edges";
@@ -325,6 +337,14 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
unsigned original_edges_counter = 0;
std::ofstream edge_data_file(original_edge_data_filename.c_str(), std::ios::binary);
std::ofstream edge_segment_file;
std::ofstream edge_penalty_file;
if (generate_edge_lookup)
{
edge_segment_file.open(edge_segment_lookup_filename.c_str(), std::ios::binary);
edge_penalty_file.open(edge_fixed_penalties_filename.c_str(), std::ios::binary);
}
// writes a dummy value that is updated later
edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
@@ -437,7 +457,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
if (turn_instruction == TurnInstruction::UTurn)
{
distance += speed_profile.u_turn_penalty;
}
}
distance += turn_penalty;
const bool edge_is_compressed = m_compressed_edge_container.HasEntryForID(e1);
@@ -464,6 +485,59 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
m_edge_based_edge_list.emplace_back(edge_data1.edge_id, edge_data2.edge_id,
m_edge_based_edge_list.size(), distance, true, false);
// Here is where we write out the mapping between the edge-expanded edges, and
// the node-based edges that are originally used to calculate the `distance`
// for the edge-expanded edges. About 40 lines back, there is:
//
// unsigned distance = edge_data1.distance;
//
// This tells us that the weight for an edge-expanded-edge is based on the weight
// of the *source* node-based edge. Therefore, we will look up the individual
// segments of the source node-based edge, and write out a mapping between
// those and the edge-based-edge ID.
// External programs can then use this mapping to quickly perform
// updates to the edge-expanded-edge based directly on its ID.
if (generate_edge_lookup)
{
unsigned fixed_penalty = distance - edge_data1.distance;
edge_penalty_file.write(reinterpret_cast<const char *>(&fixed_penalty), sizeof(fixed_penalty));
if (edge_is_compressed)
{
const auto node_based_edges = m_compressed_edge_container.GetBucketReference(e1);
NodeID previous = node_u;
const unsigned node_count = node_based_edges.size()+1;
edge_segment_file.write(reinterpret_cast<const char *>(&node_count), sizeof(node_count));
const QueryNode &first_node = m_node_info_list[previous];
edge_segment_file.write(reinterpret_cast<const char *>(&first_node.node_id), sizeof(first_node.node_id));
for (auto target_node : node_based_edges)
{
const QueryNode &from = m_node_info_list[previous];
const QueryNode &to = m_node_info_list[target_node.first];
const double segment_length = coordinate_calculation::great_circle_distance(from.lat, from.lon, to.lat, to.lon);
edge_segment_file.write(reinterpret_cast<const char *>(&to.node_id), sizeof(to.node_id));
edge_segment_file.write(reinterpret_cast<const char *>(&segment_length), sizeof(segment_length));
edge_segment_file.write(reinterpret_cast<const char *>(&target_node.second), sizeof(target_node.second));
previous = target_node.first;
}
}
else
{
static const unsigned node_count = 2;
const QueryNode from = m_node_info_list[node_u];
const QueryNode to = m_node_info_list[node_v];
const double segment_length = coordinate_calculation::great_circle_distance(from.lat, from.lon, to.lat, to.lon);
edge_segment_file.write(reinterpret_cast<const char *>(&node_count), sizeof(node_count));
edge_segment_file.write(reinterpret_cast<const char *>(&from.node_id), sizeof(from.node_id));
edge_segment_file.write(reinterpret_cast<const char *>(&to.node_id), sizeof(to.node_id));
edge_segment_file.write(reinterpret_cast<const char *>(&segment_length), sizeof(segment_length));
edge_segment_file.write(reinterpret_cast<const char *>(&edge_data1.distance), sizeof(edge_data1.distance));
}
}
}
}
}
+10 -2
View File
@@ -67,7 +67,11 @@ class EdgeBasedGraphFactory
SpeedProfileProperties speed_profile);
void Run(const std::string &original_edge_data_filename,
lua_State *lua_state);
lua_State *lua_state,
const std::string &edge_segment_lookup_filename,
const std::string &edge_penalty_filename,
const bool generate_edge_lookup
);
void GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &edges);
@@ -100,7 +104,11 @@ class EdgeBasedGraphFactory
unsigned RenumberEdges();
void GenerateEdgeExpandedNodes();
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
lua_State *lua_state);
lua_State *lua_state,
const std::string &edge_segment_lookup_filename,
const std::string &edge_fixed_penalties_filename,
const bool generate_edge_lookup
);
void InsertEdgeBasedNode(const NodeID u, const NodeID v);
+5 -1
View File
@@ -532,7 +532,11 @@ extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_n
compressed_edge_container.SerializeInternalVector(config.geometry_output_path);
edge_based_graph_factory.Run(config.edge_output_path, lua_state);
edge_based_graph_factory.Run(config.edge_output_path, lua_state,
config.edge_segment_lookup_path,
config.edge_penalty_path,
config.generate_edge_lookup
);
lua_close(lua_state);
edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list);
+13 -1
View File
@@ -61,7 +61,10 @@ ExtractorOptions::ParseArguments(int argc, char *argv[], ExtractorConfig &extrac
"threads,t",
boost::program_options::value<unsigned int>(&extractor_config.requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use");
"Number of threads to use")(
"generate-edge-lookup",boost::program_options::value<bool>(
&extractor_config.generate_edge_lookup)->implicit_value(true)->default_value(false),
"Generate a lookup table for internal edge-expanded-edge IDs to OSM node pairs");
// hidden options, will be allowed both on command line and in config file, but will not be
// shown to the user
@@ -70,6 +73,7 @@ ExtractorOptions::ParseArguments(int argc, char *argv[], ExtractorConfig &extrac
&extractor_config.input_path),
"Input file in .osm, .osm.bz2 or .osm.pbf format");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("input", 1);
@@ -149,6 +153,8 @@ void ExtractorOptions::GenerateOutputFilesNames(ExtractorConfig &extractor_confi
extractor_config.node_output_path = input_path.string();
extractor_config.rtree_nodes_output_path = input_path.string();
extractor_config.rtree_leafs_output_path = input_path.string();
extractor_config.edge_segment_lookup_path = input_path.string();
extractor_config.edge_penalty_path = input_path.string();
std::string::size_type pos = extractor_config.output_file_name.find(".osm.bz2");
if (pos == std::string::npos)
{
@@ -177,6 +183,8 @@ void ExtractorOptions::GenerateOutputFilesNames(ExtractorConfig &extractor_confi
extractor_config.edge_graph_output_path.append(".osrm.ebg");
extractor_config.rtree_nodes_output_path.append(".osrm.ramIndex");
extractor_config.rtree_leafs_output_path.append(".osrm.fileIndex");
extractor_config.edge_segment_lookup_path.append(".osrm.edge_segment_lookup");
extractor_config.edge_penalty_path.append(".osrm.edge_penalties");
}
else
{
@@ -190,6 +198,8 @@ void ExtractorOptions::GenerateOutputFilesNames(ExtractorConfig &extractor_confi
extractor_config.edge_graph_output_path.replace(pos, 5, ".osrm.ebg");
extractor_config.rtree_nodes_output_path.replace(pos, 5, ".osrm.ramIndex");
extractor_config.rtree_leafs_output_path.replace(pos, 5, ".osrm.fileIndex");
extractor_config.edge_segment_lookup_path.replace(pos,5, ".osrm.edge_segment_lookup");
extractor_config.edge_penalty_path.replace(pos,5, ".osrm.edge_penalties");
}
}
else
@@ -204,5 +214,7 @@ void ExtractorOptions::GenerateOutputFilesNames(ExtractorConfig &extractor_confi
extractor_config.edge_graph_output_path.replace(pos, 8, ".osrm.ebg");
extractor_config.rtree_nodes_output_path.replace(pos, 8, ".osrm.ramIndex");
extractor_config.rtree_leafs_output_path.replace(pos, 8, ".osrm.fileIndex");
extractor_config.edge_segment_lookup_path.replace(pos,8, ".osrm.edge_segment_lookup");
extractor_config.edge_penalty_path.replace(pos,8, ".osrm.edge_penalties");
}
}
+4
View File
@@ -58,6 +58,10 @@ struct ExtractorConfig
std::string rtree_leafs_output_path;
unsigned requested_num_threads;
bool generate_edge_lookup;
std::string edge_penalty_path;
std::string edge_segment_lookup_path;
};
struct ExtractorOptions