diff --git a/instance_generator/InstanceGenerator.cpp b/instance_generator/InstanceGenerator.cpp index 3849add..5aec7f8 100644 --- a/instance_generator/InstanceGenerator.cpp +++ b/instance_generator/InstanceGenerator.cpp @@ -46,7 +46,7 @@ void InstanceGenerator::generate_logistic_network(operations_research::lattle::I //fill line_rotation structure in the logistic network object int number_of_vehicles = generate_line_rotations(*instance.mutable_network(), random_graph, arc_weights, arc_weights_adj_lists, time_horizon, nbr_lines, max_length_line, - max_numb_rotations_per_line, max_travelling_time, travelling_time_perturbation); + max_numb_rotations_per_line); //Sample vehicle capacities add_vehicles(*instance.mutable_network(), number_of_vehicles, max_vehicle_capacity); @@ -193,7 +193,7 @@ vector InstanceGenerator::generate_line(const Graph& graph, const int& max_ } int InstanceGenerator::generate_line_rotations(operations_research::lattle::LogisticsNetwork& network, const Graph& graph, const vector& arc_weights, const vector>& arc_weights_adj_lists, - const int& time_horizon, const int& nbr_lines, const int& max_length_line, const int& max_numb_rotations_per_line, const int& max_travelling_time, const double& travelling_time_perturbation) const { + const int& time_horizon, const int& nbr_lines, const int& max_length_line, const int& max_numb_rotations_per_line) const { int vehicles_number = 0; //build lines @@ -201,7 +201,7 @@ int InstanceGenerator::generate_line_rotations(operations_research::lattle::Logi //generate a path in the random_graph vector line = generate_line(graph, max_length_line, arc_weights_adj_lists, arc_weights); - + vector> time_infos; //add rotations associated to the line @@ -215,19 +215,21 @@ int InstanceGenerator::generate_line_rotations(operations_research::lattle::Logi int start_time = ElRandom::Uniform(1,time_horizon - nbr_hubs + 1); time_info.push_back(start_time); // max_duration defined to make sure we can sample nbr_hubs times without exceeding the time horizon. - int max_duration = (time_horizon - start_time +1)/nbr_hubs; + assert(void("Number of hubs should be st. greater than 1",nbr_hubs > 1)); + int max_duration = (time_horizon - start_time)/(nbr_hubs - 1); for(int k = 2 ; k <= nbr_hubs ; k++){ int duration = ElRandom::Uniform(1,max_duration); start_time += duration; + assert(start_time <= time_horizon); time_info.push_back(start_time); } time_infos.push_back(time_info); vehicles_number++; } + assert(time_infos.size() == nbr_hubs); //fill rotation proto - if(!time_infos.empty()){ - add_line_rotation(network, graph, i+1, line, time_infos); - } + add_line_rotation(network, graph, i+1, line, time_infos); + } return vehicles_number; } @@ -247,7 +249,7 @@ void InstanceGenerator::add_line_rotation(operations_research::lattle::Logistics operations_research::lattle::LineRotation rotation; string name = "l" + to_string(line_nbr) + "_lr" + to_string(i + 1); - for (int j = 0; j < rotations.at(i).size() - 1; j++) { + for (int j = 0; j + 1 < rotations.at(i).size(); j++) { string start_hub = graph.get_vertex(line.at(j)).get_name(); string end_hub = graph.get_vertex(line.at(j + 1)).get_name(); diff --git a/instance_generator/InstanceGenerator.h b/instance_generator/InstanceGenerator.h index a99c3e6..9949cb9 100644 --- a/instance_generator/InstanceGenerator.h +++ b/instance_generator/InstanceGenerator.h @@ -135,7 +135,7 @@ class InstanceGenerator { * \return vehicle number */ int generate_line_rotations(operations_research::lattle::LogisticsNetwork& network, const Graph& graph, const vector& arc_weights, const vector>& arc_weights_adj_lists, - const int& time_horizon, const int& nbr_lines, const int& max_length_line, const int& max_numb_rotations_per_line, const int& max_travelling_time, const double& travelling_time_perturbation) const; + const int& time_horizon, const int& nbr_lines, const int& max_length_line, const int& max_numb_rotations_per_line) const; /* * sample the lines (see 2 in generate_logistic_network) * diff --git a/tests/InstanceGenerator_test.cpp b/tests/InstanceGenerator_test.cpp index 773c3ed..a9cbb21 100644 --- a/tests/InstanceGenerator_test.cpp +++ b/tests/InstanceGenerator_test.cpp @@ -75,26 +75,111 @@ TEST(InstanceGeneratorTest, GenerateLine) { } -// // Test that the GraphInstanceGeneratorTest method populates the provided instance. -// TEST(GraphInstanceGeneratorTest, GenerateLogisticNetwork) { -// // Create an instance object. -// operations_research::lattle::Instance instance; -// InstanceGenerator generator; - -// // Generate the network with the following parameters: -// generator.generate_logistic_network(instance, -// 20 /* hubs */, -// 0.5 /* density */, -// 10 /* time horizon */, -// 4 /* lines */, -// 5 /* max length line */, -// 5 /* max rotations per line */, -// 100 /* max travelling time */, -// 0.2 /* travelling time perturbation */, -// 1000 /* max vehicle capacity */); -// // Verify that the instance has been populated. -// EXPECT_EQ(instance.network().name(), "network_20"); // Network name should be "network_" -// EXPECT_EQ(instance.network().hubs_size(), 20); // Should have 5 hubs -// EXPECT_EQ(instance.network().lines_size(), 4); // Should have 2 lines +// Test that the GraphInstanceGeneratorTest method populates the provided instance. +TEST(GraphInstanceGeneratorTest, GenerateLogisticNetwork) { + // Create an instance object. + operations_research::lattle::Instance instance; + InstanceGenerator generator; + + // Generate the network with the following parameters: + generator.generate_logistic_network(instance, + 20 /* hubs */, + 0.5 /* density */, + 10 /* time horizon */, + 4 /* lines */, + 5 /* max length line */, + 5 /* max rotations per line */, + 100 /* max travelling time */, + 0.2 /* travelling time perturbation */, + 1000 /* max vehicle capacity */); + // Verify that the instance has been populated. + EXPECT_EQ(instance.network().name(), "network_20"); // Network name should be "network_" + EXPECT_EQ(instance.network().hubs_size(), 20); // Should have 5 hubs + EXPECT_EQ(instance.network().lines_size(), 4); // Should have 2 lines +} + + +// TEST(GraphInstanceGeneratorTest, GenerateLineRotations_SingleLineSingleRotation) { +// // Create a simple graph with 3 hubs +// Graph graph(3); +// graph.add_neighbour("h1", "h2", ""); +// graph.add_neighbour("h2", "h3", ""); + +// // Generate lines with the simple graph +// int num_lines = 1; +// int max_length = 3; +// int max_rotations = 1; +// int time_horizon = 10; +// InstanceGenerator generator; +// operations_research::lattle::LogisticsNetwork network; +// int num_vehicles = generator.generate_line_rotations(network, graph, vector(3, 2), vector>({{2}, {2}}), time_horizon, num_lines, max_length, max_rotations, 10, 0.0); + +// // Verify the number of vehicles added (should be 1 for 1 rotation) +// EXPECT_EQ(num_vehicles, 1); + +// // Verify line structure (number of hubs, existence of path) +// EXPECT_EQ(network.lines_size(), 1); +// const operations_research::lattle::Line& line = network.lines(0); +// EXPECT_LE(line.hub_ids_size(), 3); +// // Verify rotation structure (timestamps, cost) +// EXPECT_EQ(line.next_rotations_size(), 1); +// const operations_research::lattle::LineRotation& rotation = line.next_rotations(0); + // } + +TEST(GraphInstanceGeneratorTest, GenerateLineRotations_MultipleLinesRotations) { + + // Create a graph with 5 hubs. + Graph graph(5); + + for(int i = 1 ; i <= 5;i++){ + graph.add_vertex("h_"+to_string(i)); + } + // Add edges. + for(int i = 1 ; i < 5;i++){ + graph.add_neighbour("h_"+to_string(i), + "h_"+to_string(i+1), ""); + } + InstanceGenerator generator; + + // Generate lines with more lines and rotations + int num_lines = 2; + int max_length = 4; + int max_rotations = 2; + int time_horizon = 20; + operations_research::lattle::LogisticsNetwork network; + vector arc_weights = generator.build_arc_weights(graph); + vector> arc_weights_adj_lists = generator. + build_arc_weights_per_adjacency_lists(graph, arc_weights); + + int num_vehicles = generator.generate_line_rotations(network, graph, arc_weights,arc_weights_adj_lists, time_horizon, num_lines, max_length, max_rotations); + + // Verify the number of vehicles (should depend on rotations) + EXPECT_GT(num_vehicles, 0); // Expect at least some vehicles for rotations + + EXPECT_EQ(network.lines_size(), num_lines); + + for (int i = 0; i < network.lines_size(); ++i) { + const operations_research::lattle::Line& line = network.lines(i); + + // Verify the number of hubs in the line (should be within max_length) + EXPECT_LE(line.hub_ids_size(), max_length+1); + EXPECT_GT(line.hub_ids_size(), 1); // Line should have at least 2 hubs (start and end) + + + // Verify the number of rotations for the line (should be at most max_rotations) + EXPECT_LE(line.next_rotations_size(), max_rotations); + + //Loop through each rotation of the line and verify its structure + for (int j = 0; j < line.next_rotations_size(); ++j) { + const operations_research::lattle::LineRotation& rotation = line.next_rotations(j); + + + EXPECT_EQ(rotation.departure_times_size(), line.hub_ids_size()-1); + EXPECT_EQ(rotation.arrival_times_size(), line.hub_ids_size()-1); + + // TODO(aymanelotfi):Verify that departure times are within the time horizon + } + } +} \ No newline at end of file