Skip to content

Commit

Permalink
adding unittests to STNetwork
Browse files Browse the repository at this point in the history
  • Loading branch information
Aymane Lotfi committed Apr 11, 2024
1 parent 514c2c1 commit 4bb9a0b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 170 deletions.
114 changes: 0 additions & 114 deletions graph_utils/SpaceTimeNetwork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,10 @@ SpaceTimeNetwork::SpaceTimeNetwork(const string& network_file, const int& time_h
ArcST::restart_id_counter();
parse_logistic_network(network_file);
build_underlying_graph(this->network);
cout << this->underlying_graph.toString() << endl;
build_vertices(time_horizon);
cout << "\n\nSORT ADJACENCY LISTS FOR GRAPH ALGORITHMS --- STARTING\n\n";
this->sort_adjacency_list_out();
cout << "\n\nSORT ADJACENCY LISTS FOR GRAPH ALGORITHMS --- COMPLETED\n\n";
build_arcs(this->network, time_horizon);
build_lorries(this->network);
cout << toString() << endl;
cout << "\n\nCOMPUTE ADJACENCY LISTS FOR GRAPH ALGORITHMS --- STARTING\n\n";
this->initialise_adjacency_lists_graph_algorithms("length");
cout << "\n\nCOMPUTE TOPOLOGICAL ORDER --- STARTING\n\n";
}


Expand Down Expand Up @@ -62,7 +55,6 @@ SpaceTimeNetwork::SpaceTimeNetwork(const SpaceTimeNetwork& spaceTimeNetwork) {
this->vertex_dictionary = spaceTimeNetwork.vertex_dictionary;
this->lorries = spaceTimeNetwork.lorries;
this->network = spaceTimeNetwork.network;
this->adjacency_lists_graph_algorithms = spaceTimeNetwork.adjacency_lists_graph_algorithms;
this->adjacency_lists_arc_position = spaceTimeNetwork.adjacency_lists_arc_position;
}

