routingkit-cch 0.1.4

Rust bindings for RoutingKit's Customizable Contraction Hierarchies (CCH)
Documentation
#include <routingkit/vector_io.h>
#include <routingkit/permutation.h>
#include <routingkit/inverse_vector.h>
#include <routingkit/customizable_contraction_hierarchy.h>
#include <routingkit/min_max.h>
#include <routingkit/timer.h>

#include <iostream>
#include <stdexcept>
#include <vector>

using namespace RoutingKit;
using namespace std;

int main(int argc, char*argv[]){

	try{
		long long timer;
	
		string first_out_file;
		string head_file;
		string weight_file;
		string cch_order_file;

		if(argc != 5){
			cerr << argv[0] << " first_out head weight_file cch_order" << endl;
			return 1;
		}else{
			first_out_file = argv[1];
			head_file = argv[2];
			weight_file = argv[3];
			cch_order_file = argv[4];
		}

		cout << "Loading Graph ... " << flush;

		auto first_out = load_vector<unsigned>(first_out_file);
		auto tail = invert_inverse_vector(first_out);
		auto head = load_vector<unsigned>(head_file);
		auto weight = load_vector<unsigned>(weight_file);

		cout << "done" << endl;

		cout << "Loading order ... " << flush;
		
		auto cch_order = load_vector<unsigned>(cch_order_file);

		cout << "done" << endl;

		cout << "Building CCH ... " << flush;
		
		timer = -get_micro_time();
		CustomizableContractionHierarchy cch(cch_order, invert_inverse_vector(first_out), head);
		timer += get_micro_time();

		cout << "done [" << timer << "musec]" << endl;

		cout << "Customizing CCH ... " << flush;
		
		timer = -get_micro_time();
		CustomizableContractionHierarchyMetric metric(cch, weight);
		metric.customize();
		timer += get_micro_time();

		cout << "done [" << timer << "musec]" << endl;

		cout << "Generating queries ... " << flush;

		const unsigned
			source_count = 500,
			target_count = 500;

		std::vector<unsigned>
			source_set(source_count),
			target_set(target_count);

		for(unsigned i=0; i<source_count; ++i)
			source_set[i] = rand() % cch.node_count();
		for(unsigned i=0; i<target_count; ++i)
			target_set[i] = rand() % cch.node_count();
		
		cout << "done" << endl;


		std::vector<unsigned>optimal_result(source_count * target_count);

		{
			timer = -get_micro_time();
			cout << "Running baseline ... " << flush;
		
			CustomizableContractionHierarchyQuery query(metric);
			for(unsigned s=0; s<source_count; ++s){
				for(unsigned t=0; t<target_count; ++t){
					optimal_result[s*target_count + t] = query.reset().add_source(source_set[s]).add_target(target_set[t]).run().get_distance();
				}
			}

			timer += get_micro_time();

			cout << "done ["<<timer << "musec]" << endl;
		}


		std::vector<unsigned>pinned_source_result(source_count * target_count);

		{


			long long select_time = 0;
			unsigned select_count = 0;
			long long query_time = 0;
			unsigned query_count = 0;

			timer = -get_micro_time();
			cout << "Running forward pinning ... " << flush;
		
			CustomizableContractionHierarchyQuery query(metric);

			select_time -= get_micro_time();
			query.reset();
			query.pin_targets(target_set);
			select_time += get_micro_time();
			++select_count;

			for(unsigned s=0; s<source_count; ++s){

				query_time -= get_micro_time();
				auto d = query.reset_source().add_source(source_set[s]).run_to_pinned_targets().get_distances_to_targets();

				for(unsigned t=0; t<target_count; ++t){
					pinned_source_result[s*target_count + t] = d[t];
				}
				query_time += get_micro_time();
				++query_count;
			}

			timer += get_micro_time();

			cout << "done [" << timer << "musec]" << endl;

			cout << "query_time" << " : " << query_time / query_count << "musec" << endl;
			cout << "pin_time" << " : " << select_time / select_count << "musec" << endl;
		}

		if(pinned_source_result != optimal_result){
			cout << "Pinned source is not correct" << endl;
		} else {
			cout << "No error with pinned source found" << endl;
		}

		std::vector<unsigned>pinned_target_result(source_count * target_count);

		{


			long long select_time = 0;
			unsigned select_count = 0;
			long long query_time = 0;
			unsigned query_count = 0;

			timer = -get_micro_time();
			cout << "Running forward pinning ... " << flush;
		
			CustomizableContractionHierarchyQuery query(metric);

			select_time -= get_micro_time();
			query.reset();
			query.pin_sources(source_set);
			select_time += get_micro_time();
			++select_count;

			for(unsigned t=0; t<target_count; ++t){

				query_time -= get_micro_time();
				auto d = query.reset_target().add_target(target_set[t]).run_to_pinned_sources().get_distances_to_sources();
				for(unsigned s=0; s<source_count; ++s){
					pinned_target_result[s*target_count + t] = d[s];
				}
				query_time += get_micro_time();
				++query_count;
			}

			timer += get_micro_time();

			cout << "done [" << timer << "musec]" << endl;

			cout << "query_time" << " : " << query_time / query_count << "musec" << endl;
			cout << "pin_time" << " : " << select_time / select_count << "musec" << endl;

		}

		if(pinned_target_result != optimal_result){
			cout << "Pinned target is not correct" << endl;
		} else {
			cout << "No error with pinned target found" << endl;
		}

	}catch(exception&err){
		cerr << "Stopped on exception : " << err.what() << endl;
		return 1;
	}
	return 0;
}