diff --git a/plugins/round_trip.hpp b/plugins/round_trip.hpp index 891e422eb..92922671b 100644 --- a/plugins/round_trip.hpp +++ b/plugins/round_trip.hpp @@ -115,6 +115,37 @@ template class RoundTripPlugin final : public BasePlugin return 400; } + auto number_of_locations = phantom_node_vector.size(); + const auto maxint = std::numeric_limits::max(); + + //////////////////////////////////// DELETE UNACCESSIBLE LOCATIONS ///////////////////////////////////////// + + if (*std::max_element(result_table->begin(), result_table->end()) == maxint) { + const int half = number_of_locations / 2; + std::vector to_delete; + + for (int i = number_of_locations - 1; i >= 0; --i) { + // if the location is unaccessible by most of the other locations, remember the location + if (std::count(result_table->begin() + i * number_of_locations, result_table->begin() + (i+1) * number_of_locations, maxint) > half) { + to_delete.push_back(i); + } + } + //delete all unaccessible locations + for (int k = 0; k < to_delete.size(); ++k) { + // delete its row + result_table->erase(result_table->begin() + to_delete[k] * number_of_locations, result_table->begin() + (to_delete[k]+1) * number_of_locations); + --number_of_locations; + // delete its column + for (int j = 0; j < number_of_locations; ++j) { + result_table->erase(result_table->begin() + j * number_of_locations + to_delete[k]); + } + } + } + //todo: delete + if (*std::max_element(result_table->begin(), result_table->end()) == maxint) { + SimpleLogger().Write() << "SOMETHING WENT WRONG"; + } + // compute TSP round trip InternalRouteResult min_route; std::vector min_loc_permutation(phantom_node_vector.size(), -1); diff --git a/plugins/round_trip_BF.hpp b/plugins/round_trip_BF.hpp index 611c9d542..60c12c2b5 100644 --- a/plugins/round_trip_BF.hpp +++ b/plugins/round_trip_BF.hpp @@ -115,6 +115,37 @@ template class RoundTripPluginBF final : public BasePlugin return 400; } + auto number_of_locations = phantom_node_vector.size(); + const auto maxint = std::numeric_limits::max(); + + //////////////////////////////////// DELETE UNACCESSIBLE LOCATIONS ///////////////////////////////////////// + + if (*std::max_element(result_table->begin(), result_table->end()) == maxint) { + const int half = number_of_locations / 2; + std::vector to_delete; + + for (int i = number_of_locations - 1; i >= 0; --i) { + // if the location is unaccessible by most of the other locations, remember the location + if (std::count(result_table->begin() + i * number_of_locations, result_table->begin() + (i+1) * number_of_locations, maxint) > half) { + to_delete.push_back(i); + } + } + //delete all unaccessible locations + for (int k = 0; k < to_delete.size(); ++k) { + // delete its row + result_table->erase(result_table->begin() + to_delete[k] * number_of_locations, result_table->begin() + (to_delete[k]+1) * number_of_locations); + --number_of_locations; + // delete its column + for (int j = 0; j < number_of_locations; ++j) { + result_table->erase(result_table->begin() + j * number_of_locations + to_delete[k]); + } + } + } + //todo: delete + if (*std::max_element(result_table->begin(), result_table->end()) == maxint) { + SimpleLogger().Write() << "SOMETHING WENT WRONG"; + } + // compute TSP round trip InternalRouteResult min_route; std::vector min_loc_permutation(phantom_node_vector.size(), -1); diff --git a/plugins/round_trip_FI.hpp b/plugins/round_trip_FI.hpp index f470052fa..96197a48a 100644 --- a/plugins/round_trip_FI.hpp +++ b/plugins/round_trip_FI.hpp @@ -115,6 +115,37 @@ template class RoundTripPluginFI final : public BasePlugin return 400; } + auto number_of_locations = phantom_node_vector.size(); + const auto maxint = std::numeric_limits::max(); + + //////////////////////////////////// DELETE UNACCESSIBLE LOCATIONS ///////////////////////////////////////// + + if (*std::max_element(result_table->begin(), result_table->end()) == maxint) { + const int half = number_of_locations / 2; + std::vector to_delete; + + for (int i = number_of_locations - 1; i >= 0; --i) { + // if the location is unaccessible by most of the other locations, remember the location + if (std::count(result_table->begin() + i * number_of_locations, result_table->begin() + (i+1) * number_of_locations, maxint) > half) { + to_delete.push_back(i); + } + } + //delete all unaccessible locations + for (int k = 0; k < to_delete.size(); ++k) { + // delete its row + result_table->erase(result_table->begin() + to_delete[k] * number_of_locations, result_table->begin() + (to_delete[k]+1) * number_of_locations); + --number_of_locations; + // delete its column + for (int j = 0; j < number_of_locations; ++j) { + result_table->erase(result_table->begin() + j * number_of_locations + to_delete[k]); + } + } + } + //todo: delete + if (*std::max_element(result_table->begin(), result_table->end()) == maxint) { + SimpleLogger().Write() << "SOMETHING WENT WRONG"; + } + // compute TSP round trip InternalRouteResult min_route; std::vector min_loc_permutation(phantom_node_vector.size(), -1); diff --git a/plugins/round_trip_NN.hpp b/plugins/round_trip_NN.hpp index 4d6d674af..bc6c4cdc6 100644 --- a/plugins/round_trip_NN.hpp +++ b/plugins/round_trip_NN.hpp @@ -43,6 +43,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../util/string_util.hpp" #include "../util/timing_util.hpp" #include "../util/simple_logger.hpp" +#include "../tools/tsp_logs.hpp" #include @@ -115,9 +116,40 @@ template class RoundTripPluginNN final : public BasePlugin return 400; } + auto number_of_locations = phantom_node_vector.size(); + const auto maxint = std::numeric_limits::max(); + + //////////////////////////////////// DELETE UNACCESSIBLE LOCATIONS ///////////////////////////////////////// + + if (*std::max_element(result_table->begin(), result_table->end()) == maxint) { + const int half = number_of_locations / 2; + std::vector to_delete; + + for (int i = number_of_locations - 1; i >= 0; --i) { + // if the location is unaccessible by most of the other locations, remember the location + if (std::count(result_table->begin() + i * number_of_locations, result_table->begin() + (i+1) * number_of_locations, maxint) > half) { + to_delete.push_back(i); + } + } + //delete all unaccessible locations + for (int k = 0; k < to_delete.size(); ++k) { + // delete its row + result_table->erase(result_table->begin() + to_delete[k] * number_of_locations, result_table->begin() + (to_delete[k]+1) * number_of_locations); + --number_of_locations; + // delete its column + for (int j = 0; j < number_of_locations; ++j) { + result_table->erase(result_table->begin() + j * number_of_locations + to_delete[k]); + } + } + } + //todo: delete + if (*std::max_element(result_table->begin(), result_table->end()) == maxint) { + SimpleLogger().Write() << "SOMETHING WENT WRONG"; + } + // compute TSP round trip InternalRouteResult min_route; - std::vector min_loc_permutation(phantom_node_vector.size(), -1); + std::vector min_loc_permutation(number_of_locations, -1); TIMER_STOP(tsp_pre); //######################### NEAREST NEIGHBOUR ###############################// diff --git a/routing_algorithms/tsp_nearest_neighbour.hpp b/routing_algorithms/tsp_nearest_neighbour.hpp index 113e8d36f..bf9492293 100644 --- a/routing_algorithms/tsp_nearest_neighbour.hpp +++ b/routing_algorithms/tsp_nearest_neighbour.hpp @@ -66,38 +66,10 @@ void NearestNeighbourTSP(const PhantomNodeArray & phantom_node_vector, const auto number_of_locations = phantom_node_vector.size(); min_route.shortest_path_length = std::numeric_limits::max(); - // is_lonely_island[i] indicates whether node i is a node that cannot be reached from other nodes - // 1 means that node i is a lonely island - // 0 means that it is not known for node i - // -1 means that node i is not a lonely island but a reachable, connected node - std::vector is_lonely_island(number_of_locations, 0); - int count_unreachables; - // ALWAYS START AT ANOTHER STARTING POINT for(int start_node = 0; start_node < number_of_locations; ++start_node) { - - if (is_lonely_island[start_node] >= 0) - { - // if node is a lonely island it is an unsuitable node to start from and shall be skipped - if (is_lonely_island[start_node]) - continue; - count_unreachables = 0; - auto start_dist_begin = dist_table.begin() + (start_node * number_of_locations); - auto start_dist_end = dist_table.begin() + ((start_node + 1) * number_of_locations); - for (auto it2 = start_dist_begin; it2 != start_dist_end; ++it2) { - if (*it2 == 0 || *it2 == std::numeric_limits::max()) { - ++count_unreachables; - } - } - if (count_unreachables >= number_of_locations) { - is_lonely_island[start_node] = 1; - continue; - } - } - int curr_node = start_node; - is_lonely_island[curr_node] = -1; InternalRouteResult raw_route; //TODO: Should we always use the same vector or does it not matter at all because of loop scope? std::vector loc_permutation(number_of_locations, -1); @@ -119,33 +91,18 @@ void NearestNeighbourTSP(const PhantomNodeArray & phantom_node_vector, auto row_end_iterator = dist_table.begin() + ((curr_node + 1) * number_of_locations); for (auto it = row_begin_iterator; it != row_end_iterator; ++it) { auto index = std::distance(row_begin_iterator, it); - if (is_lonely_island[index] < 1 && !visited[index] && *it < min_dist) + if (!visited[index] && *it < min_dist) { min_dist = *it; min_id = index; } } - // in case there was no unvisited and reachable node found, it means that all remaining (unvisited) nodes must be lonely islands - if (min_id == -1) - { - for(int loc = 0; loc < visited.size(); ++loc) { - if (!visited[loc]) { - is_lonely_island[loc] = 1; - } - } - break; - } - // set the nearest unvisited location as the next via_point - else - { - is_lonely_island[min_id] = -1; - loc_permutation[min_id] = via_point; - visited[min_id] = true; - viapoint = PhantomNodes{phantom_node_vector[curr_node][0], phantom_node_vector[min_id][0]}; - raw_route.segment_end_coordinates.emplace_back(viapoint); - trip_dist += min_dist; - curr_node = min_id; - } + loc_permutation[min_id] = via_point; + visited[min_id] = true; + viapoint = PhantomNodes{phantom_node_vector[curr_node][0], phantom_node_vector[min_id][0]}; + raw_route.segment_end_coordinates.emplace_back(viapoint); + trip_dist += min_dist; + curr_node = min_id; } // 4. ROUTE BACK TO STARTING POINT