Expand All @@ -73,7 +65,6 @@ SpaceTimeNetwork& SpaceTimeNetwork::operator=(const SpaceTimeNetwork& spaceTimeN
this->vertex_dictionary = spaceTimeNetwork.vertex_dictionary;
this->lorries = spaceTimeNetwork.lorries;
this->network = spaceTimeNetwork.network;
this->adjacency_lists_graph_algorithms = spaceTimeNetwork.adjacency_lists_graph_algorithms;
this->adjacency_lists_arc_position = spaceTimeNetwork.adjacency_lists_arc_position;
return *this;
}
Expand Down Expand Up @@ -115,7 +106,6 @@ void SpaceTimeNetwork::build_arcs(const operations_research::lattle::LogisticsNe
for (int i = 0; i < line.hub_ids().size() - 1; i++) {
string departure_hub = line.hub_ids().at(i);
string arrival_hub = line.hub_ids().at(i + 1);
//cout << departure_hub << "\t" << arrival_hub << endl;
double cost = 0.0;
for (const auto& rotations : line.next_rotations()) {
operations_research::lattle::DateTimeRange dt = rotations.departure_times().at(departure_hub);
Expand Down Expand Up @@ -188,31 +178,6 @@ void SpaceTimeNetwork::add_to_adjacency_list_in(const ArcST& arc) {
}



const vector<int> SpaceTimeNetwork::get_hub_time_after_t(const int& hub, const int& time) const {
vector<int> v_ids;
const auto& finder_id = this->vertex_dictionary.find(hub);
assert(finder_id != this->vertex_dictionary.end());
for (unordered_map<int, int>::const_iterator it = finder_id->second.begin(); it != finder_id->second.end(); it++) {
if (it->first >= time) {
v_ids.push_back(it->second);
}
}
return v_ids;
}

const vector<int> SpaceTimeNetwork::get_hub_time_before_t(const int& hub, const int& time) const {
vector<int> v_ids;
const auto& finder_id = this->vertex_dictionary.find(hub);
assert(finder_id != this->vertex_dictionary.end());
for (unordered_map<int, int>::const_iterator it = finder_id->second.begin(); it != finder_id->second.end(); it++) {
if (it->first <= time) {
v_ids.push_back(it->second);
}
}
return v_ids;
}

const VertexST& SpaceTimeNetwork::get_vertex(const string& hub, const operations_research::lattle::DateTimeRange& time) const {
int graph_id = this->underlying_graph.get_vertex(hub).get_id();
int encTime = ::time_encoder(time.first_date());
Expand All @@ -233,14 +198,6 @@ const VertexST& SpaceTimeNetwork::get_vertex(const int& hub, const int& time) co
return this->vertices.at(finder_time->second);
}

const vector<unordered_map<int, double>>& SpaceTimeNetwork::get_adjacency_lists_graph_algorithms() const {
return this->adjacency_lists_graph_algorithms;
}

const vector<unordered_map<int, int>>& SpaceTimeNetwork::get_adjacency_lists_arc_position() const {
return this->adjacency_lists_arc_position;
}


void SpaceTimeNetwork::add_vertexST(const int& hub, const int& time) {
auto dict1 = this->vertex_dictionary.find(hub);
Expand All @@ -267,77 +224,6 @@ void SpaceTimeNetwork::add_vertexST(const string& hub, const operations_research
add_vertexST(v.get_id(), encTime);
}

void SpaceTimeNetwork::initialise_adjacency_lists_arc_position() {
this->adjacency_lists_arc_position = vector<unordered_map<int, int>>(this->vertices.size());
for (const auto& vertex : this->vertices) {
for (const auto& neighbour : vertex.get_adjacency_list_out()) {
this->adjacency_lists_arc_position.at(vertex.get_id()).insert(make_pair(neighbour.first, 0));
}
}
}

void SpaceTimeNetwork::initialise_adjacency_lists_graph_algorithms(const string& type) {
this->adjacency_lists_graph_algorithms = vector<unordered_map<int, double>>(this->vertices.size());
if (type == "length") {
for (const auto& vertex : this->vertices) {
for (const auto& neighbour : vertex.get_adjacency_list_out()) {
this->adjacency_lists_graph_algorithms.at(vertex.get_id()).insert(make_pair(neighbour.first, 1.0));
}
}
}
else if (type == "cost") {
for (const auto& vertex : this->vertices) {
for (const auto& neighbour : vertex.get_adjacency_list_out_cost()) {
int arcId = neighbour.second.front();
this->adjacency_lists_graph_algorithms.at(vertex.get_id()).insert(make_pair(neighbour.first, this->arcs.at(arcId).get_cost()));
}
}
}
else if (type == "time") {
for (const auto& vertex : this->vertices) {
for (const auto& neighbour : vertex.get_adjacency_list_out_time()) {
int arcId = neighbour.second.front();
this->adjacency_lists_graph_algorithms.at(vertex.get_id()).insert(make_pair(neighbour.first, this->arcs.at(arcId).get_travelling_time()));
}
}
}
else {
cout << "\n\nWRONG TYPE in initialise_adjacency_lists_graph_algorithms\n\n";
exit(EXIT_FAILURE);
}
}

void SpaceTimeNetwork::restore_adjacency_lists_graph_value(const string& type, const int& u, const int& v) {
double new_value = 1.0;
this->adjacency_lists_arc_position.at(u).at(v) = 0;
if (type == "cost") {
int arcId = this->vertices.at(u).get_adjacency_list_out_cost().at(v).at(0);
new_value = this->arcs.at(arcId).get_cost();
}
else if (type == "time") {
int arcId = this->vertices.at(u).get_adjacency_list_out_time().at(v).at(0);
new_value = this->arcs.at(arcId).get_travelling_time();
}
this->adjacency_lists_graph_algorithms.at(u).at(v) = new_value;
}

void SpaceTimeNetwork::modify_adjacency_lists_graph_value(const string& type, const int& u, const int& v, const int& position_in_adj_list) {
double new_value = ::OMEGA * ::OMEGA;
if (type != "length" && position_in_adj_list < this->vertices.at(u).get_adjacency_list_out().at(v).size() - 1) {
int current_arc_position = position_in_adj_list + 1;
this->adjacency_lists_arc_position.at(u).at(v) = current_arc_position;
if (type == "cost") {
int arcId = this->vertices.at(u).get_adjacency_list_out_cost().at(v).at(current_arc_position);
new_value = this->arcs.at(arcId).get_cost();
}
else if (type == "time") {
int arcId = this->vertices.at(u).get_adjacency_list_out_time().at(v).at(current_arc_position);
new_value = this->arcs.at(arcId).get_travelling_time();
}
}
this->adjacency_lists_graph_algorithms.at(u).at(v) = new_value;
}

const operations_research::lattle::LogisticsNetwork& SpaceTimeNetwork::get_network() const {
return this->network;
}
Expand Down
55 changes: 0 additions & 55 deletions graph_utils/SpaceTimeNetwork.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,6 @@ class SpaceTimeNetwork {
*/
unordered_map<int, unordered_map<int, int>> vertex_dictionary;

/**
* Adjacency lists used in the graph algorithms, e.g., dfs, Yen, spp
* the space-time network is a multigraph, instead adjacency_lists_graph_algorithms contains only one arc between two vertices.
* adjacency_lists_graph_algorithms[u] = adj list of vertex u = pairs (v,cost) where (u,v) is an arc in the network and cost is its associated cost
* This data structure is mutable
*/
vector<unordered_map<int,double>> adjacency_lists_graph_algorithms;
/**
* current arc processed in an adjacency list = the space-time network is a multi-graph used in the k-shortest path algorithm
*/
Expand Down Expand Up @@ -162,61 +155,13 @@ class SpaceTimeNetwork {
* \brief Sort arcs in adjacency lists by increasing cost, time
*/
void sort_adjacency_list_out();
/**
* \brief Get vertices (hub,t) where t >= time
*
* \param hub : int
* \param time : int
* \return vertices ids: vector<int>
*/
const vector<int> get_hub_time_after_t(const int& hub, const int& time) const;
/**
* \brief Get vertices (hub,t) where t <= time
*
* \param hub : int
* \param time : int
* \return vertices ids: vector<int>
*/
const vector<int> get_hub_time_before_t(const int& hub, const int& time) const;
/**
* \brief for each adjacency list the arc position is set to zero
*/
void initialise_adjacency_lists_arc_position();
/**
* \brief for each adjacency list graph algorithm
*/
void initialise_adjacency_lists_graph_algorithms(const string& type);
/**
* \brief restore value of arc (u,v) in adjacency list.
* If type is length set value to 1, otherwise set it to the best arc in the multi-graph
*
* \param type of value (lenght,cost, travelling time)
* \param vertex id u
* \param vertex id v
*/
void restore_adjacency_lists_graph_value(const string& type, const int& u, const int& v);
/**
* \brief modify value of arc (u,v) in adjacency list.
* If type is length do nothing, otherwise if there is another arc between u and v fix the values to those of that arc
* update list arc position container as well.
* if there is no other arc, set the value to infinity
*
* \param type of value (lenght,cost, travelling time)
* \param vertex id u
* \param vertex id v
* \param position of the arc to modify in the adjacency list
*/
void modify_adjacency_lists_graph_value(const string& type, const int& u, const int& v, const int& position_in_adj_list);


const operations_research::lattle::LogisticsNetwork& get_network() const;
const Graph& get_underlying_graph() const;
const vector<VertexST>& get_vertices() const;
const vector<ArcST>& get_arcs() const;
const VertexST& get_vertex(const string& hub, const operations_research::lattle::DateTimeRange& time) const;
const VertexST& get_vertex(const int& hub, const int& time) const;
const vector<unordered_map<int, double>>& get_adjacency_lists_graph_algorithms() const;
const vector<unordered_map<int, int>>& get_adjacency_lists_arc_position() const;

const string toString() const;

Expand Down
1 change: 0 additions & 1 deletion graph_utils/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ inline int randomIntBetween(int _min, int _max, mt19937& generator) {
int maximum = max(_min, _max);
uniform_int_distribution<int> distr(minimum, maximum);

//return distr(generator);
return minimum + (rand() % (int)(maximum - minimum + 1));

}
Expand Down
42 changes: 42 additions & 0 deletions tests/SpaceTimeNetwork_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <gtest/gtest.h>

#include "../graph_utils/SpaceTimeNetwork.h"

TEST(SpaceTimeNetworkTest, BuildVertices) {
operations_research::lattle::LogisticsNetwork network;
int time_horizon = 5;
SpaceTimeNetwork stn(network, time_horizon);
// Creating a network of 10 hubs.
for (int i = 0; i < 10; i++) {
operations_research::lattle::Hub h;
h.set_name("node_"+to_string(i));
network.mutable_hubs()->Add(move(h));
}
// Check that the correct number of vertices were created.
ASSERT_EQ(stn.get_vertices().size(), stn.get_underlying_graph().get_vertices().size() * time_horizon);

// Check that the vertices have the correct graph and time values.
for (int i = 0; i < stn.get_underlying_graph().get_vertices().size(); i++) {
for (int t = 0; t < time_horizon; t++) {
const VertexST& vertex = stn.get_vertex(i, t);
ASSERT_EQ(vertex.get_id_in_graph(), i);
ASSERT_EQ(vertex.get_time(), t);
}
}
}

//TODO(aymanelotfi) : Improve this by supporting get vertexST by id.
TEST(SpaceTimeNetworkTest, BuildArcs) {
operations_research::lattle::LogisticsNetwork network;
int time_horizon = 5;
SpaceTimeNetwork stn(network, time_horizon);

// Check that the correct number of arcs were created.
int num_travelling_arcs = 0;
int num_waiting_arcs = 0;
for (const auto& line : network.lines()) {
num_travelling_arcs += (line.hub_ids().size() - 1) * line.next_rotations().size();
}
num_waiting_arcs = stn.get_underlying_graph().get_vertices().size() * (time_horizon - 1);
ASSERT_EQ(stn.get_arcs().size(), num_travelling_arcs + num_waiting_arcs);
}

0 comments on commit 4bb9a0b

Please sign in to comment.