├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── config └── default_config.yaml ├── external ├── gurobi_setup.sh ├── json │ ├── LICENSE │ └── include │ │ └── json │ │ ├── json.hpp │ │ ├── json.hpp.1 │ │ └── json.hpp.2 ├── lkh_glkh_setup.sh └── mcpm │ ├── LICENSE │ └── include │ └── mcpm │ ├── binary_heap.h │ ├── globals.h │ ├── graph.h │ └── matching.h ├── include └── lclibrary │ ├── algorithms │ ├── algorithms.h │ ├── apsp_base.h │ ├── apsp_floyd_warshall.h │ ├── apsp_turns.h │ ├── atsp_base.h │ ├── atsp_held_karp.h │ ├── atsp_lkh.h │ ├── connected_components.h │ ├── euler_tour.h │ ├── gtsp_glkh.h │ ├── is_balanced.h │ ├── matching.h │ ├── mst_prim.h │ └── required_graph.h │ ├── core │ ├── config.h │ ├── constants.h │ ├── core.h │ ├── edge.h │ ├── edge_cost_base.h │ ├── graph.h │ ├── graph_io.h │ ├── graph_utilities.h │ ├── graph_wrapper.h │ ├── math_utils.h │ ├── mem_base.h │ ├── route.h │ ├── route_turns.h │ ├── transform_lla_xy.h │ ├── typedefs.h │ ├── vec2d.h │ └── vertex.h │ ├── mlc │ ├── ilp_base.h │ ├── ilp_gurobi.h │ ├── mlc.h │ ├── mlc_base.h │ ├── mlc_mem.h │ ├── mlc_mem_path.h │ └── tour_splitting_md.h │ ├── slc │ ├── cpp.h │ ├── ilp_base.h │ ├── ilp_glpk.h │ ├── ilp_gurobi.h │ ├── lp_beta3_glpk.h │ ├── lp_beta3_gurobi.h │ ├── lp_glpk.h │ ├── lp_gurobi.h │ ├── mem.h │ ├── rpp_3by2.h │ ├── slc.h │ ├── slc_base.h │ ├── slc_beta2_atsp.h │ ├── slc_beta2_gtsp.h │ ├── slc_beta3_atsp.h │ └── slc_lp.h │ └── utils │ ├── convert_osm_json_graph.h │ ├── create_temp_dir.h │ ├── edge_cost_travel_time.h │ ├── edge_cost_with_circular_turns.h │ ├── edge_cost_with_turns.h │ ├── plot_graph.h │ ├── utils.h │ ├── video_generator.h │ └── write_geojson.h ├── lclibrary-config.cmake.in ├── lclibrary_config.h.in ├── main ├── CMakeLists.txt ├── mlc.cc └── slc.cc ├── python ├── CMakeLists.txt ├── rpp_3by2.py └── src │ └── slc.cc ├── src ├── core │ ├── adjacency_list_generation.cc │ ├── graph.cc │ ├── graph_file_parser.cc │ ├── graph_io.cc │ └── graph_utilities.cc ├── slc │ ├── ilp_glpk.cc │ ├── lp_beta3_glpk.cc │ └── lp_glpk.cc └── utils │ ├── plot_graph.cc │ └── video_generator.cc └── utils ├── leaflet_geojson_viz ├── graph.json ├── index.html ├── main.js ├── route.json └── styles.css └── leaflet_osm_viz ├── index.html ├── main.js └── styles.css /.gitignore: -------------------------------------------------------------------------------- 1 | bin/* 2 | obj/* 3 | lib/* 4 | external_libraries/* 5 | LineCoverage-dataset/* 6 | LineCoverage-dataset/ 7 | vim.session 8 | 9 | *.log 10 | 11 | # Compiled Object files 12 | *.slo 13 | *.lo 14 | *.o 15 | *.obj 16 | 17 | # Precompiled Headers 18 | *.gch 19 | *.pch 20 | 21 | # Compiled Dynamic libraries 22 | *.so 23 | *.dylib 24 | *.dll 25 | 26 | # Fortran module files 27 | *.mod 28 | *.smod 29 | 30 | # Compiled Static libraries 31 | *.lai 32 | *.la 33 | *.a 34 | *.lib 35 | 36 | # Executables 37 | *.exe 38 | *.out 39 | *.app 40 | -------------------------------------------------------------------------------- /config/default_config.yaml: -------------------------------------------------------------------------------- 1 | # Default configuration for the LineCoverage-library in YAML format 2 | 3 | database: 4 | path: 'LineCoverage-dataset/most_pop_50cities' 5 | data_dir: 'paris' 6 | 7 | # 'slc' for single robot 8 | # 'mlc' for multiple robots 9 | problem: 'mlc' 10 | 11 | # 'beta2_atsp' (preferred) 12 | # 'beta2_gtsp' 13 | # 'beta3_atsp' 14 | # 'ilp_gurobi' (use only if gurobi is installed and configured) 15 | # 'ilp_glpk' (use for very small graphs) 16 | solver_slc: 'beta2_atsp' 17 | 18 | # 'mem' 19 | # 'ilp_gurobi' (use only if gurobi is installed and configured) 20 | solver_mlc: 'mem' 21 | 22 | # 'euclidean' for euclidean distance 23 | # 'travel time' for asymmetric travel time based on speed (see travel_time_config) 24 | # 'ramp' for ramp based velocity profile 25 | cost_function: 'travel_time' 26 | travel_time_config: 27 | service_speed: 5.0 28 | deadhead_speed: 8.0 29 | wind_speed: 0.0 30 | wind_dir: 45 31 | 32 | ramp_config: 33 | speed: 1.0 34 | acceleration: 1.0 35 | 36 | # Add non-required edges between each pair of vertices 37 | add_pairwise_nonreq_edges: true 38 | 39 | # Convert osm json file to internal text based format 40 | convert_osm_json: true 41 | 42 | # Set the capacity for mlc problem 43 | capacity: 1800 44 | 45 | # 2opt heuristic to improve routes. It can take a long time for large graphs 46 | use_2opt: false 47 | 48 | # Set the time limit for ILP solvers 49 | ilp_time_limit: 3600 # (in seconds. Used only with Gurobi) 50 | 51 | # depot: mean (use the node closest to the mean) 52 | # custom (provide a specific node ID for the depot) 53 | # none (no depot, cannot be none for mlc) 54 | depot: 55 | mode: mean 56 | ID: 1 57 | 58 | # These are relevant if a custom graph is provided 59 | input_graph: 60 | lla: true 61 | costs: false 62 | 63 | plot_input_graph: 64 | name: 'graph' 65 | plot: true 66 | plot_nreq_edges: false 67 | 68 | writeGeoJSON: 69 | write: false 70 | filename: 'graph.json' 71 | var_name: 'graph_data' 72 | non_req_edges: false 73 | 74 | route_output: 75 | plot: true 76 | kml: false 77 | data: false 78 | geojson: false 79 | edge_data: false 80 | agg_results: true 81 | append: false 82 | clear_dir: false 83 | 84 | filenames: 85 | map_json: 'map_data.json' 86 | nodes_ll: 'node_list_lat_long' 87 | nodes_data: 'node_data' 88 | req_edges: 'req_edge_list' 89 | nonreq_edges: 'non_req_edge_list' 90 | -------------------------------------------------------------------------------- /external/gurobi_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Gurobi installation script 4 | 5 | INSTALL_DIR=${HOME}/opt/ 6 | MAJOR_VERSION=10.0 7 | MINOR_VERSION=1 8 | mkdir -p ${INSTALL_DIR} 9 | cd ${INSTALL_DIR} 10 | GUROBI_FILENAME=gurobi${MAJOR_VERSION}.${MINOR_VERSION}_linux64.tar.gz 11 | wget https://packages.gurobi.com/${MAJOR_VERSION}/${GUROBI_FILENAME} 12 | tar -xf ${GUROBI_FILENAME} 13 | rm ${GUROBI_FILENAME} 14 | GUROBI_LIB=gurobi"${MAJOR_VERSION//.}" 15 | GUROBI_DIR=gurobi"${MAJOR_VERSION//.}"${MINOR_VERSION} 16 | echo ${GUROBI_DIR} 17 | cd ${GUROBI_DIR}/linux64/src/build 18 | sed -i ' 1 s/.*/& -std=c++17/' Makefile 19 | make -j 20 | cp libgurobi_c++.a ../../lib/. 21 | 22 | echo "export GUROBI_HOME=${INSTALL_DIR}/${GUROBI_DIR}/linux64" >> ${HOME}/.bashrc 23 | echo 'export PATH="${PATH}:${GUROBI_HOME}/bin"' >> ${HOME}/.bashrc 24 | echo 'export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${GUROBI_HOME}/lib"' >> ${HOME}/.bashrc 25 | echo "export GUROBI_LIB=${GUROBI_LIB}" >> ${HOME}/.bashrc 26 | 27 | source ${HOME}/.bashrc 28 | 29 | echo "Gurobi installation is complete. Please activate your license. Visit www.gurobi.com" 30 | -------------------------------------------------------------------------------- /external/json/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-2022 Niels Lohmann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /external/lkh_glkh_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | print_usage() { 4 | printf "bash $0 [-alkh] [-aglkh]\n" 5 | } 6 | 7 | USE_LKH=false 8 | USE_GLKH=false 9 | while getopts 'd:a:' flag; do 10 | case "${flag}" in 11 | d) LC_DATABASE_DIR="${OPTARG%/}" ;; 12 | a) if [[ ${OPTARG} == "lkh" ]] 13 | then 14 | USE_LKH=true 15 | fi 16 | if [[ ${OPTARG} == "glkh" ]] 17 | then 18 | USE_GLKH=true 19 | USE_LKH=true 20 | fi 21 | ;; 22 | *) print_usage 23 | exit 1 ;; 24 | esac 25 | done 26 | BASE_DIR=`pwd` 27 | source ~/.bashrc 28 | 29 | LC_EXT_DIR=${BASE_DIR}/ 30 | LOG_FILE=${LC_EXT_DIR}/lkh_glkh_setup.log 31 | 32 | cd ${LC_EXT_DIR} 33 | 34 | if [[ ${USE_LKH} == true ]] 35 | then 36 | echo "====================" 37 | echo "" 38 | echo "Obtaining LKH" 39 | echo "" 40 | echo "====================" 41 | echo "" 42 | wget -O lkh.tgz http://akira.ruc.dk/~keld/research/LKH-3/LKH-3.0.8.tgz 43 | tar -xzf lkh.tgz -C ${LC_EXT_DIR} 44 | rm lkh.tgz 45 | cd ${LC_EXT_DIR} 46 | mv LKH-3.0.8 lkh 47 | fi 48 | 49 | if [[ ${USE_GLKH} == true ]] 50 | then 51 | echo "====================" 52 | echo "" 53 | echo "Obtaining GLKH" 54 | echo "" 55 | echo "====================" 56 | echo "" 57 | 58 | wget http://akira.ruc.dk/~keld/research/GLKH/GLKH-1.1.tgz 59 | mkdir -p ${LC_EXT_DIR} 60 | tar -xzf GLKH-1.1.tgz -C ${LC_EXT_DIR} 61 | rm GLKH-1.1.tgz 62 | mv GLKH-1.1 glkh 63 | sed -i ' 4 s/.*/& -fcommon/' glkh/SRC/Makefile 64 | rm glkh/SRC/GLKH_EXPmain.c 65 | rm glkh/SRC/GLKH_CHECKmain.c 66 | 67 | cd ${LC_EXT_DIR}/glkh/ 68 | GLKH_SCRIPT=glkh.sh 69 | 70 | # SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" 71 | echo '#!/bin/bash' > $GLKH_SCRIPT 72 | # echo "cd "$(dirname ${BASH_SOURCE[0]})"" >> $GLKH_SCRIPT 73 | echo 'cd ${1}' >> $GLKH_SCRIPT 74 | echo './GLKH TMP/gtsp.par' >> $GLKH_SCRIPT 75 | # echo "rm -r TMP/*" >> $GLKH_SCRIPT 76 | fi 77 | -------------------------------------------------------------------------------- /external/mcpm/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 dilsonpereira 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /external/mcpm/include/mcpm/binary_heap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /*! 7 | * This is a binary heap for pairs of the type (double key, int satellite) 8 | * It is assumed that satellites are unique integers 9 | * This is the case with graph algorithms, in which satellites are vertex or edge indices 10 | */ 11 | 12 | namespace mcpm { 13 | class BinaryHeap { 14 | 15 | public: 16 | 17 | BinaryHeap(): satellite(1), size(0) {}; 18 | 19 | //Inserts (key k, satellite s) in the heap 20 | void Insert(double k, int s) { 21 | //Ajust the structures to fit new data 22 | if(s >= (int)pos.size()) { 23 | pos.resize(s+1, -1); 24 | key.resize(s+1); 25 | //Recall that position 0 of satellite is unused 26 | satellite.resize(s+2); 27 | } 28 | //If satellite is already in the heap 29 | else if(pos[s] != -1) { 30 | throw "Error: satellite already in heap"; 31 | } 32 | 33 | int i; 34 | for(i = ++size; i/2 > 0 && GREATER(key[satellite[i/2]], k); i /= 2) { 35 | satellite[i] = satellite[i/2]; 36 | pos[satellite[i]] = i; 37 | } 38 | satellite[i] = s; 39 | pos[s] = i; 40 | key[s] = k; 41 | } 42 | 43 | //Deletes the element with minimum key and returns its satellite information 44 | int DeleteMin() { 45 | if(size == 0) 46 | throw "Error: empty heap"; 47 | 48 | int min = satellite[1]; 49 | int slast = satellite[size--]; 50 | 51 | 52 | int child; 53 | int i; 54 | for(i = 1, child = 2; child <= size; i = child, child *= 2) { 55 | if(child < size && GREATER(key[satellite[child]], key[satellite[child+1]])) 56 | child++; 57 | 58 | if(GREATER(key[slast], key[satellite[child]])) { 59 | satellite[i] = satellite[child]; 60 | pos[satellite[child]] = i; 61 | } 62 | else 63 | break; 64 | } 65 | satellite[i] = slast; 66 | pos[slast] = i; 67 | 68 | pos[min] = -1; 69 | 70 | return min; 71 | } 72 | 73 | //Changes the key of the element with satellite s 74 | void ChangeKey(double k, int s) { 75 | Remove(s); 76 | Insert(k, s); 77 | } 78 | 79 | //Removes the element with satellite s 80 | void Remove(int s) { 81 | int i; 82 | for(i = pos[s]; i/2 > 0; i /= 2) { 83 | satellite[i] = satellite[i/2]; 84 | pos[satellite[i]] = i; 85 | } 86 | satellite[1] = s; 87 | pos[s] = 1; 88 | 89 | DeleteMin(); 90 | } 91 | 92 | //Returns the number of elements in the heap 93 | int Size() { 94 | return size; 95 | } 96 | 97 | //Resets the structure 98 | void Clear() { 99 | key.clear(); 100 | pos.clear(); 101 | satellite.clear(); 102 | } 103 | 104 | private: 105 | std::vector key;//Given the satellite, this is its key 106 | std::vector pos;//Given the satellite, this is its position in the heap 107 | std::vector satellite;//This is the heap! 108 | 109 | //Number of elements in the heap 110 | int size; 111 | }; 112 | 113 | } //namespace mcpm 114 | -------------------------------------------------------------------------------- /external/mcpm/include/mcpm/globals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace mcpm { 5 | constexpr double EPSILON = 0.000001; 6 | constexpr double INFINITO = 1000000000.0; 7 | 8 | template 9 | inline bool GREATER(T a, U b) { return (a - b) > EPSILON; } 10 | 11 | template 12 | inline bool LESS(T a, T b) { return (b - a) > EPSILON; } 13 | 14 | template 15 | inline bool EQUAL(T a, T b) { return std::abs(b - a) < EPSILON; } 16 | 17 | template 18 | inline bool GREATER_EQUAL(T a, T b) { return GREATER(a, b) || EQUAL(a, b); } 19 | 20 | template 21 | inline bool LESS_EQUAL(T a, T b) { return LESS(a, b) || EQUAL(a, b); } 22 | 23 | template 24 | inline T MIN(T a, T b) { return std::min(a, b); } 25 | 26 | template 27 | inline T MAX(T a, T b) { return std::max(a, b); } 28 | } 29 | -------------------------------------------------------------------------------- /external/mcpm/include/mcpm/graph.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace mcpm { 8 | class Graph { 9 | public: 10 | 11 | //n is the number of vertices 12 | //edges is a list of pairs representing the edges (default = empty list) 13 | Graph(int n, const std::list< std::pair > & edges = std::list< std::pair >()) : 14 | n(n), 15 | m(0), 16 | adjMat(n, std::vector(n, false)), 17 | adjList(n), 18 | edges(), 19 | edgeIndex(n, std::vector(n, -1)) { 20 | for(std::list< std::pair >::const_iterator it = edges.begin(); it != edges.end(); it++) { 21 | int u = (*it).first; 22 | int v = (*it).second; 23 | AddEdge(u, v); 24 | } 25 | } 26 | 27 | 28 | //Default constructor creates an empty graph 29 | Graph(): n(0), m(0) {}; 30 | 31 | //Returns the number of vertices 32 | int GetNumVertices() const { return n; }; 33 | //Returns the number of edges 34 | int GetNumEdges() const { return m; }; 35 | 36 | //Given the edge's index, returns its endpoints as a pair 37 | std::pair GetEdge(int e) const { 38 | if(e > (int)edges.size()) 39 | throw "Error: edge does not exist"; 40 | return edges[e]; 41 | } 42 | 43 | //Given the endpoints, returns the index 44 | int GetEdgeIndex(int u, int v) const { 45 | if( u > n or 46 | v > n ) 47 | throw "Error: vertex does not exist"; 48 | 49 | if(edgeIndex[u][v] == -1) 50 | throw "Error: edge does not exist"; 51 | 52 | return edgeIndex[u][v]; 53 | } 54 | 55 | //Adds a new vertex to the graph 56 | void AddVertex() { 57 | for(int i = 0; i < n; i++) { 58 | adjMat[i].push_back(false); 59 | edgeIndex[i].push_back(-1); 60 | } 61 | n++; 62 | adjMat.push_back( std::vector(n, false) ); 63 | edgeIndex.push_back( std::vector(n, -1) ); 64 | adjList.push_back( std::list() ); 65 | } 66 | 67 | //Adds a new edge to the graph 68 | void AddEdge(int u, int v) { 69 | if( u > n or 70 | v > n ) 71 | throw "Error: vertex does not exist"; 72 | 73 | if(adjMat[u][v]) return; 74 | 75 | adjMat[u][v] = adjMat[v][u] = true; 76 | adjList[u].push_back(v); 77 | adjList[v].push_back(u); 78 | 79 | edges.push_back(std::pair(u, v)); 80 | edgeIndex[u][v] = edgeIndex[v][u] = m++; 81 | } 82 | 83 | //Returns the adjacency list of a vertex 84 | const std::list & AdjList(int v) const { 85 | if(v > n) 86 | throw "Error: vertex does not exist"; 87 | 88 | return adjList[v]; 89 | } 90 | 91 | //Returns the graph's adjacency matrix 92 | const std::vector< std::vector > & AdjMat() const { 93 | return adjMat; 94 | } 95 | 96 | void PrintGraph() { 97 | std::cout << "Number of vertices: " << n << std::endl; 98 | std::cout << "Number of edges: " << m << std::endl; 99 | for(int i = 0; i < m; ++i) { 100 | auto e = edges[i]; 101 | std::cout << e.first << " " << e.second << std::endl; 102 | } 103 | } 104 | 105 | private: 106 | //Number of vertices 107 | int n; 108 | //Number of edges 109 | int m; 110 | 111 | //Adjacency matrix 112 | std::vector< std::vector > adjMat; 113 | 114 | //Adjacency lists 115 | std::vector< std::list > adjList; 116 | 117 | //Array of edges 118 | std::vector< std::pair > edges; 119 | 120 | //Indices of the edges 121 | std::vector< std::vector > edgeIndex; 122 | 123 | }; 124 | } /* namespace mcpm */ 125 | -------------------------------------------------------------------------------- /include/lclibrary/algorithms/algorithms.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * Top level header for algorithms 4 | * 5 | * @author Saurav Agarwal 6 | * @contact sagarw10@uncc.edu 7 | * @contact agr.saurav1@gmail.com 8 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 9 | * 10 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 11 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 12 | * 13 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 14 | * 15 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 16 | * 17 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 18 | * 19 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 20 | */ 21 | 22 | #ifndef LCLIBRARY_ALGORITHMS_H_ 23 | #define LCLIBRARY_ALGORITHMS_H_ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #endif /* LCLIBRARY_ALGORITHMS_H_ */ 36 | -------------------------------------------------------------------------------- /include/lclibrary/algorithms/apsp_base.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains APSP base class 4 | * 5 | * TODO: Add APSP_Turns as another base class? Perhaps use traits? 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_ALGORITHMS_APSP_H_ 25 | #define LCLIBRARY_ALGORITHMS_APSP_H_ 26 | 27 | #include 28 | namespace lclibrary { 29 | 30 | class APSP { 31 | public: 32 | virtual void GetPath(std::vector < Edge > &, const size_t, const size_t) const = 0; 33 | virtual double GetCost(const size_t, const size_t) const = 0; 34 | virtual ~APSP() {}; 35 | }; 36 | 37 | } 38 | 39 | #endif /* LCLIBRARY_CORE_APSP_HPP_ */ 40 | -------------------------------------------------------------------------------- /include/lclibrary/algorithms/apsp_floyd_warshall.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains functions to generate all pair shortest paths 4 | * 5 | * TODO: Use GraphEdge instead of creating new edges? 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_ALGORITHMS_APSP_FLOYDWARSHALL_H_ 25 | #define LCLIBRARY_ALGORITHMS_APSP_FLOYDWARSHALL_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | namespace lclibrary { 35 | 36 | class APSP_FloydWarshall : public APSP { 37 | std::shared_ptr g_; 38 | size_t n_; 39 | size_t m_; 40 | size_t m_nr_; 41 | std::vector > distance_; 42 | std::vector > demand_; 43 | std::vector > helper_; 44 | std::vector > helper_edge_; 45 | bool compute_demand_ = false; 46 | 47 | void Initialize() { 48 | distance_.resize(n_, std::vector (n_, kDoubleMax)); 49 | helper_.resize(n_, std::vector (n_, kNIL)); 50 | helper_edge_.resize(n_, std::vector (n_, MakeEdgeTuple(nullptr, kIsRequired))); 51 | if(compute_demand_) { 52 | demand_.resize(n_, std::vector (n_, kDoubleMax)); 53 | } 54 | } 55 | 56 | void GetPath(std::vector < EdgeTuple > &path, size_t i, size_t j) const { 57 | if(helper_[i][j] == kNIL) 58 | path.push_back(helper_edge_[i][j]); 59 | else { 60 | GetPath(path, i, helper_[i][j]); 61 | GetPath(path, helper_[i][j], j); 62 | } 63 | } 64 | 65 | public: 66 | APSP_FloydWarshall(std::shared_ptr &g) : g_{g} { 67 | n_ = g_->GetN(); 68 | m_ = g_->GetM(); 69 | m_nr_ = g_->GetMnr(); 70 | Initialize(); 71 | } 72 | 73 | APSP_FloydWarshall(std::shared_ptr &g, bool compute_demand) : g_{g}, compute_demand_{compute_demand} { 74 | n_ = g_->GetN(); 75 | m_ = g_->GetM(); 76 | m_nr_ = g_->GetMnr(); 77 | Initialize(); 78 | } 79 | 80 | void APSP_Deadheading() { 81 | double cost = kDoubleMax; 82 | for(size_t i = 0; i < n_; ++i) { 83 | distance_[i][i] = 0; 84 | } 85 | if(compute_demand_) { 86 | for(size_t i = 0; i < n_; ++i) { 87 | demand_[i][i] = 0; 88 | } 89 | } 90 | for(size_t i = 0; i < m_; ++i) { 91 | size_t t, h; 92 | g_->GetVerticesIndexOfEdge(i, t, h, kIsRequired); 93 | cost = g_->GetDeadheadCost(i, kIsRequired); 94 | if (cost < distance_[t][h]) { 95 | distance_[t][h] = cost; 96 | helper_edge_[t][h] = MakeEdgeTuple(g_->GetEdge(i, kIsRequired), false); 97 | if(compute_demand_) { 98 | demand_[t][h] = g_->GetDeadheadDemand(i, kIsRequired); 99 | } 100 | } 101 | cost = g_->GetReverseDeadheadCost(i, kIsRequired); 102 | if (cost < distance_[h][t]) { 103 | distance_[h][t] = cost; 104 | helper_edge_[h][t] = MakeEdgeTuple(g_->GetEdge(i, kIsRequired), true); 105 | if(compute_demand_) { 106 | demand_[h][t] = g_->GetReverseDeadheadDemand(i, kIsRequired); 107 | } 108 | } 109 | } 110 | for(size_t i = 0; i < m_nr_; ++i) { 111 | size_t t, h; 112 | g_->GetVerticesIndexOfEdge(i, t, h, kIsNotRequired); 113 | cost = g_->GetDeadheadCost(i, kIsNotRequired); 114 | if (cost < distance_[t][h]) { 115 | distance_[t][h] = cost; 116 | helper_edge_[t][h] = MakeEdgeTuple(g_->GetEdge(i, kIsNotRequired), false); 117 | if(compute_demand_) { 118 | demand_[t][h] = g_->GetDeadheadDemand(i, kIsNotRequired); 119 | } 120 | } 121 | cost = g_->GetReverseDeadheadCost(i, kIsNotRequired); 122 | if (cost < distance_[h][t]) { 123 | distance_[h][t] = cost; 124 | helper_edge_[h][t] = MakeEdgeTuple(g_->GetEdge(i, kIsNotRequired), true); 125 | if(compute_demand_) { 126 | demand_[h][t] = g_->GetReverseDeadheadDemand(i, kIsNotRequired); 127 | } 128 | } 129 | } 130 | 131 | for(size_t k = 0; k < n_; ++k) { 132 | for(size_t i = 0; i < n_; ++i) { 133 | for(size_t j = 0; j < n_; ++j) { 134 | if(distance_[i][k] + distance_[k][j] < distance_[i][j]) { 135 | distance_[i][j] = distance_[i][k] + distance_[k][j]; 136 | helper_[i][j] = k; 137 | if(compute_demand_) { 138 | demand_[i][j] = demand_[i][k] + demand_[k][j]; 139 | } 140 | } 141 | } 142 | } 143 | } 144 | } 145 | 146 | void GetPath(std::vector < Edge > &edge_list, const size_t i, const size_t j) const { 147 | std::vector path; 148 | GetPath(path, i, j); 149 | for(auto &[e, is_rev] : path) { 150 | if(e == nullptr) 151 | continue; 152 | Edge new_edge = *e; 153 | new_edge.SetReq(kIsNotRequired); 154 | if(is_rev) { 155 | new_edge.SetCost(e->GetReverseDeadheadCost()); 156 | new_edge.Reverse(); 157 | } 158 | else { 159 | new_edge.SetCost(e->GetDeadheadCost()); 160 | } 161 | edge_list.push_back(new_edge); 162 | } 163 | } 164 | 165 | double GetCost(const size_t i, const size_t j) const { 166 | return distance_[i][j]; 167 | } 168 | 169 | double GetDemand(const size_t i, const size_t j) const { 170 | return demand_[i][j]; 171 | } 172 | 173 | }; 174 | 175 | } // namespace lclibrary 176 | 177 | #endif /* LCLIBRARY_ALGORITHMS_APSP_FLOYDWARSHALL_H_ */ 178 | -------------------------------------------------------------------------------- /include/lclibrary/algorithms/atsp_base.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains ATSP abstract base class 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_ALGORITHMS_ATSP_H_ 25 | #define LCLIBRARY_ALGORITHMS_ATSP_H_ 26 | 27 | namespace lclibrary { 28 | 29 | class ATSP { 30 | public: 31 | virtual int GetPath(std::vector < size_t > &) const = 0; 32 | virtual ~ATSP() {} 33 | }; 34 | 35 | } 36 | 37 | #endif /* LCLIBRARY_CORE_APSP_H_ */ 38 | -------------------------------------------------------------------------------- /include/lclibrary/algorithms/atsp_held_karp.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains DP algorithm for ATSP given by Bellman-Held-Karp 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_ALGORITHMS_ATSP_DP_BHK_H_ 25 | #define LCLIBRARY_ALGORITHMS_ATSP_DP_BHK_H_ 26 | 27 | #include 28 | #include 29 | 30 | namespace lclibrary { 31 | 32 | class ATSP_DP_BHK: public ATSP { 33 | struct Path { 34 | size_t v; 35 | size_t s; 36 | double c; 37 | Path() : v{kNIL}, s{kNIL}, c{kDoubleMax} {} 38 | }; 39 | size_t n_; 40 | const std::vector < std::vector > &d_; 41 | std::vector < std::vector > subpath_; 42 | size_t max_subsets_; 43 | double cost_; 44 | 45 | void SolveATSP(size_t v, size_t s) { 46 | size_t min_v = kNIL; 47 | size_t s_min = kNIL; 48 | 49 | for(size_t i = 0; i < n_; ++i) { 50 | 51 | if(i == v || (s & (1 << i))) { 52 | continue; 53 | } 54 | 55 | size_t s_new = (s | (1 << i)); 56 | 57 | double path_cost = d_[v][i]; 58 | if(s_new == max_subsets_) { 59 | path_cost += d_[i][0]; 60 | } 61 | else if(subpath_[i][s_new].v == kNIL) { 62 | SolveATSP(i, s_new); 63 | path_cost += subpath_[i][s_new].c; 64 | } 65 | else { 66 | path_cost += subpath_[i][s_new].c; 67 | } 68 | 69 | if(path_cost < subpath_[v][s].c) { 70 | subpath_[v][s].c = path_cost; 71 | min_v = i; 72 | s_min = s_new; 73 | } 74 | } 75 | subpath_[v][s].v = min_v; 76 | subpath_[v][s].s = s_min; 77 | } 78 | 79 | public: 80 | ATSP_DP_BHK(const size_t n, const std::vector < std::vector > &d) : n_{n}, d_{d} { 81 | max_subsets_ = (1 << n) - 1; 82 | subpath_.resize(n, std::vector (max_subsets_)); 83 | SolveATSP(0, 1); 84 | cost_ = subpath_[0][1].c; 85 | } 86 | 87 | 88 | int GetPath(std::vector < size_t > &path) const { 89 | path.push_back(0); 90 | double cost = 0; 91 | size_t v = 0; size_t s = 1; 92 | for(size_t i = 0; i < n_ - 1; ++i) { 93 | auto p = subpath_[v][s]; 94 | cost += d_[v][p.v]; 95 | v = p.v; 96 | s = p.s; 97 | path.push_back(v); 98 | } 99 | path.push_back(0); 100 | cost += d_[v][0]; 101 | if(path.size() != (n_ + 1)) 102 | return 1; 103 | if(!IsNearZero(cost - cost_)) 104 | return 1; 105 | return 0; 106 | } 107 | 108 | }; 109 | 110 | } // namespace lclibrary 111 | 112 | #endif /* LCLIBRARY_ALGORITHMS_ATSP_DP_BHK_H_ */ 113 | -------------------------------------------------------------------------------- /include/lclibrary/algorithms/atsp_lkh.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains interfacing class for solving ATSP using LKH 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_ALGORITHMS_ATSP_LKH_H_ 25 | #define LCLIBRARY_ALGORITHMS_ATSP_LKH_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | namespace lclibrary { 32 | 33 | class ATSP_LKH: public ATSP { 34 | size_t n_; 35 | const std::vector < std::vector > &d_; 36 | double cost_; 37 | std::vector path_; 38 | std::string parameter_file_name_; 39 | std::string problem_file_name_; 40 | std::string out_file_name_; 41 | 42 | void WriteParameterFile() const { 43 | std::ofstream parameter_file(parameter_file_name_); 44 | parameter_file << "PROBLEM_FILE = " + problem_file_name_ + "\n"; 45 | parameter_file << "TOUR_FILE = " + out_file_name_ + "\n"; 46 | parameter_file << "RUNS = 1\n"; 47 | parameter_file << "TRACE_LEVEL = 0\n"; 48 | parameter_file.close(); 49 | } 50 | 51 | void WriteProblemFile() const { 52 | std::ofstream problem_file(problem_file_name_); 53 | problem_file << "NAME : atsp\n"; 54 | problem_file << "TYPE : ATSP\n"; 55 | problem_file << "DIMENSION : " << n_ << "\n"; 56 | problem_file << "EDGE_WEIGHT_TYPE: EXPLICIT\n"; 57 | problem_file << "EDGE_WEIGHT_FORMAT: FULL_MATRIX \n"; 58 | problem_file << "EDGE_WEIGHT_SECTION\n"; 59 | double sum_max = 0; 60 | for(size_t i = 0; i < n_; ++i) { 61 | sum_max += *(std::max_element(d_[i].cbegin(), d_[i].cend())); 62 | } 63 | size_t multiplier = kIntMax/sum_max - 1; 64 | if (multiplier > 3) { 65 | multiplier = 3; 66 | } 67 | std::cout << "multiplier: " << multiplier << std::endl; 68 | multiplier = std::pow(10, multiplier); 69 | for(size_t i = 0; i < n_; ++i) { 70 | for(size_t j = 0; j < n_; ++j) { 71 | problem_file << (size_t)(d_[i][j] * multiplier) << " "; 72 | } 73 | problem_file << "\n"; 74 | } 75 | problem_file.close(); 76 | } 77 | 78 | void ReadTourFile() { 79 | std::ifstream tour_file(out_file_name_); 80 | std::string line; 81 | while(tour_file >> line) { 82 | if (line == "TOUR_SECTION") 83 | break; 84 | } 85 | size_t vertex, start_vertex = kNIL; 86 | bool assign_start_vertex = false; 87 | for(size_t i = 0; i < n_; ++i) { 88 | tour_file >> vertex; 89 | if(assign_start_vertex == false) { 90 | start_vertex = vertex; 91 | assign_start_vertex = true; 92 | } 93 | path_.push_back(vertex - 1); 94 | } 95 | path_.push_back(start_vertex - 1); 96 | tour_file.close(); 97 | } 98 | 99 | public: 100 | ATSP_LKH(size_t n, const std::vector < std::vector > &d) : n_{n}, d_{d} { 101 | path_.reserve(n_); 102 | SolveATSP(); 103 | } 104 | 105 | void SolveATSP() { 106 | std::string tmp_dir = CreateTempDir().string(); 107 | parameter_file_name_ = tmp_dir + "/atsp.par"; 108 | problem_file_name_ = tmp_dir + "/atsp.in"; 109 | out_file_name_ = tmp_dir + "/atsp.out"; 110 | WriteParameterFile(); 111 | WriteProblemFile(); 112 | std::string command_string = "LKH " + parameter_file_name_; 113 | std::cout << command_string << std::endl; 114 | const char *command_char = command_string.c_str(); 115 | auto lkh_exit = system(command_char); 116 | if(lkh_exit != 0) { 117 | std::cerr << "LKH failed\n"; 118 | } 119 | ReadTourFile(); 120 | std::filesystem::remove_all(tmp_dir); 121 | } 122 | 123 | int GetPath(std::vector < size_t > &path) const { 124 | path = path_; 125 | return 0; 126 | } 127 | 128 | }; 129 | 130 | } // namespace lclibrary 131 | 132 | #endif /* LCLIBRARY_ALGORITHMS_ATSP_LKH_H_ */ 133 | -------------------------------------------------------------------------------- /include/lclibrary/algorithms/connected_components.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains functions to compute connected components for a balanced graph 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_ALGORITHMS_CONNECTEDCOMPONENTS_H_ 25 | #define LCLIBRARY_ALGORITHMS_CONNECTEDCOMPONENTS_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace lclibrary { 34 | enum Color { 35 | kWhite, 36 | kGray, 37 | kBlack, 38 | }; 39 | 40 | class ConnectedComponents { 41 | std::shared_ptr g_; 42 | std::vector vertex_list_; 43 | std::vector adjacent_iterator_list_; 44 | std::vector vertex_color_list_; 45 | std::vector vertex_cc_; 46 | std::vector rep_vertices_; 47 | size_t n_; 48 | size_t cc_count_; 49 | 50 | void StronglyCCBalancedAux (size_t u) { 51 | vertex_cc_[u] = cc_count_; 52 | const Vertex *t_v, *h_v; 53 | vertex_color_list_[u] = kGray; 54 | size_t v; 55 | const Edge *e = nullptr; 56 | while (!vertex_list_[u]->IsAdjacencyEnd(adjacent_iterator_list_[u])) { 57 | vertex_list_[u]->GetAdjacentEdge(e, adjacent_iterator_list_[u]); 58 | ++adjacent_iterator_list_[u]; 59 | e->GetVertices(t_v, h_v); 60 | g_->GetVertexIndex(h_v->GetID(), v); 61 | if (vertex_color_list_[v] == kWhite) { 62 | StronglyCCBalancedAux(v); 63 | } 64 | } 65 | vertex_color_list_[u] = kBlack; 66 | 67 | } 68 | 69 | public: 70 | ConnectedComponents(const std::shared_ptr &g) : g_{g}, cc_count_{0} { 71 | n_ = g_->GetN(); 72 | vertex_list_.reserve(n_); 73 | for(size_t i = 0; i < n_; ++i) { 74 | auto v = g_->GetVertex(i); 75 | vertex_list_.push_back(v); 76 | adjacent_iterator_list_.push_back(v->GetAdjacencyStart()); 77 | vertex_cc_.push_back(0); 78 | } 79 | n_ = vertex_list_.size(); 80 | } 81 | 82 | /* Compute connected components for a balanced graph */ 83 | int StronglyCCBalanced() { 84 | if(!IsBalancedDigraph(g_)) { 85 | std::cerr << "Graph is not balanced: at each vertex, number of incoming edges should be equal to outgoing edges \n"; 86 | return 1; 87 | } 88 | for(size_t i = 0; i < n_; ++i) { 89 | if (vertex_list_[i]->GetAdjListSize() > 0) { 90 | vertex_color_list_.push_back(kWhite); 91 | } 92 | else { 93 | vertex_color_list_.push_back(kBlack); 94 | } 95 | } 96 | for (size_t i = 0; i < n_; ++i) { 97 | if (vertex_color_list_[i] == kWhite) { 98 | rep_vertices_.push_back(i); 99 | StronglyCCBalancedAux(i); 100 | ++cc_count_; 101 | } 102 | } 103 | return 0; 104 | } 105 | 106 | size_t GetNumCC() { 107 | return cc_count_; 108 | } 109 | 110 | size_t GetVertexCC(const size_t i) { 111 | return vertex_cc_[i]; 112 | } 113 | 114 | size_t GetRepVertex(const size_t i) { 115 | return rep_vertices_[i]; 116 | } 117 | 118 | }; 119 | 120 | } // namespace lclibrary 121 | 122 | #endif /* LCLIBRARY_ALGORITHMS_CONNECTEDCOMPONENTS_H_ */ 123 | -------------------------------------------------------------------------------- /include/lclibrary/algorithms/euler_tour.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains functions to generate Eulerian Tour 4 | * 5 | * TODO: Why is the GraphType enum here? 6 | * Does not check if the graph is Eulerian! 7 | * Needs cleanup and improvement 8 | * 9 | * @author Saurav Agarwal 10 | * @contact sagarw10@uncc.edu 11 | * @contact agr.saurav1@gmail.com 12 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 13 | * 14 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 15 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 16 | * 17 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 18 | * 19 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 20 | * 21 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 22 | * 23 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 24 | */ 25 | 26 | #ifndef LCLIBRARY_ALGORITHMS_EULERTOURGENERATION_H_ 27 | #define LCLIBRARY_ALGORITHMS_EULERTOURGENERATION_H_ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | namespace lclibrary { 35 | enum GraphType { 36 | kDirectedGraph, 37 | kUndirectedGraph, 38 | }; 39 | 40 | struct EdgeType { 41 | size_t e; 42 | bool type; 43 | bool is_traversed; 44 | EdgeType (): e{0}, type{kIsRequired}, is_traversed{false} {}; 45 | EdgeType (size_t e_in, bool type_in, bool traversed): e{e_in}, type{type_in}, is_traversed{traversed} {}; 46 | }; 47 | 48 | inline Route EulerTourGeneration(const std::shared_ptr g, GraphType graph_type = kDirectedGraph) { 49 | Route route; 50 | if(graph_type == kDirectedGraph) { 51 | if(!IsBalancedDigraph(g)){ 52 | std::cerr << "Graph is not an Eulerian digraph\n"; 53 | return route; 54 | } 55 | } 56 | else if(!IsBalancedGraph(g)){ 57 | std::cerr << "Graph is not balanced\n"; 58 | return route; 59 | } 60 | 61 | auto n = g->GetN(); 62 | auto m = g->GetM(); 63 | auto m_nr = g->GetMnr(); 64 | 65 | std::vector > adjacent_lists; 66 | adjacent_lists.resize(n); 67 | std::vector edge_list; 68 | 69 | size_t t, h; 70 | for(size_t i = 0; i < m; ++i) { 71 | g->GetVerticesIndexOfEdge(i, t, h, kIsRequired); 72 | EdgeType e(i, kIsRequired, false); 73 | edge_list.push_back(e); 74 | adjacent_lists[t].push_back(edge_list.size() - 1); 75 | if (graph_type == kUndirectedGraph) { 76 | adjacent_lists[h].push_back(edge_list.size() - 1); 77 | } 78 | } 79 | for(size_t i = 0; i < m_nr; ++i) { 80 | g->GetVerticesIndexOfEdge(i, t, h, kIsNotRequired); 81 | EdgeType e(i, kIsNotRequired, false); 82 | edge_list.push_back(e); 83 | adjacent_lists[t].push_back(edge_list.size() - 1); 84 | if (graph_type == kUndirectedGraph) { 85 | adjacent_lists[h].push_back(edge_list.size() - 1); 86 | } 87 | } 88 | 89 | std::vector adjacent_list_iterator; 90 | adjacent_list_iterator.resize(n, 0); 91 | 92 | const Vertex *t_v, *h_v; 93 | g->GetVerticesIndexOfEdge(0, t, h, kIsRequired); 94 | auto v = t; 95 | 96 | auto route_it = route.GetRouteStart(); 97 | std::list insert_route; 98 | std::list multi_vertex_list; 99 | const Edge *e = nullptr; 100 | while(adjacent_list_iterator[v] < adjacent_lists[v].size()) { 101 | auto e_idx = adjacent_lists[v][adjacent_list_iterator[v]]; 102 | auto e_t = edge_list[e_idx]; 103 | 104 | e = g->GetEdge(e_t.e, e_t.type); 105 | ++adjacent_list_iterator[v]; 106 | 107 | if (e_t.is_traversed == false) { 108 | 109 | Edge e_new; 110 | e_new = (*e); 111 | if(e_new.GetTailVertexID() != g->GetVertexID(v)) { 112 | e_new.Reverse(); 113 | if(e_new.GetTailVertexID() != g->GetVertexID(v)) { 114 | return route; 115 | } 116 | } 117 | edge_list[e_idx].is_traversed = true; 118 | auto route_it1 = route.AddEdge(e_new, route_it); 119 | 120 | if(adjacent_list_iterator[v] < adjacent_lists[v].size()) { 121 | multi_vertex_list.push_back(v); 122 | insert_route.push_back(route_it1); 123 | } 124 | 125 | e_new.GetVertices(t_v, h_v); 126 | g->GetVertexIndex(h_v->GetID(), v); 127 | } 128 | 129 | while(adjacent_list_iterator[v] >= adjacent_lists[v].size() and multi_vertex_list.size() > 0) { 130 | v = multi_vertex_list.front(); 131 | route_it = insert_route.front(); 132 | multi_vertex_list.pop_front(); 133 | insert_route.pop_front(); 134 | while(adjacent_list_iterator[v] < adjacent_lists[v].size()) { 135 | auto idx = adjacent_lists[v][adjacent_list_iterator[v]]; 136 | if (edge_list[idx].is_traversed == true) { 137 | ++adjacent_list_iterator[v]; 138 | continue; 139 | } 140 | else { 141 | break; 142 | } 143 | } 144 | } 145 | } 146 | return route; 147 | 148 | } 149 | 150 | } // namespace lclibrary 151 | 152 | #endif /* LCLIBRARY_ALGORITHMS_EULERTOURGENERATION_H_ */ 153 | -------------------------------------------------------------------------------- /include/lclibrary/algorithms/is_balanced.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains routine to check if graph is balanced 4 | * 5 | * TODO: Actually add functions to check Eulerian 6 | * Eulerian means balanced and connected 7 | * 8 | * @author Saurav Agarwal 9 | * @contact sagarw10@uncc.edu 10 | * @contact agr.saurav1@gmail.com 11 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 12 | * 13 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 14 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 15 | * 16 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 17 | * 18 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 19 | * 20 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 21 | * 22 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 23 | */ 24 | 25 | #ifndef LCLIBRARY_ALGORITHMS_ISBALANCED_H_ 26 | #define LCLIBRARY_ALGORITHMS_ISBALANCED_H_ 27 | 28 | #include 29 | #include 30 | 31 | namespace lclibrary { 32 | 33 | inline bool IsBalancedDigraph(const std::shared_ptr g) { 34 | auto n = g->GetN(); 35 | auto m = g->GetM(); 36 | auto m_nr = g->GetMnr(); 37 | std::vector vertex_imbalance_list(n, 0); 38 | size_t t_idx, h_idx; 39 | for(size_t i = 0; i < m; ++i) { 40 | g->GetVerticesIndexOfEdge(i, t_idx, h_idx, kIsRequired); 41 | ++vertex_imbalance_list[t_idx]; 42 | --vertex_imbalance_list[h_idx]; 43 | } 44 | for(size_t i = 0; i < m_nr; ++i) { 45 | g->GetVerticesIndexOfEdge(i, t_idx, h_idx, kIsNotRequired); 46 | ++vertex_imbalance_list[t_idx]; 47 | --vertex_imbalance_list[h_idx]; 48 | } 49 | for(auto &del:vertex_imbalance_list) { 50 | if(del != 0) 51 | return false; 52 | } 53 | return true; 54 | } 55 | 56 | inline void ComputeVertexDegree(const std::shared_ptr g, std::vector &vertex_degree_list) { 57 | auto n = g->GetN(); 58 | auto m = g->GetM(); 59 | auto m_nr = g->GetMnr(); 60 | vertex_degree_list.resize(n, 0); 61 | size_t t_idx, h_idx; 62 | for(size_t i = 0; i < m; ++i) { 63 | g->GetVerticesIndexOfEdge(i, t_idx, h_idx, kIsRequired); 64 | ++vertex_degree_list[t_idx]; 65 | ++vertex_degree_list[h_idx]; 66 | } 67 | for(size_t i = 0; i < m_nr; ++i) { 68 | g->GetVerticesIndexOfEdge(i, t_idx, h_idx, kIsNotRequired); 69 | ++vertex_degree_list[t_idx]; 70 | ++vertex_degree_list[h_idx]; 71 | } 72 | } 73 | 74 | inline bool IsBalancedGraph(const std::shared_ptr g) { 75 | std::vector vertex_degree_list; 76 | ComputeVertexDegree(g, vertex_degree_list); 77 | for(const auto &del:vertex_degree_list) { 78 | if(del%2 != 0) 79 | return false; 80 | } 81 | return true; 82 | } 83 | 84 | } // namespace lclibrary 85 | 86 | #endif /* LCLIBRARY_ALGORITHMS_ISBALANCED_H_ */ 87 | -------------------------------------------------------------------------------- /include/lclibrary/algorithms/matching.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains routine to compute matching of odd vertices in a graph 4 | * 5 | * The file uses code from https://github.com/dilsonpereira/Minimum-Cost-Perfect-Matching under MIT license 6 | * Modifications to the program are released in the following repository: 7 | * https://github.com/AgarwalSaurav/mcpm 8 | * 9 | * TODO: Consider writing own matching functions. I did not test the mcpm library. 10 | * 11 | * @author Saurav Agarwal 12 | * @contact sagarw10@uncc.edu 13 | * @contact agr.saurav1@gmail.com 14 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 15 | * 16 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 17 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 18 | * 19 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 20 | * 21 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 22 | * 23 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 24 | * 25 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 26 | */ 27 | 28 | #ifndef LCLIBRARY_ALGORITHMS_MATCHING_H_ 29 | #define LCLIBRARY_ALGORITHMS_MATCHING_H_ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | namespace lclibrary{ 41 | 42 | inline void ComputeMatching(std::vector vertex_degree_list, const std::shared_ptr &apsp, std::vector &matching_edges) { 43 | size_t num_odd_vertices = std::count_if (vertex_degree_list.begin(), vertex_degree_list.end(), [](int i) {return ((i%2) == 1);}); 44 | std::vector odd_vertices; 45 | odd_vertices.reserve(num_odd_vertices); 46 | std::list< std::pair > edges; 47 | for(size_t i = 0; i < vertex_degree_list.size(); ++i) { 48 | if(vertex_degree_list[i]%2 == 1) { 49 | odd_vertices.push_back(i); 50 | } 51 | } 52 | std::vector costs; 53 | costs.reserve((num_odd_vertices * num_odd_vertices - num_odd_vertices)/2); 54 | std::vector < std::vector > d; 55 | d.resize(num_odd_vertices, std::vector (num_odd_vertices)); 56 | for(size_t i = 0; i < num_odd_vertices; ++i) { 57 | for(size_t j = i + 1; j < num_odd_vertices; ++j){ 58 | costs.push_back(apsp->GetCost(odd_vertices[i], odd_vertices[j])); 59 | std::pair edge (i, j); 60 | edges.push_back(edge); 61 | } 62 | } 63 | 64 | mcpm::Graph g_mcpm (num_odd_vertices, edges); 65 | mcpm::Matching m_mcpm(g_mcpm); 66 | std::pair< std::list, double > solution = m_mcpm.SolveMinimumCostPerfectMatching(costs); 67 | auto matching = solution.first; 68 | for(std::list::iterator it = matching.begin(); it != matching.end(); it++) { 69 | std::pair e = g_mcpm.GetEdge( *it ); 70 | apsp->GetPath(matching_edges, odd_vertices[e.first], odd_vertices[e.second]); 71 | } 72 | } 73 | } 74 | 75 | #endif /* LCLIBRARY_ALGORITHMS_MATCHING_H_ */ 76 | -------------------------------------------------------------------------------- /include/lclibrary/algorithms/mst_prim.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains Prim's algorithm for MST 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_ALGORITHMS_MST_PRIM_H_ 25 | #define LCLIBRARY_ALGORITHMS_MST_PRIM_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace lclibrary { 34 | 35 | bool MST_Prim(const std::shared_ptr &g, std::vector &mst_edges) { 36 | size_t n = g->GetN(); 37 | size_t m = g->GetM(); 38 | std::vector > adjacent_lists; 39 | adjacent_lists.resize(n); 40 | 41 | size_t t, h; 42 | for(size_t i = 0; i < m; ++i) { 43 | g->GetVerticesIndexOfEdge(i, t, h); 44 | adjacent_lists[t].push_back(i); 45 | adjacent_lists[h].push_back(i); 46 | } 47 | 48 | std::vector adjacent_list_iterator; 49 | adjacent_list_iterator.resize(n, 0); 50 | 51 | std::vector vertex_list(n, kNIL); 52 | for(size_t i = 0; i < n; ++i) { 53 | vertex_list[i] = i; 54 | } 55 | 56 | std::vector visited (n, false); 57 | std::vector value (n, kDoubleMax); 58 | 59 | value[0] = 0; 60 | 61 | auto cmp = [&value](size_t lhs, size_t rhs) { return value[lhs] > value[rhs]; }; 62 | std::priority_queue , decltype(cmp)> q(cmp); 63 | q.push(0); 64 | 65 | size_t u = kNIL; 66 | while(not q.empty()) { 67 | u = q.top(); 68 | q.pop(); 69 | if(visited[u] == true) 70 | continue; 71 | visited[u] = true; 72 | while(adjacent_list_iterator[u] < adjacent_lists[u].size()) { 73 | size_t v; 74 | size_t t, h; 75 | auto e = adjacent_lists[u][adjacent_list_iterator[u]]; 76 | g->GetVerticesIndexOfEdge(e, t, h); 77 | ++adjacent_list_iterator[u]; 78 | if(u == t) 79 | v = h; 80 | else 81 | v = t; 82 | 83 | if(visited[v] == false and g->GetCost(e) < value[v] ) { 84 | 85 | g->GetVerticesIndexOfEdge(e, t, h); 86 | mst_edges.push_back(*(g->GetEdge(e))); 87 | value[v] = g->GetCost(e); 88 | q.push(v); 89 | } 90 | } 91 | } 92 | 93 | return 0; 94 | } 95 | 96 | } // namespace lclibrary 97 | 98 | #endif /* LCLIBRARY_ALGORITHMS_MST_PRIM_H_ */ 99 | -------------------------------------------------------------------------------- /include/lclibrary/algorithms/required_graph.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains helpful functions related to required subgraph 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_ALGORITHMS_REQUIRED_GRAPH_H_ 25 | #define LCLIBRARY_ALGORITHMS_REQUIRED_GRAPH_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | namespace lclibrary { 33 | 34 | inline bool GenerateRequiredGraph(const std::shared_ptr &g, std::shared_ptr &g_r) { 35 | size_t m = g->GetM(); 36 | size_t n = g->GetN(); 37 | std::vector required_vertices_check (n, false); 38 | std::vector edge_list; 39 | edge_list.reserve(m); 40 | std::vector vertex_list; 41 | vertex_list.reserve(n); 42 | for (size_t i = 0; i < m; ++i) { 43 | size_t t, h; 44 | g->GetVerticesIndexOfEdge(i, t, h, kIsRequired); 45 | if (required_vertices_check[t] == false) { 46 | Vertex tv; 47 | g->GetVertexData(t, tv); 48 | vertex_list.push_back(tv); 49 | required_vertices_check[t] = true; 50 | } 51 | if (required_vertices_check[h] == false) { 52 | Vertex hv; 53 | g->GetVertexData(h, hv); 54 | vertex_list.push_back(hv); 55 | required_vertices_check[h] = true; 56 | } 57 | Edge e; 58 | g->GetEdgeData(i, e, kIsRequired); 59 | edge_list.push_back(e); 60 | } 61 | g_r = std::make_shared (vertex_list, edge_list, m, 0); 62 | return 0; 63 | } 64 | 65 | inline size_t GetNumCCRequiredGraph(std::shared_ptr g) { 66 | std::shared_ptr g_r; 67 | GenerateRequiredGraph(g, g_r); 68 | g_r->AddReverseEdges(); 69 | ConnectedComponents cc(g_r); 70 | cc.StronglyCCBalanced(); 71 | size_t num_cc = cc.GetNumCC(); 72 | return num_cc; 73 | } 74 | 75 | } // namespace lclibrary 76 | 77 | #endif /* LCLIBRARY_ALGORITHMS_REQUIRED_GRAPH_H_ */ 78 | -------------------------------------------------------------------------------- /include/lclibrary/core/constants.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains constants 4 | * 5 | * @author Saurav Agarwal 6 | * @contact sagarw10@uncc.edu 7 | * @contact agr.saurav1@gmail.com 8 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 9 | * 10 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 11 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 12 | * 13 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 14 | * 15 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 16 | * 17 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 18 | * 19 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 20 | */ 21 | 22 | #ifndef LCLIBRARY_CORE_CONSTANTS_H_ 23 | #define LCLIBRARY_CORE_CONSTANTS_H_ 24 | 25 | #include 26 | #include 27 | 28 | namespace lclibrary { 29 | const double kEps = 1e-12; 30 | const double kDoubleMax = std::numeric_limits::max(); 31 | const double kDoubleMin = std::numeric_limits::min(); 32 | const double kIntMax = std::numeric_limits::max(); 33 | const size_t kNIL = std::numeric_limits::max(); 34 | const bool kIsRequired = true; 35 | const bool kIsNotRequired = false; 36 | const bool kReverse = true; 37 | const bool kSuccess = false; 38 | const bool kFail = true; 39 | const bool kIsWithLLA = true; 40 | const bool kIsWithCost = true; 41 | const double kDoubleNaN = std::numeric_limits::quiet_NaN(); 42 | } 43 | 44 | #endif /* LCLIBRARY_CORE_CONSTANTS_H_ */ 45 | -------------------------------------------------------------------------------- /include/lclibrary/core/core.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * Top level header for core 4 | * 5 | * @author Saurav Agarwal 6 | * @contact sagarw10@uncc.edu 7 | * @contact agr.saurav1@gmail.com 8 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 9 | * 10 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 11 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 12 | * 13 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 14 | * 15 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 16 | * 17 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 18 | * 19 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 20 | */ 21 | 22 | #ifndef LCLIBRARY_CORE_H_ 23 | #define LCLIBRARY_CORE_H_ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #endif /* LCLIBRARY_CORE_H_ */ 39 | -------------------------------------------------------------------------------- /include/lclibrary/core/edge_cost_base.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains abstract base class for edge costs 4 | * 5 | * @author Saurav Agarwal 6 | * @contact sagarw10@uncc.edu 7 | * @contact agr.saurav1@gmail.com 8 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 9 | * 10 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 11 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 12 | * 13 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 14 | * 15 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 16 | * 17 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 18 | * 19 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 20 | */ 21 | 22 | 23 | #ifndef LCLIBRARY_CORE_EDGECOST_H_ 24 | #define LCLIBRARY_CORE_EDGECOST_H_ 25 | 26 | #include 27 | 28 | namespace lclibrary { 29 | 30 | class EdgeCost { 31 | 32 | public: 33 | virtual int ComputeServiceCost(const Edge &, double &, double &) const = 0; 34 | virtual int ComputeDeadheadCost(const Edge &, double &, double &) const = 0; 35 | }; 36 | 37 | class EdgeCostTurns : public EdgeCost{ 38 | public: 39 | virtual int ComputeTurnCost(const Edge &, const Edge &, const bool, const bool, const bool, const bool, double &) const = 0; 40 | }; 41 | 42 | } 43 | 44 | #endif /* LCLIBRARY_CORE_EDGECOST_H_ */ 45 | -------------------------------------------------------------------------------- /include/lclibrary/core/graph_io.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains functions for Graph IO 4 | * 5 | * @author Saurav Agarwal 6 | * @contact sagarw10@uncc.edu 7 | * @contact agr.saurav1@gmail.com 8 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 9 | * 10 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 11 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 12 | * 13 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 14 | * 15 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 16 | * 17 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 18 | * 19 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 20 | */ 21 | 22 | #ifndef LCLIBRARY_CORE_GRAPH_IO_H_ 23 | #define LCLIBRARY_CORE_GRAPH_IO_H_ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | namespace lclibrary { 34 | 35 | /*! Create graph with only required edges */ 36 | int CreateGraph( 37 | std::shared_ptr &, 38 | const std::string &, 39 | const std::string &, 40 | const bool, 41 | const bool, 42 | const bool filter_vertices = false); 43 | 44 | /*! Create graph with required and non-required edges */ 45 | int CreateGraph( 46 | std::shared_ptr &, 47 | const std::string &, 48 | const std::string &, 49 | const std::string &, 50 | const bool, 51 | const bool); 52 | 53 | void WriteGraphInfo (std::shared_ptr , 54 | const std::string &); 55 | 56 | void WriteNodes( 57 | std::shared_ptr , 58 | const std::string, 59 | const bool is_with_lla = not kIsWithLLA); 60 | 61 | void WriteRequiredEdges( 62 | std::shared_ptr , 63 | const std::string); 64 | 65 | void WriteNonRequiredEdges( 66 | std::shared_ptr , 67 | const std::string); 68 | 69 | void VertexParser ( 70 | std::vector &, 71 | const std::ifstream &, 72 | const bool is_with_lla = kIsWithLLA); 73 | 74 | void FileParser ( 75 | std::shared_ptr &, 76 | std::ifstream &, 77 | std::ifstream &, 78 | const bool, 79 | const bool, 80 | const bool filter_vertices = false); 81 | 82 | void FileParser ( 83 | std::shared_ptr &, 84 | std::ifstream &, 85 | std::ifstream &, 86 | std::ifstream &, 87 | const bool, 88 | const bool, 89 | const bool filter_vertices = false); 90 | 91 | void EdgeParser ( 92 | std::vector &, 93 | std::ifstream &, const bool, size_t &); 94 | 95 | void EdgeParser ( 96 | std::vector &, 97 | std::ifstream &, 98 | std::ifstream &, 99 | const bool, 100 | size_t &, 101 | size_t &); 102 | 103 | void DepotListParser( 104 | const std::string &, 105 | std::vector &); 106 | } 107 | #endif /* LCLIBRARY_CORE_GRAPH_IO_H_ */ 108 | 109 | -------------------------------------------------------------------------------- /include/lclibrary/core/graph_utilities.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains utilities functions for graphs 4 | * 5 | * @author Saurav Agarwal 6 | * @contact sagarw10@uncc.edu 7 | * @contact agr.saurav1@gmail.com 8 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 9 | * 10 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 11 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 12 | * 13 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 14 | * 15 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 16 | * 17 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 18 | * 19 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 20 | */ 21 | 22 | #ifndef LCLIBRARY_CORE_GRAPH_UTILITIES_H_ 23 | #define LCLIBRARY_CORE_GRAPH_UTILITIES_H_ 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | namespace lclibrary { 30 | 31 | /* Add a non-required edge for every pair of vertices */ 32 | void AddCompleteNonRequiredEdges(std::shared_ptr &); 33 | 34 | /* Add a non-required edge for every pair of vertices, except when it is same as a required edge */ 35 | void AddReducedCompleteNonRequiredEdges(std::shared_ptr &); 36 | 37 | /* Compute edge costs for all the edges using an EdgeCost based object */ 38 | int ComputeAllEdgeCosts(std::shared_ptr &, EdgeCost &); 39 | 40 | } 41 | 42 | #endif /* GRAPH_UTILITIES_UTILITIES_H_ */ 43 | -------------------------------------------------------------------------------- /include/lclibrary/core/graph_wrapper.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains wrapper function for graphs, uses Config object to create graphs 4 | * 5 | * @author Saurav Agarwal 6 | * @contact sagarw10@uncc.edu 7 | * @contact agr.saurav1@gmail.com 8 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 9 | * 10 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 11 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 12 | * 13 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 14 | * 15 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 16 | * 17 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 18 | * 19 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 20 | */ 21 | 22 | #ifndef LCLIBRARY_CORE_GRAPH_WRAPPER_H_ 23 | #define LCLIBRARY_CORE_GRAPH_WRAPPER_H_ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | namespace lclibrary { 37 | 38 | inline int GraphCreate(const Config &config, std::shared_ptr &g) { 39 | if(CreateGraph(g, config.database.dir + config.filenames.nodes_data, config.database.dir + config.filenames.req_edges, config.input_graph.lla, config.input_graph.costs) == kFail) { 40 | std::cerr << "Graph creation failed\n"; 41 | return kFail; 42 | } 43 | 44 | if(config.add_pairwise_nonreq_edges) { 45 | /* AddCompleteNonRequiredEdges(g); */ 46 | AddReducedCompleteNonRequiredEdges(g); 47 | } 48 | 49 | if(config.depot_mode == Config::DepotMode::mean) { 50 | if(g->SetMeanDepot() == kFail) { 51 | std::cerr << "Depot could not be set\n"; 52 | return kFail; 53 | } 54 | } 55 | 56 | if(config.depot_mode == Config::DepotMode::custom) { 57 | if(g->SetDepot(config.depot_ID) == kFail) { 58 | std::cerr << "Depot could not be set\n"; 59 | return kFail; 60 | } 61 | } 62 | 63 | if(config.problem == "mlc") { 64 | if(g->CheckDepotRequiredVertex() == kFail) { 65 | if(g->AddDepotAsRequiredEdge() == kFail) { 66 | return kFail; 67 | } 68 | } 69 | } 70 | 71 | return kSuccess; 72 | } 73 | 74 | inline int GraphCreateWithCostFn(const Config &config, std::shared_ptr &g) { 75 | 76 | if(GraphCreate(config, g) == kFail) { 77 | return kFail; 78 | } 79 | 80 | if(config.cost_function == "euclidean") { 81 | g->SetDefaultEdgeCosts(); 82 | } 83 | 84 | if(config.cost_function == "ramp") { 85 | g->SetRampEdgeCosts(config.ramp.acceleration, config.ramp.speed); 86 | } 87 | 88 | if(config.cost_function == "travel_time") { 89 | std::shared_ptr edge_cost_fn; 90 | auto params = config.travel_time; 91 | edge_cost_fn = std::make_shared (params.service_speed, params.deadhead_speed, params.wind_speed, params.wind_dir); 92 | ComputeAllEdgeCosts(g, *edge_cost_fn); 93 | } 94 | 95 | if(config.cost_function == "travel_time_circturns") { 96 | std::shared_ptr edge_cost_fn; 97 | auto params = config.travel_time_circ_turns; 98 | edge_cost_fn = std::make_shared (params.service_speed, params.deadhead_speed, params.wind_speed, params.wind_dir, params.angular_vel, params.acc, params.delta); 99 | ComputeAllEdgeCosts(g, *edge_cost_fn); 100 | g->SetTurnsCostFunction(edge_cost_fn); 101 | } 102 | 103 | if(config.problem == "mlc" or config.problem == "mlc_md") { 104 | g->SetCapacity(config.capacity); 105 | g->SetDemandsToCosts(); 106 | } 107 | 108 | return kSuccess; 109 | } 110 | 111 | 112 | } 113 | 114 | #endif /* LCLIBRARY_CORE_GRAPH_WRAPPER_H_ */ 115 | -------------------------------------------------------------------------------- /include/lclibrary/core/math_utils.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains math utility functions 4 | * 5 | * @author Saurav Agarwal 6 | * @contact sagarw10@uncc.edu 7 | * @contact agr.saurav1@gmail.com 8 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 9 | * 10 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 11 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 12 | * 13 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 14 | * 15 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 16 | * 17 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 18 | * 19 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 20 | */ 21 | 22 | /** 23 | * TODO: Add more helpful functions instead of spilling all over the library 24 | */ 25 | 26 | #ifndef LCLIBRARY_UTILS_MATH_UTILS_H_ 27 | #define LCLIBRARY_UTILS_MATH_UTILS_H_ 28 | 29 | #include 30 | #include 31 | 32 | namespace lclibrary { 33 | 34 | inline bool IsNearZero(double const x, double const eps = kEps) { 35 | if(std::abs(x) < eps) 36 | return true; 37 | else 38 | return false; 39 | } 40 | 41 | } /* lclibrary */ 42 | #endif /* LCLIBRARY_UTILS_MATH_UTILS_H_ */ 43 | -------------------------------------------------------------------------------- /include/lclibrary/core/mem_base.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains base class for MEM 4 | * 5 | * @author Saurav Agarwal 6 | * @contact sagarw10@uncc.edu 7 | * @contact agr.saurav1@gmail.com 8 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 9 | * 10 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 11 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 12 | * 13 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 14 | * 15 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 16 | * 17 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 18 | * 19 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 20 | */ 21 | 22 | /** 23 | * TODO: use smart pointers 24 | */ 25 | 26 | #ifndef LCLIBRARY_MEM_BASE_H_ 27 | #define LCLIBRARY_MEM_BASE_H_ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | namespace lclibrary { 35 | 36 | struct RouteSavings { 37 | size_t p_; 38 | size_t q_; 39 | double savings_; 40 | size_t savings_perm_; 41 | double demands_; 42 | size_t depot_; 43 | RouteSavings() : p_{kNIL}, q_{kNIL}, savings_{-kDoubleMax} {} 44 | RouteSavings(const size_t p, const size_t q) : p_{p}, q_{q}, savings_{-kDoubleMax} {} 45 | }; 46 | 47 | struct MEM_Route { 48 | MEM_Route *route1_ = nullptr; 49 | MEM_Route *route2_ = nullptr; 50 | EdgeTuple edge_ = MakeEdgeTuple(nullptr, false); 51 | size_t vertex_idx_start_ = kNIL; 52 | size_t vertex_idx_end_ = kNIL; 53 | size_t edge_idx_start_ = kNIL; 54 | size_t edge_idx_end_ = kNIL; 55 | bool start_reversed_ = false; 56 | bool end_reversed_ = false; 57 | bool reversed_ = false; 58 | double cost_ = 0; 59 | double demand_ = 0; 60 | double req_cost_ = 0; 61 | double req_cost_rev_ = 0; 62 | double req_demand_ = 0; 63 | double req_demand_rev_ = 0; 64 | size_t depot_; 65 | 66 | void XOR(const bool reverse) {reversed_ = reversed_ xor reverse;} 67 | void GetVertices(size_t &t, size_t &h) const { 68 | if(reversed_) { 69 | t = vertex_idx_end_; h = vertex_idx_start_; 70 | } 71 | else { 72 | h = vertex_idx_end_; t = vertex_idx_start_; 73 | } 74 | } 75 | void GetEdges(size_t &e_start, size_t &e_end) const { 76 | e_start = edge_idx_start_; e_end = edge_idx_end_; 77 | } 78 | }; 79 | 80 | typedef std::priority_queue , std::less > SavingsHeap; 81 | 82 | inline bool operator<(const RouteSavings &lhs, const RouteSavings &rhs) { 83 | return lhs.savings_ < rhs.savings_; 84 | } 85 | 86 | class MEM_Base { 87 | SavingsHeap savings_heap_; 88 | 89 | virtual bool InitializeRoutes() = 0; 90 | virtual bool ComputeSavings(RouteSavings &) = 0; 91 | virtual void Merge(const RouteSavings &) = 0; 92 | virtual bool IsTourEmpty(const size_t) = 0; 93 | virtual size_t NumOfRoutes() = 0; 94 | 95 | public: 96 | 97 | MEM_Base() {} 98 | 99 | void MEM() { 100 | size_t m = NumOfRoutes(); 101 | std::vector initial_savings; 102 | for (size_t i = 0; i < m; ++i) { 103 | for (size_t j = i + 1; j < m; ++j) { 104 | RouteSavings rs(i, j); 105 | if(ComputeSavings(rs) == kSuccess) { 106 | /* std::cout << "Init: " << rs.depot_ << " " << rs.savings_<< std::endl; */ 107 | initial_savings.push_back(rs); 108 | } 109 | } 110 | } 111 | savings_heap_ = SavingsHeap(initial_savings.begin(), initial_savings.end()); 112 | 113 | /* int count = 0; */ 114 | while(!savings_heap_.empty()) { 115 | auto pqs = savings_heap_.top(); 116 | savings_heap_.pop(); 117 | if(IsTourEmpty(pqs.p_)) 118 | continue; 119 | if(IsTourEmpty(pqs.q_)) 120 | continue; 121 | /* std::cout << "saving: " << pqs.depot_ << " " << pqs.savings_ << std::endl; */ 122 | Merge(pqs); 123 | auto r = NumOfRoutes() - 1; 124 | for(size_t i = 0; i < r; ++i) { 125 | if(IsTourEmpty(i)) 126 | continue; 127 | RouteSavings rs(r, i); 128 | if(ComputeSavings(rs) == kSuccess) { 129 | savings_heap_.push(rs); 130 | } 131 | } 132 | } 133 | } 134 | }; 135 | 136 | } 137 | #endif /* LCLIBRARY_MEM_BASE_H_ */ 138 | -------------------------------------------------------------------------------- /include/lclibrary/core/transform_lla_xy.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains class to convert LLA to XY and vice versa 4 | * 5 | * TODO: 6 | * Use geodesy library? 7 | * 8 | * @author Saurav Agarwal 9 | * @contact sagarw10@uncc.edu 10 | * @contact agr.saurav1@gmail.com 11 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 12 | * 13 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 14 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 15 | * 16 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 17 | * 18 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 19 | * 20 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 21 | * 22 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 23 | */ 24 | 25 | #ifndef LCLIBRARY_CORE_TRANSFORM_LLA_XY_H_ 26 | #define LCLIBRARY_CORE_TRANSFORM_LLA_XY_H_ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #define WGS84_EquitorialRadius 6378137.000000 34 | #define WGS84_PolarSemiMinorAxis 6356752.314245 35 | #define WGS84_flattening 0.003352810664 36 | /* 37 | input: 38 | refLat,refLon : geodetic coordinate which you defined as 0,0 in cartesian coordinate (the unit is in radian) 39 | 40 | lat,lon : geodetic coordinate which you want to calculate its cartesian coordinate (the unit is in radian) 41 | 42 | xOffset,yOffset : the result in cartesian coordinate x,y (the unit is in meters) 43 | 44 | */ 45 | namespace lclibrary{ 46 | 47 | class LLAtoXY { 48 | private: 49 | double a, b, f; 50 | double refLat, refLon, refAlt; 51 | double r_n, r_m; 52 | public: 53 | inline double degTorad (double deg){ 54 | return M_PI * deg / 180.0; 55 | } 56 | inline double radTodeg (double rad){ 57 | return 180.0 * rad / M_PI; 58 | } 59 | 60 | LLAtoXY() {}; 61 | LLAtoXY(std::string nodeFileName, std::string outNodeFileName){ 62 | parse_write(nodeFileName, outNodeFileName); 63 | } 64 | 65 | void GetRefLatLong(double &rlat, double &rlon, double &ralt) { 66 | rlat = refLat; 67 | rlon = refLon; 68 | ralt = refAlt; 69 | } 70 | 71 | void SetRefLatLong(const double rlat, const double rlon, const double ralt) { 72 | refLat = degTorad(rlat); 73 | refLon = degTorad(rlon); 74 | refAlt = ralt; 75 | double R = WGS84_EquitorialRadius; 76 | double sinMu0 = sin(refLat); 77 | double sinSqMu0 = sinMu0 * sinMu0; 78 | 79 | double f = WGS84_flattening; 80 | double r_m_deno = 1.0 - (2.0 * f - f * f) * sinSqMu0; 81 | double r_n_deno = std::sqrt(r_m_deno); 82 | r_n = R / r_n_deno; 83 | r_m = r_n * (1.0 - (2.0 * f - f * f)) / r_m_deno; 84 | } 85 | 86 | void llaToFlat(double lat, double lon, double alt, double& xOffset, double& yOffset, double& zOffset) { 87 | 88 | double R = WGS84_EquitorialRadius; 89 | double sinMu0 = sin(refLat); 90 | double sinSqMu0 = sinMu0 * sinMu0; 91 | 92 | double f = WGS84_flattening; 93 | double r_m_deno = 1.0 - (2.0 * f - f * f) * sinSqMu0; 94 | double r_n_deno = std::sqrt(r_m_deno); 95 | r_n = R / r_n_deno; 96 | r_m = r_n * (1.0 - (2.0 * f - f * f)) / r_m_deno; 97 | double dMu = degTorad(lat) - refLat; 98 | double dL = degTorad(lon) - refLon; 99 | yOffset = dMu/(atan(1.0/r_m)); 100 | xOffset = dL/(atan(1.0/(r_n * cos (refLat)))); 101 | zOffset = alt - refAlt; 102 | } 103 | void flatToLLA(double xOffset, double yOffset, double zOffset, double &lat, double &lon, double &alt) { 104 | double dMu = yOffset * (atan(1.0/r_m)); 105 | double dL = xOffset * (atan(1.0/(r_n * cos (refLat)))); 106 | lat = radTodeg(dMu + refLat); 107 | lon = radTodeg(dL + refLon); 108 | alt = zOffset - refAlt; 109 | } 110 | 111 | void parse_write(std::string nodeFileName, std::string outNodeFileName){ 112 | std::fstream nodeInFile; 113 | nodeInFile.open(nodeFileName); 114 | if (!nodeInFile) { 115 | std::cerr << "Unable to open file " << nodeFileName << "\n"; 116 | exit(1); // call system to stop 117 | } 118 | 119 | std::ofstream nodeOutFile; 120 | nodeOutFile.open(outNodeFileName); 121 | if (!nodeOutFile) { 122 | std::cerr << "Unable to open file " << outNodeFileName << "\n"; 123 | exit(1); // call system to stop 124 | } 125 | nodeOutFile.precision(16); 126 | double dummyAlt = 229; 127 | 128 | std::unordered_map nodeMap; 129 | size_t nodeID; 130 | double nodeLat, nodeLon; 131 | size_t countNode = 0; 132 | bool flag = 0; 133 | while (nodeInFile >> nodeID){ 134 | nodeMap[nodeID] = countNode++; 135 | nodeInFile >> nodeLat; 136 | nodeInFile >> nodeLon; 137 | if ( !flag ){ 138 | flag = 1; 139 | refLat = degTorad(nodeLat); 140 | refLon = degTorad(nodeLon);; 141 | refAlt = dummyAlt; 142 | } 143 | double xOffset, yOffset, zOffset; 144 | llaToFlat(nodeLat, nodeLon, dummyAlt + 50.0, xOffset, yOffset, zOffset); 145 | nodeOutFile << nodeID << " " << xOffset << " " << yOffset << " " << nodeLat << " " << nodeLon << " " << zOffset << "\n"; 146 | 147 | } 148 | nodeInFile.close(); 149 | nodeOutFile.close(); 150 | 151 | } 152 | 153 | }; 154 | } // namespace lclibrary 155 | 156 | #endif /* LCLIBRARY_CORE_TRANSFORM_LLA_XY_H_ */ 157 | -------------------------------------------------------------------------------- /include/lclibrary/core/typedefs.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains TypeDefs 4 | * 5 | * TODO: Is this a good way to define typedefs, or should they be in relevant class header files? 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_CORE_TYPEDEFS_H_ 25 | #define LCLIBRARY_CORE_TYPEDEFS_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | namespace lclibrary { 32 | typedef std::vector VertexList; 33 | typedef std::vector EdgeList; 34 | } 35 | 36 | #endif /* LCLIBRARY_CORE_TYPEDEFS_H_ */ 37 | -------------------------------------------------------------------------------- /include/lclibrary/core/vec2d.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The following Vec2d Class is for 2D-vector based computations 4 | * 5 | * @author Saurav Agarwal 6 | * @contact sagarw10@uncc.edu 7 | * @contact agr.saurav1@gmail.com 8 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 9 | * 10 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 11 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 12 | * 13 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 14 | * 15 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 16 | * 17 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 18 | * 19 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 20 | */ 21 | 22 | #ifndef LCLIBRARY_CORE_VEC2D_H_ 23 | #define LCLIBRARY_CORE_VEC2D_H_ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | namespace lclibrary { 31 | 32 | class Vec2d { 33 | public: 34 | double x; 35 | double y; 36 | Vec2d(): x{0.0}, y{0.0}{} 37 | Vec2d(const double x_i, const double y_i): x{x_i}, y{y_i}{} 38 | Vec2d (const double p1[2], const double p2[2]){ 39 | x = p2[0] - p1[0]; 40 | y = p2[1] - p1[1]; 41 | } 42 | 43 | /*! Computes perpendicular Vector */ 44 | Vec2d Perpendicular() const{ 45 | Vec2d v_perpendicular; 46 | v_perpendicular.x = -y; 47 | v_perpendicular.y = x; 48 | return v_perpendicular; 49 | } 50 | 51 | /*! Adds two vectors */ 52 | void Add(Vec2d const &v) { 53 | x += v.x; y += v.y; 54 | } 55 | 56 | /*! Divide vector by a scalar */ 57 | int Divide(const double scalar) { 58 | if(std::abs(scalar) < kEps) { 59 | return kFail; 60 | } 61 | x = x/scalar; y = y/scalar; 62 | return kSuccess; 63 | } 64 | 65 | /*! Computes dot product of two Vectors */ 66 | double Dot(Vec2d const &v) const{ 67 | return v.x * x + v.y * y; 68 | } 69 | 70 | /*! Returns square of Euclidean distance from origin */ 71 | double NormSqr() const{ 72 | return x * x + y *y; 73 | } 74 | 75 | /*! Returns Euclidean distance from origin */ 76 | double Norm() const{ 77 | return std::sqrt(NormSqr()); 78 | } 79 | 80 | /*! Gives cosine of the angle between this and Vector v */ 81 | int CosAngle(Vec2d const &v, double &ang) const{ 82 | if (std::abs(Norm()) < 1e-10 || std::abs(v.Norm()) < 1e-10) 83 | return kFail; 84 | ang = Dot(v)/(Norm() * v.Norm()); 85 | return kSuccess; 86 | } 87 | 88 | /*! Gives the distance between the Vector and another Vector v */ 89 | double DistSqr(Vec2d const &v) const{ 90 | double del_x = x - v.x; 91 | double del_y = y - v.y; 92 | double dSqr = (del_x * del_x + del_y * del_y); 93 | return dSqr; 94 | } 95 | 96 | double Dist(Vec2d const &v) const { 97 | return std::sqrt(DistSqr(v)); 98 | } 99 | 100 | /*! Computes distance and angle with another Vector (v-this)*/ 101 | void DistTht(Vec2d const &v, double &d, double &tht) const{ 102 | d = std::sqrt(DistSqr(v)); 103 | double del_x = -x + v.x; 104 | double del_y = -y + v.y; 105 | tht = std::atan2(del_y, del_x); 106 | if(tht < 0) 107 | tht += M_PI; 108 | } 109 | 110 | bool IsZero() const { 111 | if(IsNearZero(x) and IsNearZero(y)) { 112 | return true; 113 | } 114 | return false; 115 | } 116 | 117 | /*! Gives the direction of travel Vector */ 118 | Vec2d TravelVec(Vec2d const &v) const{ 119 | Vec2d travel_vec; 120 | travel_vec.x = -x + v.x; 121 | travel_vec.y = -y + v.y; 122 | return travel_vec; 123 | } 124 | 125 | Vec2d operator+ (const Vec2d &vec){ 126 | return Vec2d(x + vec.x, y + vec.y); 127 | } 128 | 129 | Vec2d operator- (const Vec2d &vec){ 130 | return Vec2d(x - vec.x, y - vec.y); 131 | } 132 | 133 | Vec2d operator- (){ 134 | return Vec2d(-x, -y); 135 | } 136 | 137 | Vec2d operator/ (const double &scalar){ 138 | return Vec2d(x / scalar, y / scalar); 139 | } 140 | 141 | Vec2d operator* (const double &scalar){ 142 | return Vec2d(x * scalar, y * scalar); 143 | } 144 | 145 | int Normalize () { 146 | double norm = Norm(); 147 | if(norm < kEps) { 148 | return kFail; 149 | } 150 | x = x/norm; 151 | y = y/norm; 152 | return kSuccess; 153 | } 154 | }; 155 | 156 | inline std::ostream& operator<<(std::ostream &ostream_obj, const Vec2d &vec) { 157 | ostream_obj << vec.x << " " << vec.y; 158 | return ostream_obj; 159 | } 160 | 161 | } // namespace lclibrary 162 | #endif /* LCLIBRARY_CORE_VEC2D_H_ */ 163 | -------------------------------------------------------------------------------- /include/lclibrary/core/vertex.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The following Vertex Class is for creating, deleting and modifying vertices in a Graph. 4 | * 5 | * @author Saurav Agarwal 6 | * @contact sagarw10@uncc.edu 7 | * @contact agr.saurav1@gmail.com 8 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 9 | * 10 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 11 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 12 | * 13 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 14 | * 15 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 16 | * 17 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 18 | * 19 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 20 | */ 21 | 22 | #ifndef LCLIBRARY_CORE_VERTEX_H_ 23 | #define LCLIBRARY_CORE_VERTEX_H_ 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | namespace lclibrary { 32 | 33 | class Edge; 34 | typedef std::list AdjacentEdgeList; 35 | 36 | class Vertex { 37 | size_t id_; /*! Actual node ID of the Vertex */ 38 | AdjacentEdgeList adjacent_edges_list_; /*! Stores adjacent vertices of the Vertex */ 39 | double lla_[3]; /*! Latitude, longitude, altitude */ 40 | Vec2d xy_; /*! XY coordinate */ 41 | 42 | public: 43 | 44 | /*! Constructor: takes in id_ of the Vertex */ 45 | Vertex(size_t id_i) : id_{id_i} { SetLLA(0, 0, 0); SetXY(0, 0); } 46 | 47 | Vertex() : Vertex(0) {} 48 | 49 | /*! Copy constructor (does not copy adjacency list)*/ 50 | Vertex(const Vertex &v){ 51 | CopyDataFromVertex(v); 52 | } 53 | 54 | void operator = (const Vertex &v ) { 55 | CopyDataFromVertex(v); 56 | } 57 | 58 | void CopyDataFromVertex(const Vertex &v) { 59 | auto v_xy = v.GetXY(); 60 | xy_.x = v_xy.x; xy_.y = v_xy.y; 61 | double v_lla[3]; 62 | v.GetLLA(v_lla); 63 | for(size_t i = 0; i < 3; ++i){ 64 | lla_[i] = v_lla[i]; 65 | } 66 | id_ = v.GetID(); 67 | } 68 | 69 | void SetLLA(const double lat, const double lon, const double alt) { 70 | lla_[0] = lat; lla_[1] = lon; lla_[2] = alt; 71 | } 72 | 73 | void SetXY(const double X, const double Y) { xy_.x = X; xy_.y = Y; } 74 | 75 | Vec2d GetXY() const{ return xy_; } 76 | 77 | void PrintXY() const{ std::cout << id_ <<" " << xy_.x << " " << xy_.y << std::endl; } 78 | 79 | void GetLLA(double * v_lla) const{ 80 | for(size_t i = 0; i < 3; ++i){ 81 | v_lla[i] = lla_[i]; 82 | } 83 | } 84 | 85 | /*! Adds adjacent edge/arc */ 86 | void AddEdge(const Edge *e) { 87 | adjacent_edges_list_.push_back(e); 88 | } 89 | 90 | /*! Clears adjacent edge list */ 91 | void ClearAdjacentList(){ 92 | adjacent_edges_list_.clear(); 93 | } 94 | 95 | AdjacentEdgeList::const_iterator GetAdjacencyStart() const{ 96 | return adjacent_edges_list_.cbegin(); 97 | } 98 | 99 | bool IsAdjacencyEnd(const AdjacentEdgeList::const_iterator it) const { 100 | if (it == adjacent_edges_list_.cend()) 101 | return kFail; 102 | else 103 | return kSuccess; 104 | } 105 | 106 | bool GetAdjacentEdge(const Edge *&e, const AdjacentEdgeList::const_iterator it) const { 107 | if(it == adjacent_edges_list_.end()) { 108 | e = nullptr; 109 | return kFail; 110 | } 111 | e = *it; 112 | return kSuccess; 113 | } 114 | 115 | /*! Returns size of adjacent list */ 116 | size_t GetAdjListSize() const{ return adjacent_edges_list_.size(); } 117 | 118 | size_t GetID() const { return id_; } 119 | 120 | void SetID(const size_t a){ id_ = a; } 121 | 122 | }; 123 | 124 | } // namespace lclibrary 125 | 126 | #endif /* LCLIBRARY_CORE_VERTEX_H_ */ 127 | -------------------------------------------------------------------------------- /include/lclibrary/mlc/ilp_base.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains MLC ILP solver 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_MLC_ILP_H_ 25 | #define LCLIBRARY_MLC_ILP_H_ 26 | 27 | #include 28 | #include 29 | 30 | namespace lclibrary { 31 | 32 | class MLC_ILP : public MLC_Base { 33 | 34 | public: 35 | MLC_ILP(const std::shared_ptr g_in) : MLC_Base (g_in) {} 36 | virtual int SolveILP() = 0; 37 | virtual int GenerateSolutionGraph() = 0; 38 | 39 | int Solve() { 40 | SolveILP(); 41 | int exit_status = GenerateSolutionGraph(); 42 | if(exit_status == 0 or exit_status == 1) { 43 | for(const auto &sol_digraph:sol_digraph_list_) { 44 | sol_digraph->SetDepot(g_->GetDepotID()); 45 | sol_digraph->PrintNM(); 46 | std::cout << sol_digraph->GetCost() << std::endl; 47 | auto route = EulerTourGeneration(sol_digraph); 48 | if(sol_digraph->IsDepotSet()) { 49 | route.RotateToDepot(sol_digraph->GetVertexID(g_->GetDepot())); 50 | } 51 | route_list_.push_back(route); 52 | } 53 | } 54 | return exit_status; 55 | } 56 | 57 | double GetRouteCost() { 58 | double cost = 0; 59 | for(const auto &route:route_list_) { 60 | cost += route.GetCost(); 61 | } 62 | return cost; 63 | } 64 | }; 65 | 66 | } 67 | #endif /* LCLIBRARY_SLC_ILP_H_ */ 68 | -------------------------------------------------------------------------------- /include/lclibrary/mlc/mlc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * Top level header for MLC 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_MLC_H_ 25 | #define LCLIBRARY_MLC_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #endif /* LCLIBRARY_SLC_H_ */ 34 | -------------------------------------------------------------------------------- /include/lclibrary/mlc/mlc_base.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains base class for MLC 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_MLC_MLC_BASE_H_ 25 | #define LCLIBRARY_MLC_MLC_BASE_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | namespace lclibrary { 32 | 33 | class MLC_Base { 34 | 35 | protected: 36 | std::shared_ptr g_; 37 | std::vector > sol_digraph_list_; 38 | std::vector route_list_; 39 | bool use_2opt_ = true; 40 | 41 | public: 42 | MLC_Base(const std::shared_ptr g_in) : g_{g_in} {}; 43 | virtual int Solve() = 0; 44 | 45 | virtual bool CheckSolution() { 46 | for(const auto &sol_digraph:sol_digraph_list_) { 47 | if (IsBalancedDigraph(sol_digraph) == false) 48 | return false; 49 | ConnectedComponents cc(sol_digraph); 50 | cc.StronglyCCBalanced(); 51 | if(cc.GetNumCC() != 1) 52 | return false; 53 | } 54 | return true; 55 | } 56 | 57 | virtual ~MLC_Base() { 58 | } 59 | 60 | virtual void Use2Opt(const bool use) { 61 | use_2opt_ = use; 62 | } 63 | 64 | void Gnuplot(const std::string data_file_name, const std::string gnuplot_file_name, const std::string output_plot_file_name, bool plot_non_required) const { 65 | if(sol_digraph_list_.empty()) { 66 | std::cerr << "MLC not solved\n"; 67 | return; 68 | } 69 | GnuplotMap(sol_digraph_list_, data_file_name, gnuplot_file_name, output_plot_file_name, plot_non_required); 70 | } 71 | 72 | /* void GenerateVideo(std::string video_dir, const size_t num_frames = 900) { */ 73 | /* VideoGenerator(sol_digraph_, &route_, video_dir, num_frames); */ 74 | /* } */ 75 | 76 | void GetRoutes(std::vector &routes) const{ 77 | routes = route_list_; 78 | } 79 | 80 | void WriteRouteEdgeData(const std::string file_name) const { 81 | for(size_t i = 0; i < route_list_.size(); ++i) { 82 | route_list_[i].WriteRouteEdgeData(file_name + std::to_string(i)); 83 | } 84 | } 85 | 86 | void WriteKML(const std::string file_name) const{ 87 | for(size_t i = 0; i < route_list_.size(); ++i) { 88 | route_list_[i].WriteKML(file_name + std::to_string(i) + ".kml"); 89 | } 90 | } 91 | 92 | void WriteGeoJSON(const std::string file_name, const std::string var_name = "graph_data") const { 93 | for(size_t i = 0; i < sol_digraph_list_.size(); ++i) { 94 | WriteGeoJSON_All(sol_digraph_list_[i], file_name + std::to_string(i) + ".json", var_name); 95 | } 96 | } 97 | 98 | void WriteKMLReverse(const std::string file_name) const{ 99 | for(size_t i = 0; i < route_list_.size(); ++i) { 100 | route_list_[i].WriteKMLReverse(file_name + "_reverse_" + std::to_string(i) + ".kml"); 101 | } 102 | } 103 | void WriteRouteData(const std::string file_name) const{ 104 | for(size_t i = 0; i < route_list_.size(); ++i) { 105 | route_list_[i].WriteRouteData(file_name + std::to_string(i)); 106 | } 107 | } 108 | 109 | void GetSolDigraphList(std::vector > &list) const{ 110 | list.clear(); 111 | for(const auto &g:sol_digraph_list_) { 112 | list.push_back(g); 113 | } 114 | } 115 | 116 | double GetRouteCost() const { 117 | double total_cost = 0; 118 | for(const auto &route:route_list_) { 119 | total_cost += route.GetCost(); 120 | } 121 | return total_cost; 122 | } 123 | 124 | size_t GetNumOfRoutes() const { 125 | return route_list_.size(); 126 | } 127 | 128 | size_t GetTotalNumTurns() const { 129 | size_t num_turns = 0; 130 | for(const auto &route:route_list_) { 131 | num_turns += route.GetNumTurns(); 132 | } 133 | return num_turns; 134 | 135 | } 136 | 137 | void WriteWaypointsRoutes(std::string filename) const { 138 | for(size_t i = 0; i < route_list_.size(); ++i) { 139 | route_list_[i].WriteWayPoints(filename + std::to_string(i)); 140 | } 141 | } 142 | 143 | int RouteOutput (const Config &config) const { 144 | std::string sol_dir = config.sol_dir; 145 | if(not std::filesystem::exists(sol_dir)) { 146 | std::filesystem::create_directory(sol_dir); 147 | } 148 | config.WriteConfig(sol_dir + "config.yaml"); 149 | std::string filename_prepend = sol_dir + config.problem + "_" + config.solver_mlc + "_"; 150 | if(config.route_output.plot) { 151 | std::string plot_dir = sol_dir + "/plot/"; 152 | std::filesystem::create_directory(plot_dir); 153 | std::string gnuplot_filename = plot_dir + "/plot.gp"; 154 | std::string plot_filename = filename_prepend + "route"; 155 | 156 | Gnuplot(plot_dir + "/plot_data", gnuplot_filename, plot_filename, true); 157 | auto gnuplot_status = std::system(("gnuplot " + gnuplot_filename).c_str()); 158 | std::filesystem::remove_all(plot_dir); 159 | if(gnuplot_status != 0) { 160 | std::cerr << "gnuplot failed\n"; 161 | return kFail; 162 | } 163 | } 164 | 165 | if(config.route_output.kml) { 166 | WriteKML(filename_prepend + "route"); 167 | } 168 | 169 | if(config.route_output.data) { 170 | WriteRouteData(filename_prepend + "route"); 171 | } 172 | 173 | if(config.route_output.edge_data) { 174 | WriteRouteEdgeData(filename_prepend + "route_edges"); 175 | } 176 | 177 | if(config.route_output.geojson) { 178 | WriteGeoJSON(filename_prepend + "route"); 179 | } 180 | 181 | return kSuccess; 182 | } 183 | 184 | virtual double GetObjBound() {return 0;} 185 | 186 | }; 187 | 188 | } 189 | #endif /* LCLIBRARY_MLC_MLC_BASE_H_ */ 190 | -------------------------------------------------------------------------------- /include/lclibrary/slc/cpp.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains algorithm for the Chinese Postman Problem (CPP) 4 | * 5 | * TODO: Add route improvement functions 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_SLC_CPP_H_ 25 | #define LCLIBRARY_SLC_CPP_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | namespace lclibrary { 35 | 36 | class SLC_CPP : public SLC_Base{ 37 | std::shared_ptr apsp_; 38 | std::vector vertex_degree_list_; 39 | 40 | public: 41 | SLC_CPP(std::shared_ptr g_in) : SLC_Base (g_in){ 42 | apsp_ = std::make_shared(g_); 43 | apsp_->APSP_Deadheading(); 44 | sol_digraph_ = std::make_shared (*g_); 45 | } 46 | 47 | int Solve() { 48 | ComputeVertexDegree(g_, vertex_degree_list_); 49 | size_t num_odd_vertices = std::count_if (vertex_degree_list_.begin(), vertex_degree_list_.end(), [](int i) {return ((i%2) == 1);}); 50 | if(num_odd_vertices > 0) { 51 | std::vector matching_edges; 52 | ComputeMatching(vertex_degree_list_, apsp_, matching_edges); 53 | sol_digraph_->AddEdge(matching_edges); 54 | } 55 | return GenerateTour(); 56 | } 57 | 58 | bool GenerateTour() { 59 | route_ = EulerTourGeneration(sol_digraph_, kUndirectedGraph); 60 | route_.RouteImprovement(); 61 | if(route_.CheckRoute() == kFail) 62 | return kFail; 63 | sol_digraph_->ClearAllEdges(); 64 | std::vector edge_list; 65 | route_.GenerateEdgeList(edge_list); 66 | std::cout << "Route size: " << edge_list.size() << std::endl; 67 | if(sol_digraph_->AddEdge(edge_list) == kFail) 68 | return kFail; 69 | std::cout << "Route cost: " << route_.GetCost() << std::endl; 70 | return kSuccess; 71 | } 72 | 73 | }; 74 | 75 | } 76 | #endif /* LCLIBRARY_SLC_CPP_HPP_ */ 77 | -------------------------------------------------------------------------------- /include/lclibrary/slc/ilp_base.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains the base class for SLC ILP solver 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_SLC_ILP_H_ 25 | #define LCLIBRARY_SLC_ILP_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | namespace lclibrary { 32 | 33 | class SLC_ILP : public SLC_Base { 34 | 35 | public: 36 | SLC_ILP(std::shared_ptr g_in) : SLC_Base (g_in) {} 37 | virtual int SolveILP() = 0; 38 | virtual int GenerateSolutionGraph() = 0; 39 | 40 | int Solve() { 41 | SolveILP(); 42 | int exit_status = GenerateSolutionGraph(); 43 | if(exit_status == 0 or exit_status == 1) { 44 | sol_digraph_->PrintNM(); 45 | route_ = EulerTourGeneration(sol_digraph_); 46 | 47 | if(g_->IsDepotSet()) { 48 | route_.RotateToDepot(g_->GetVertexID(g_->GetDepot())); 49 | sol_digraph_->SetDepot(g_->GetDepotID()); 50 | } 51 | 52 | std::cout << sol_digraph_->GetCost() << std::endl; 53 | } 54 | return exit_status; 55 | } 56 | 57 | double GetRouteCost() { 58 | return route_.GetCost(); 59 | } 60 | }; 61 | 62 | } 63 | #endif /* LCLIBRARY_SLC_ILP_H_ */ 64 | -------------------------------------------------------------------------------- /include/lclibrary/slc/ilp_glpk.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains SLC ILP formulation solved using GLPK 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_SLC_ILP_GLPK_H_ 25 | #define LCLIBRARY_SLC_ILP_GLPK_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | namespace lclibrary { 33 | 34 | class SLC_ILP_glpk:public SLC_ILP { 35 | size_t n_, m_, m_nr_; 36 | size_t num_of_variables_; 37 | size_t num_of_constraints_; 38 | int constraint_count_; 39 | std::vector vec_ia; 40 | std::vector vec_ja; 41 | std::vector vec_ar; 42 | int *ia_, *ja_; 43 | double *ar_; 44 | size_t coeff_count_; 45 | size_t number_of_coeff_; 46 | size_t depot_index_; 47 | double z_; 48 | 49 | glp_prob *ilp_; 50 | 51 | public: 52 | SLC_ILP_glpk(const std::shared_ptr ); 53 | ~SLC_ILP_glpk() { 54 | glp_delete_prob(ilp_); 55 | delete [] ia_; 56 | delete [] ja_; 57 | delete [] ar_; 58 | } 59 | 60 | void AddVars(); 61 | void AddRows(); 62 | void SymmetryConstraints(); 63 | void ServiceConstraints(); 64 | void AddConstraintElement(int, int, double); 65 | void TourCost(); 66 | void LoadConstraintMatrix(); 67 | void DepotFlow(); 68 | void FlowLimit(); 69 | void PrintSolution(const char *fname) { 70 | glp_write_mip(ilp_, fname); 71 | } 72 | void FlowConservation(); 73 | void AssignDepot(); 74 | void PrintFlowValues(); 75 | int SolveILP(); 76 | int GenerateSolutionGraph(); 77 | 78 | }; 79 | 80 | } 81 | #endif /* LCLIBRARY_SLC_ILP_GLPK_HPP_ */ 82 | -------------------------------------------------------------------------------- /include/lclibrary/slc/lp_beta3_glpk.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains SLC beta3 solver using GLPK 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | 25 | #ifndef LCLIBRARY_SLC_LP_BETA3_GLPK_H_ 26 | #define LCLIBRARY_SLC_LP_BETA3_GLPK_H_ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | namespace lclibrary { 37 | 38 | class SLC_LP_beta3_glpk:public SLC_LP { 39 | size_t n_, m_, m_nr_; 40 | size_t num_of_variables_; 41 | size_t num_of_constraints_; 42 | int constraint_count_; 43 | std::vector vec_ia; 44 | std::vector vec_ja; 45 | std::vector vec_ar; 46 | int *ia_, *ja_; 47 | double *ar_; 48 | size_t coeff_count_; 49 | size_t number_of_coeff_; 50 | size_t depot_index_; 51 | double z_; 52 | 53 | glp_prob * lp_; 54 | std::shared_ptr g_; 55 | 56 | public: 57 | SLC_LP_beta3_glpk(const std::shared_ptr ); 58 | ~SLC_LP_beta3_glpk() { 59 | glp_delete_prob(lp_); 60 | delete [] ia_; 61 | delete [] ja_; 62 | delete [] ar_; 63 | } 64 | 65 | void AddVars(); 66 | void AddRows(); 67 | void SymmetryConstraints(); 68 | void ServiceConstraints(); 69 | void AddConstraintElement(int, int, double); 70 | void TourCost(); 71 | void LoadConstraintMatrix(); 72 | int Solve(); 73 | void PrintSolution(const char *fname) { 74 | glp_write_mip(lp_, fname); 75 | } 76 | int GenerateSolutionGraph (std::shared_ptr &, std::shared_ptr &); 77 | 78 | }; 79 | 80 | } 81 | #endif /* LCLIBRARY_SLC_LP_BETA3_GLPK_H_ */ 82 | -------------------------------------------------------------------------------- /include/lclibrary/slc/lp_glpk.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains SLC LP solver using GLPK 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_SLC_LP_GLPK_H_ 25 | #define LCLIBRARY_SLC_LP_GLPK_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | namespace lclibrary { 35 | 36 | class SLC_LP_glpk : public SLC_LP { 37 | size_t n_, m_, m_nr_; 38 | size_t num_of_variables_; 39 | size_t num_of_constraints_; 40 | int constraint_count_; 41 | std::vector vec_ia; 42 | std::vector vec_ja; 43 | std::vector vec_ar; 44 | int *ia_, *ja_; 45 | double *ar_; 46 | size_t coeff_count_; 47 | size_t number_of_coeff_; 48 | size_t depot_index_; 49 | double z_; 50 | 51 | glp_prob * lp_; 52 | std::shared_ptr g_; 53 | 54 | public: 55 | SLC_LP_glpk(const std::shared_ptr ); 56 | ~SLC_LP_glpk() { 57 | glp_delete_prob(lp_); 58 | delete [] ia_; 59 | delete [] ja_; 60 | delete [] ar_; 61 | } 62 | 63 | bool NearZero(double x) { 64 | if (std::abs(x) < 1e-10) 65 | return true; 66 | else 67 | return false; 68 | } 69 | void AddVars(); 70 | void AddRows(); 71 | void SymmetryConstraints(); 72 | void ServiceConstraints(); 73 | void AddConstraintElement(int, int, double); 74 | void TourCost(); 75 | void LoadConstraintMatrix(); 76 | int Solve(); 77 | void PrintSolution(const char *fname) { 78 | glp_write_mip(lp_, fname); 79 | } 80 | int GenerateSolutionGraph(std::shared_ptr &, std::shared_ptr &); 81 | 82 | }; 83 | 84 | } 85 | #endif /* LCLIBRARY_SLC_LP_GLPK_H_ */ 86 | -------------------------------------------------------------------------------- /include/lclibrary/slc/rpp_3by2.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains Frederickson's 3/2-approximation algorithm for the Rural Postman Problem (RPP) 4 | * 5 | * TODO: Add route improvement calls 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_SLC_RPP_H_ 25 | #define LCLIBRARY_SLC_RPP_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | namespace lclibrary { 38 | 39 | struct MSTEdge { 40 | double cost; 41 | size_t u; 42 | size_t v; 43 | 44 | MSTEdge() : cost{kDoubleMax}, u{kNIL}, v{kNIL} {} 45 | }; 46 | 47 | class SLC_RPP : public SLC_Base{ 48 | 49 | std::shared_ptr mst_; 50 | std::shared_ptr g_r_; 51 | std::shared_ptr apsp_; 52 | std::shared_ptr cc_; 53 | size_t num_cc_; 54 | std::vector vertex_degree_list_; 55 | std::vector> edges_; 56 | 57 | void GenerateMSTGraph() { 58 | edges_.resize(num_cc_, std::vector(num_cc_)); 59 | for(size_t i = 0; i < g_r_->GetN(); ++i) { 60 | auto u = cc_->GetVertexCC(i); 61 | size_t idx_i; 62 | g_->GetVertexIndex(g_r_->GetVertexID(i), idx_i); 63 | for(size_t j = 0; j < g_r_->GetN(); ++j) { 64 | auto v = cc_->GetVertexCC(j); 65 | size_t idx_j; 66 | g_->GetVertexIndex(g_r_->GetVertexID(j), idx_j); 67 | if(apsp_->GetCost(idx_i, idx_j) < edges_[u][v].cost) { 68 | edges_[u][v].cost = apsp_->GetCost(idx_i, idx_j); 69 | edges_[u][v].u = i; 70 | edges_[u][v].v = j; 71 | } 72 | } 73 | } 74 | std::vector vertex_list; 75 | std::vector edge_list; 76 | vertex_list.reserve(num_cc_); 77 | for(size_t i = 0; i < num_cc_; ++i) { 78 | Vertex v(i); 79 | vertex_list.push_back(v); 80 | for(size_t j = i + 1; j < num_cc_; ++j) { 81 | Edge e(i, j); 82 | e.SetCost(edges_[i][j].cost); 83 | edge_list.push_back(e); 84 | } 85 | } 86 | mst_ = std::make_shared(vertex_list, edge_list); 87 | } 88 | 89 | public: 90 | SLC_RPP(const std::shared_ptr &g_in) : SLC_Base (g_in) { 91 | apsp_ = std::make_shared (g_); 92 | apsp_->APSP_Deadheading(); 93 | std::vector vertex_list; 94 | for(size_t i = 0; i < g_->GetN(); ++i) { 95 | Vertex v; 96 | g_->GetVertexData(i, v); 97 | vertex_list.push_back(v); 98 | } 99 | std::vector edge_list; 100 | for(size_t i = 0; i < g_->GetM(); ++i) { 101 | Edge e; 102 | g_->GetEdgeData(i, e, kIsRequired); 103 | edge_list.push_back(e); 104 | } 105 | sol_digraph_ = std::make_shared (vertex_list, edge_list, edge_list.size(), 0); 106 | } 107 | 108 | int Solve() { 109 | GenerateRequiredGraph(g_, g_r_); 110 | g_r_->AddReverseEdges(); 111 | 112 | cc_ = std::make_shared (g_r_); 113 | cc_->StronglyCCBalanced(); 114 | num_cc_ = cc_->GetNumCC(); 115 | std::vector mst_edges; 116 | std::vector mst_edge_list; 117 | if(num_cc_ != 1) { 118 | GenerateMSTGraph(); 119 | MST_Prim(mst_, mst_edges); 120 | for(const auto &e:mst_edges) { 121 | size_t t, h; 122 | t = edges_[e.GetTailVertexID()][e.GetHeadVertexID()].u; 123 | h = edges_[e.GetTailVertexID()][e.GetHeadVertexID()].v; 124 | apsp_->GetPath(mst_edge_list, t, h); 125 | } 126 | sol_digraph_->AddEdge(mst_edge_list); 127 | } 128 | ComputeVertexDegree(sol_digraph_, vertex_degree_list_); 129 | size_t num_odd_vertices = std::count_if (vertex_degree_list_.begin(), vertex_degree_list_.end(), [](int i) {return ((i%2) == 1);}); 130 | if(num_odd_vertices > 0) { 131 | std::vector matching_edges; 132 | ComputeMatching(vertex_degree_list_, apsp_, matching_edges); 133 | sol_digraph_->AddEdge(matching_edges); 134 | } 135 | return GenerateTour(); 136 | } 137 | 138 | bool GenerateTour() { 139 | route_ = EulerTourGeneration(sol_digraph_, kUndirectedGraph); 140 | route_.SetGraphAPSP(g_, apsp_); 141 | route_.RouteImprovement(); 142 | if(route_.CheckRoute() == kFail) 143 | return kFail; 144 | sol_digraph_->ClearAllEdges(); 145 | std::vector edge_list; 146 | route_.GenerateEdgeList(edge_list); 147 | if(sol_digraph_->AddEdge(edge_list) == kFail) 148 | return kFail; 149 | return kSuccess; 150 | } 151 | 152 | }; 153 | 154 | } 155 | #endif /* LCLIBRARY_SLC_RPP_H_ */ 156 | -------------------------------------------------------------------------------- /include/lclibrary/slc/slc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * Top level header for SLC 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_SLC_H_ 25 | #define LCLIBRARY_SLC_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #ifdef LCLIBRARY_USE_GUROBI 40 | #include 41 | #endif /* LCLIBRARY_USE_GUROBI */ 42 | 43 | #endif /* LCLIBRARY_SLC_H_ */ 44 | -------------------------------------------------------------------------------- /include/lclibrary/slc/slc_base.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains base class for SLC 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_SLC_SLC_BASE_H_ 25 | #define LCLIBRARY_SLC_SLC_BASE_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | namespace lclibrary { 36 | 37 | class SLC_Base { 38 | 39 | protected: 40 | std::shared_ptr g_; 41 | std::shared_ptr sol_digraph_; 42 | Route route_; 43 | bool use_2opt_ = true; 44 | 45 | public: 46 | SLC_Base(const std::shared_ptr &g_in) : g_{g_in} {}; 47 | virtual int Solve() = 0; 48 | virtual bool CheckSolution() { 49 | if (!IsBalancedDigraph(sol_digraph_)) 50 | return false; 51 | ConnectedComponents cc(sol_digraph_); 52 | cc.StronglyCCBalanced(); 53 | if(cc.GetNumCC() != 1) 54 | return false; 55 | return true; 56 | } 57 | 58 | virtual void Use2Opt(const bool use) { 59 | use_2opt_ = use; 60 | } 61 | 62 | void Gnuplot( 63 | const std::string data_file_name, 64 | const std::string gnuplot_file_name, 65 | const std::string output_plot_file_name, 66 | bool plot_non_required) const { 67 | /* GnuplotMapArrows(sol_digraph_, data_file_name, gnuplot_file_name, output_plot_file_name, plot_non_required); */ 68 | GnuplotMap(sol_digraph_, data_file_name, gnuplot_file_name, output_plot_file_name, plot_non_required); 69 | } 70 | 71 | void GenerateVideo(std::string video_dir, const size_t num_frames = 900) const { 72 | VideoGenerator(sol_digraph_, &route_, video_dir, num_frames); 73 | } 74 | 75 | void GetRoute(Route &r) const { 76 | r = route_; 77 | } 78 | 79 | void WriteKML(const std::string file_name) const { 80 | route_.WriteKML(file_name); 81 | } 82 | 83 | void WriteKMLReverse(const std::string file_name) const { 84 | route_.WriteKMLReverse(file_name); 85 | } 86 | 87 | void WriteRouteData(const std::string file_name) const { 88 | route_.WriteRouteData(file_name); 89 | } 90 | 91 | void WriteRouteEdgeData(const std::string file_name) const { 92 | route_.WriteRouteEdgeData(file_name); 93 | } 94 | 95 | void WriteGeoJSON(const std::string file_name, const std::string var_name = "graph_data") const { 96 | WriteGeoJSON_All(sol_digraph_, file_name, var_name); 97 | } 98 | 99 | void GetSolDigraph(Graph &digraph) const { 100 | digraph = *sol_digraph_; 101 | } 102 | 103 | double GetRouteCost() { 104 | return route_.GetCost(); 105 | } 106 | 107 | size_t GetNumLocalMoves() const { 108 | return route_.GetNumLocalMoves(); 109 | } 110 | 111 | virtual void GetComputationTimes(std::vector &comp_t) {} 112 | virtual void GetCosts(std::vector &costs) {} 113 | 114 | int RouteOutput (const Config &config) const { 115 | std::string sol_dir = config.sol_dir; 116 | if(not std::filesystem::exists(sol_dir)) { 117 | std::filesystem::create_directory(sol_dir); 118 | } 119 | 120 | config.WriteConfig(sol_dir + "config.yaml"); 121 | std::string filename_prepend = sol_dir + config.problem + "_" + config.solver_slc + "_"; 122 | if(config.route_output.plot) { 123 | std::string plot_dir = sol_dir + "/plot/"; 124 | std::filesystem::create_directory(plot_dir); 125 | std::string gnuplot_filename = plot_dir + "/plot.gp"; 126 | std::string plot_filename = filename_prepend + "route"; 127 | 128 | Gnuplot(plot_dir + "/plot_data", gnuplot_filename, plot_filename, true); 129 | auto gnuplot_status = std::system(("gnuplot " + gnuplot_filename).c_str()); 130 | std::filesystem::remove_all(plot_dir); 131 | if(gnuplot_status != 0) { 132 | std::cerr << "gnuplot failed\n"; 133 | return kFail; 134 | } 135 | } 136 | 137 | if(config.route_output.kml) { 138 | WriteKML(filename_prepend + "route.kml"); 139 | } 140 | 141 | if(config.route_output.data) { 142 | WriteRouteData(filename_prepend + "route"); 143 | } 144 | 145 | if(config.route_output.edge_data) { 146 | WriteRouteEdgeData(filename_prepend + "route_edges"); 147 | } 148 | 149 | if(config.route_output.geojson) { 150 | WriteGeoJSON(filename_prepend + "route.json"); 151 | } 152 | 153 | return kSuccess; 154 | } 155 | 156 | }; 157 | 158 | } 159 | #endif /* LCLIBRARY_SLC_SLC_BASE_H_ */ 160 | -------------------------------------------------------------------------------- /include/lclibrary/slc/slc_lp.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains SLC LP solver abstract class 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_SLC_LP_H_ 25 | #define LCLIBRARY_SLC_LP_H_ 26 | 27 | #include 28 | namespace lclibrary { 29 | 30 | class SLC_LP { 31 | 32 | public: 33 | virtual int Solve() = 0; 34 | virtual int GenerateSolutionGraph(std::shared_ptr &, std::shared_ptr &) = 0; 35 | virtual ~SLC_LP() {} 36 | 37 | }; 38 | 39 | } 40 | #endif /* LCLIBRARY_SLC_LP_H_ */ 41 | -------------------------------------------------------------------------------- /include/lclibrary/utils/convert_osm_json_graph.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains functions to convert OSM JSON to lclibrary format for vertices and edges 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_UTILS_CONVERT_OSM_JSON_GRAPH_H_ 25 | #define LCLIBRARY_UTILS_CONVERT_OSM_JSON_GRAPH_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | namespace lclibrary { 39 | 40 | using json = nlohmann::json; 41 | inline void OSMjsonGraph(const std::string &osm_filename, const std::string &node_filename, const std::string &edge_filename) { 42 | std::ifstream osm_file(osm_filename); 43 | std::ofstream node_file(node_filename); 44 | std::ofstream edge_file(edge_filename); 45 | json osm_data; 46 | osm_file >> osm_data; 47 | std::cout << osm_data["osm3s"]["copyright"] << std::endl; 48 | json elements = osm_data["elements"]; 49 | for(auto &e:elements) { 50 | if(e["type"] == "node") { 51 | node_file << e["id"] << " " << e["lat"] << " " << e["lon"] << std::endl; 52 | } 53 | else if(e["type"] == "way") { 54 | json nodes = e["nodes"]; 55 | size_t node_prev = nodes[0]; 56 | bool start_flag = false; 57 | for(auto &n:nodes) { 58 | if(start_flag == false) { 59 | start_flag = true; 60 | continue; 61 | } 62 | edge_file << node_prev << " " << n << std::endl; 63 | node_prev = n; 64 | } 65 | } 66 | else { 67 | std::cout << "Unhandled element type: " << e["type"] << std::endl; 68 | } 69 | } 70 | 71 | osm_file.close(); 72 | node_file.close(); 73 | edge_file.close(); 74 | } 75 | inline int OSMjsonGraph(const Config &config) { 76 | auto fn = config.filenames; 77 | auto dir = config.database.path + "/" + config.database.data_dir + "/"; 78 | if(not std::filesystem::exists(dir + fn.map_json)) { 79 | std::cerr << "JSON file " << dir + fn.map_json << " does not exist\n"; 80 | return 1; 81 | } 82 | OSMjsonGraph(dir + fn.map_json, dir + fn.nodes_ll, dir + fn.req_edges); 83 | LLAtoXY llaToXY(dir + fn.nodes_ll, dir + fn.nodes_data); 84 | std::shared_ptr G; 85 | lclibrary::CreateGraph(G, dir + fn.nodes_data, dir + fn.req_edges, lclibrary::kIsWithLLA, not lclibrary::kIsWithCost, true); 86 | G->ShiftOrigin(); 87 | WriteNodes(G, dir + fn.nodes_data, lclibrary::kIsWithLLA); 88 | if(config.add_pairwise_nonreq_edges) { 89 | /* AddCompleteNonRequiredEdges(G); */ 90 | AddReducedCompleteNonRequiredEdges(G); 91 | WriteNonRequiredEdges(G, dir + fn.nonreq_edges); 92 | } 93 | 94 | std::string info_filename = dir + "/" + config.database.data_dir + ".info"; 95 | WriteGraphInfo(G, info_filename); 96 | G->PrintNM(); 97 | return 0; 98 | } 99 | } 100 | 101 | #endif /* LCLIBRARY_UTILS_CONVERT_OSM_JSON_GRAPH_H_*/ 102 | -------------------------------------------------------------------------------- /include/lclibrary/utils/create_temp_dir.h: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * This file is part of the LineCoverage-library. 4 | * Functions to create temporary directory designed with help from 5 | * https://github.com/cirosantilli/linux-kernel-module-cheat/blob/9afe5355e90bbb6b6c636f871b6eb461a957b0ea/userland/cpp/temporary_directory.cpp 6 | * 7 | * TODO: 8 | * 9 | * @author Saurav Agarwal 10 | * @contact sagarw10@uncc.edu 11 | * @contact agr.saurav1@gmail.com 12 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 13 | * 14 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 15 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 16 | * 17 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 18 | * 19 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 20 | * 21 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 22 | * 23 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 24 | */ 25 | 26 | #ifndef LCLIBRARY_UTILS_CREATE_TEMP_DIR_H_ 27 | #define LCLIBRARY_UTILS_CREATE_TEMP_DIR_H_ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | std::filesystem::path CreateTempDir(unsigned long long max_tries = 100) { 38 | auto tmp_dir = std::filesystem::temp_directory_path(); 39 | unsigned long long i = 0; 40 | std::random_device dev; 41 | std::mt19937 prng(dev()); 42 | std::uniform_int_distribution rand(0); 43 | std::filesystem::path path; 44 | while (true) { 45 | std::stringstream ss; 46 | ss << std::hex << rand(prng); 47 | path = tmp_dir / ss.str(); 48 | // true if the directory was created. 49 | if (std::filesystem::create_directory(path)) { 50 | break; 51 | } 52 | if (i == max_tries) { 53 | throw std::runtime_error("could not find non-existing directory"); 54 | } 55 | i++; 56 | } 57 | return path; 58 | } 59 | 60 | #endif /* LCLIBRARY_UTILS_CREATE_TEMP_DIR_H_ */ 61 | -------------------------------------------------------------------------------- /include/lclibrary/utils/edge_cost_travel_time.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * @author Saurav Agarwal 3 | * @contact sagarw10@uncc.edu 4 | */ 5 | 6 | /** 7 | * This file is part of the LineCoverage-library. 8 | * The file contains class for travel time as Edge cost 9 | * Considers wind conditions to generate asymmetric costs 10 | * 11 | * TODO: 12 | * 13 | * @author Saurav Agarwal 14 | * @contact sagarw10@uncc.edu 15 | * @contact agr.saurav1@gmail.com 16 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 17 | * 18 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 19 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 20 | * 21 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 22 | * 23 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 24 | * 25 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 26 | * 27 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 28 | */ 29 | 30 | #ifndef LCLIBRARY_UTILS_EDGE_TRAVELTIME_H_ 31 | #define LCLIBRARY_UTILS_EDGE_TRAVELTIME_H_ 32 | 33 | #include 34 | 35 | namespace lclibrary { 36 | class EdgeCost_TravelTime:public EdgeCost { 37 | 38 | double service_speed_; 39 | double deadheading_speed_; 40 | double wind_speed_; 41 | double wind_direction_; 42 | 43 | public: 44 | 45 | EdgeCost_TravelTime(const double s, const double d, const double w_s, const double w_d) : service_speed_{s}, deadheading_speed_{d}, wind_speed_{w_s}, wind_direction_{w_d} {} 46 | 47 | int ComputeServiceCost(const Edge &e, double &cost, double &cost_rev) const { 48 | const Vertex *t, *h; 49 | e.GetVertices(t, h); 50 | if(t == nullptr or h == nullptr) 51 | return 1; 52 | auto t_xy = t->GetXY(); 53 | auto h_xy = h->GetXY(); 54 | cost = ComputeTravelTime(t_xy, h_xy, service_speed_); 55 | cost_rev = ComputeTravelTime(h_xy, t_xy, service_speed_); 56 | return 0; 57 | 58 | } 59 | 60 | int ComputeDeadheadCost(const Edge &e, double &cost, double &cost_rev) const { 61 | const Vertex *t, *h; 62 | e.GetVertices(t, h); 63 | if(t == nullptr or h == nullptr) 64 | return 1; 65 | auto t_xy = t->GetXY(); 66 | auto h_xy = h->GetXY(); 67 | cost = ComputeTravelTime(t_xy, h_xy, deadheading_speed_); 68 | cost_rev = ComputeTravelTime(h_xy, t_xy, deadheading_speed_); 69 | return 0; 70 | 71 | } 72 | 73 | double ComputeTravelTime(const Vec2d t_xy, const Vec2d h_xy, const double vel) const { 74 | double d, tht; 75 | t_xy.DistTht(h_xy, d, tht); 76 | if (std::abs(d) < 1e-10) 77 | return 0; 78 | Vec2d wind_vec (wind_speed_ * cos(wind_direction_), wind_speed_ * sin(wind_direction_)); 79 | auto travel_vec = t_xy.TravelVec(h_xy); 80 | double cos_phi = 0; 81 | wind_vec.CosAngle(travel_vec, cos_phi); 82 | double bBy2 = -wind_speed_ * cos_phi; 83 | double c = wind_speed_ * wind_speed_ - vel * vel; 84 | double g = -bBy2 + std::sqrt(bBy2 * bBy2 - c); 85 | return d/g; 86 | } 87 | 88 | }; 89 | 90 | } 91 | 92 | #endif /* LCLIBRARY_UTILS_EDGE_TRAVELTIME_H_ */ 93 | -------------------------------------------------------------------------------- /include/lclibrary/utils/edge_cost_with_turns.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains class for edge cost with turn costs 4 | * The travel time is computed as a cubic trajectory with the given velocity as the max velocity 5 | * Turn cost is computed as cubic trajectory with given angular velocity as the max angular velocity 6 | * 7 | * TODO: This is an incomplete implementation 8 | * 9 | * @author Saurav Agarwal 10 | * @contact sagarw10@uncc.edu 11 | * @contact agr.saurav1@gmail.com 12 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 13 | * 14 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 15 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 16 | * 17 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 18 | * 19 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 20 | * 21 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 22 | * 23 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 24 | */ 25 | 26 | #ifndef LCLIBRARY_UTILS_EDGE_TURNS_HPP_ 27 | #define LCLIBRARY_UTILS_EDGE_TURNS_HPP_ 28 | 29 | #include 30 | 31 | namespace lclibrary { 32 | class EdgeCost_Turns:public EdgeCost { 33 | 34 | double service_speed_; 35 | double deadheading_speed_; 36 | double asym_speed_; 37 | double max_velocity_; 38 | double max_angular_velocity_; 39 | 40 | public: 41 | 42 | EdgeCost_Turns(const double s, const double d, const double a_s, const double max_vel, const double max_omega) : service_speed_{s}, deadheading_speed_{d}, asym_speed_{a_s}, max_velocity_{max_vel}, max_angular_velocity_{max_omega} {} 43 | 44 | int ComputeServiceCost(const Edge &e, double &cost, double &cost_rev) { 45 | const Vertex *t, *h; 46 | e.GetVertices(t, h); 47 | if(t == nullptr or h == nullptr) 48 | return 1; 49 | auto t_xy = t->GetXY(); 50 | auto h_xy = h->GetXY(); 51 | double true_service_speed, true_reverse_service_speed; 52 | 53 | if(h_xy.x > t_xy.x or h_xy.y > t_xy.y) { 54 | true_service_speed = service_speed_ + asym_speed_; 55 | true_reverse_service_speed = service_speed_ - asym_speed_; 56 | } 57 | else { 58 | true_service_speed = service_speed_ - asym_speed_; 59 | true_reverse_service_speed = service_speed_ + asym_speed_; 60 | } 61 | 62 | if (e.IsSemiCircular()) { 63 | auto arc = e.GetCircularArc(); 64 | double arc_length = arc.arc_length; 65 | cost = 3.*arc_length/true_service_speed; 66 | cost_rev = 3.*arc_length/true_reverse_service_speed; 67 | return 0; 68 | } 69 | cost = ComputeTravelTime(t_xy, h_xy, true_service_speed); 70 | cost_rev = ComputeTravelTime(h_xy, t_xy, true_reverse_service_speed); 71 | return 0; 72 | 73 | } 74 | 75 | int ComputeDeadheadCost(const Edge &e, double &cost, double &cost_rev) { 76 | const Vertex *t, *h; 77 | e.GetVertices(t, h); 78 | if(t == nullptr or h == nullptr) 79 | return 1; 80 | auto t_xy = t->GetXY(); 81 | auto h_xy = h->GetXY(); 82 | cost = ComputeTravelTime(t_xy, h_xy, deadheading_speed_); 83 | cost_rev = ComputeTravelTime(h_xy, t_xy, deadheading_speed_); 84 | return 0; 85 | 86 | } 87 | 88 | double ComputeTravelTime(const Vec2d t_xy, const Vec2d h_xy, const double vel) { 89 | auto d = t_xy.Dist(h_xy); 90 | if (std::abs(d) < 1e-10) 91 | return 0; 92 | return 3.*d/vel; 93 | } 94 | 95 | int GetTurnCost(const Edge &e1, const Edge &e2, double &cost, bool rev1 = false, bool rev2 = false) { 96 | const Vertex *t, *h; 97 | e1.GetVertices(t, h); 98 | if(t == nullptr or h == nullptr) 99 | return 1; 100 | auto t1_xy = t->GetXY(); 101 | auto h1_xy = h->GetXY(); 102 | if(rev1) 103 | std::swap(t1_xy, h1_xy); 104 | auto d1 = t1_xy.Dist(h1_xy); 105 | e2.GetVertices(t, h); 106 | if(t == nullptr or h == nullptr) 107 | return 1; 108 | auto t2_xy = t->GetXY(); 109 | auto h2_xy = h->GetXY(); 110 | if(rev2) 111 | std::swap(t2_xy, h2_xy); 112 | auto d2 = t2_xy.Dist(h2_xy); 113 | if(!IsNearZero(h1_xy.x - t2_xy.x) and !IsNearZero(h1_xy.y - t2_xy.y)) 114 | return 1; 115 | 116 | if(IsNearZero(d1) or IsNearZero(d2)) 117 | return 1; 118 | 119 | auto vec1 = t1_xy.TravelVec(h1_xy); 120 | auto vec2 = t2_xy.TravelVec(h2_xy); 121 | if(e1.IsSemiCircular()) { 122 | auto arc = e1.GetCircularArc(); 123 | auto vec1a = vec1; 124 | vec1a.x = 2 * (h1_xy.x - arc.center.x); 125 | vec1a.y = 2 * (h1_xy.y - arc.center.y); 126 | if(vec1a.Dot(vec1) < 0){ 127 | vec1a.x = -vec1a.x; vec1a.y = -vec1a.y; 128 | } 129 | vec1 = vec1a; 130 | } 131 | if(e2.IsSemiCircular()) { 132 | auto arc = e2.GetCircularArc(); 133 | auto vec2a = vec2; 134 | vec2a.x = 2 * (t2_xy.x - arc.center.x); 135 | vec2a.y = 2 * (t2_xy.y - arc.center.y); 136 | if(vec2a.Dot(vec2) < 0){ 137 | vec2a.x = -vec2a.x; vec2a.y = -vec2a.y; 138 | } 139 | vec2 = vec2a; 140 | } 141 | double inner_product = vec1.x * vec2.x + vec1.y * vec2.y; 142 | double angle = std::acos(inner_product/(d1 * d2)); 143 | return 3*angle/max_angular_velocity_; 144 | } 145 | 146 | }; 147 | 148 | } 149 | 150 | #endif /* LCLIBRARY_UTILS_EDGE_TURNS_HPP_ */ 151 | -------------------------------------------------------------------------------- /include/lclibrary/utils/plot_graph.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains functins for plotting using Gnuplot 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_UTILS_PLOTGRAPH_H_ 25 | #define LCLIBRARY_UTILS_PLOTGRAPH_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | namespace lclibrary { 36 | 37 | void PlotDataRequiredEdges( 38 | const std::shared_ptr &, 39 | const std::string, 40 | std::string color = "1"); 41 | 42 | bool PlotDataNonRequiredEdges( 43 | const std::shared_ptr &, 44 | const std::string, 45 | std::string color = "2"); 46 | 47 | void PlotDataRequiredEdgesArrows( 48 | const std::shared_ptr &, 49 | const std::string, 50 | std::string color = "1"); 51 | 52 | bool PlotDataNonRequiredEdgesArrows( 53 | const std::shared_ptr &, 54 | const std::string, 55 | std::string color = "2"); 56 | 57 | void GnuplotMap( 58 | const std::shared_ptr &, 59 | const std::string, 60 | const std::string, 61 | const std::string, 62 | bool plot_non_required = false); 63 | 64 | void GnuplotMap( 65 | const std::vector > &, 66 | const std::string, 67 | const std::string, 68 | const std::string, 69 | bool plot_non_required = false); 70 | 71 | void GnuplotMapArrows( 72 | const std::shared_ptr &, 73 | const std::string, 74 | const std::string, 75 | const std::string, 76 | bool plot_non_required = false); 77 | 78 | int PlotMap(const Config &); 79 | int PlotMap(const Config &, std::shared_ptr ); 80 | 81 | } /* lclibrary */ 82 | #endif /* LCLIBRARY_UTILS_PLOTGRAPH_H_*/ 83 | -------------------------------------------------------------------------------- /include/lclibrary/utils/utils.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * Top level header for utils 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_UTILS_H_ 25 | #define LCLIBRARY_UTILS_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #endif /* LCLIBRARY_UTILS_H_ */ 34 | -------------------------------------------------------------------------------- /include/lclibrary/utils/video_generator.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains functions to generate video frames using gnuplot 4 | * 5 | * TODO: The implementation is incomplete 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #ifndef LCLIBRARY_UTILS_VIDEOGENERATOR_H_ 25 | #define LCLIBRARY_UTILS_VIDEOGENERATOR_H_ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | namespace lclibrary { 36 | 37 | class VideoGenerator { 38 | std::shared_ptr g_; 39 | const Route *route_; 40 | std::string video_dir_; 41 | size_t num_frames_; 42 | int scale_order_; 43 | double scale_; 44 | double size_x_, size_y_; 45 | double minX_, maxX_, minY_, maxY_; 46 | std::string req_filename_, nreq_filename_, req_curr_filename_, nreq_curr_filename_, req_point_filename_, nreq_point_filename_; 47 | std::string frame_filename_, plot_filename_; 48 | 49 | public: 50 | VideoGenerator( 51 | std::shared_ptr g_in, 52 | const Route *r, 53 | std::string video_dir, 54 | size_t frames = 900) : 55 | g_{g_in}, 56 | route_{r}, 57 | video_dir_{video_dir}, 58 | num_frames_{frames} { 59 | 60 | if(video_dir_.back() != '/') 61 | video_dir_ += '/'; 62 | g_->GetLimits(minX_, maxX_, minY_, maxY_); 63 | double ratioXY = (maxY_ - minY_)/(maxX_ - minX_); 64 | size_x_ = 12; 65 | size_y_ = ratioXY * size_x_; 66 | scale_order_ = std::max((int(log10 (maxX_ - minX_))), (int(log10 (maxY_ - minY_)))); 67 | if(scale_order_ < 1) 68 | scale_order_ = 1; 69 | scale_ = std::pow(10, scale_order_); 70 | req_filename_ = video_dir_ + "req"; 71 | nreq_filename_ = video_dir_ + "nreq"; 72 | req_curr_filename_ = video_dir_ + "req_curr"; 73 | nreq_curr_filename_ = video_dir_ + "nreq_curr"; 74 | req_point_filename_ = video_dir_ + "req_point"; 75 | nreq_point_filename_ = video_dir_ + "nreq_point"; 76 | frame_filename_ = video_dir_ + "frames/f"; 77 | plot_filename_ = video_dir_ + "plot.gp"; 78 | GenerateVideo(); 79 | 80 | } 81 | void GnuplotMap( 82 | const std::string, 83 | bool curr_req = true, 84 | bool req = true, 85 | bool non_req = false, 86 | bool at_end = false); 87 | 88 | void GenerateVideo(); 89 | 90 | }; 91 | 92 | } /* lclibrary */ 93 | #endif /* LCLIBRARY_UTILS_VIDEOGENERATOR_H_*/ 94 | -------------------------------------------------------------------------------- /include/lclibrary/utils/write_geojson.h: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains function for writing GeoJSON file for graphs 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | 25 | #ifndef LCLIBRARY_UTILS_WRITEGEOJSON_H_ 26 | #define LCLIBRARY_UTILS_WRITEGEOJSON_H_ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | namespace lclibrary { 35 | 36 | inline void WriteGeoJSON_Req( 37 | const std::shared_ptr &g, 38 | const std::string filename, 39 | const std::string varName){ 40 | std::ofstream out_file (filename); 41 | out_file.precision(16); 42 | auto m = g->GetM(); 43 | out_file << "var "<< varName <<" = ["; 44 | for (size_t i = 0; i < m; ++i){ 45 | double tLLA[3], hLLA[3]; 46 | g->GetVertexLLAofEdge(i, tLLA, hLLA, kIsRequired); 47 | if (i == 0) 48 | out_file << "{\n"; 49 | else 50 | out_file << ", {\n"; 51 | out_file << "\t\"type\": \"Feature\",\n"; 52 | out_file << "\t\"req\": \"true\",\n"; 53 | out_file << "\t\"geometry\": {\n"; 54 | out_file << "\t\"type\": \"LineString\",\n"; 55 | out_file << "\t\"coordinates\": [["<< tLLA[1] <<", "< &g, 63 | const std::string filename, 64 | const std::string varName){ 65 | std::ofstream out_file (filename); 66 | out_file.precision(16); 67 | auto m = g->GetM(); auto m_nr = g->GetMnr(); 68 | bool init = false; 69 | out_file << "var "<< varName <<" = ["; 70 | for (size_t i = 0; i < m; ++i){ 71 | double tLLA[3], hLLA[3]; 72 | g->GetVertexLLAofEdge(i, tLLA, hLLA, kIsRequired); 73 | if (init == false) { 74 | out_file << "{\n"; 75 | init = true; 76 | } 77 | else { 78 | out_file << ", {\n"; 79 | } 80 | out_file << "\t\"type\": \"Feature\",\n"; 81 | out_file << "\t\"req\": \"true\",\n"; 82 | out_file << "\t\"geometry\": {\n"; 83 | out_file << "\t\"type\": \"LineString\",\n"; 84 | out_file << "\t\"coordinates\": [["<< tLLA[1] <<", "<GetVertexLLAofEdge(i, tLLA, hLLA, kIsNotRequired); 89 | if (init == false) { 90 | out_file << "{\n"; 91 | init = true; 92 | } 93 | else { 94 | out_file << ", {\n"; 95 | } 96 | out_file << "\t\"type\": \"Feature\",\n"; 97 | out_file << "\t\"req\": \"false\",\n"; 98 | out_file << "\t\"geometry\": {\n"; 99 | out_file << "\t\"type\": \"LineString\",\n"; 100 | out_file << "\t\"coordinates\": [["<< tLLA[1] <<", "< g) { 107 | if(config.writeGeoJSON.write == false) { 108 | std::cerr << "writeGeoJSON is off in config\n"; 109 | return kFail; 110 | } 111 | 112 | if(config.writeGeoJSON.non_req_edges) { 113 | WriteGeoJSON_All(g, config.database.dir + config.writeGeoJSON.filename, config.writeGeoJSON.var_name); 114 | } else { 115 | WriteGeoJSON_Req(g, config.database.dir + config.writeGeoJSON.filename, config.writeGeoJSON.var_name); 116 | } 117 | 118 | return kSuccess; 119 | } 120 | 121 | inline int WriteGeoJSON(const Config &config) { 122 | 123 | if(config.writeGeoJSON.write == false) { 124 | std::cerr << "writeGeoJSON is off in config\n"; 125 | return kFail; 126 | } 127 | 128 | std::shared_ptr g; 129 | if(GraphCreate (config, g) == kFail) { 130 | std::cerr << "Graph creation failed\n"; 131 | return kFail; 132 | } 133 | 134 | return WriteGeoJSON(config, g); 135 | } 136 | 137 | } /* lclibrary */ 138 | #endif /* LCLIBRARY_UTILS_WRITEGEOJSON_H_*/ 139 | -------------------------------------------------------------------------------- /lclibrary-config.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include ("${CMAKE_CURRENT_LIST_DIR}/lclibrary-targets.cmake") 4 | get_filename_component(lclibrary_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) 5 | set(LCLIBRARY_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@") 6 | set(LCLIBRARY_LIB_DIR "@CMAKE_INSTALL_FULL_LIBDIR@") 7 | set(LCLIBRARY_USE_GLPK "@LCLIBRARY_USE_GLPK@") 8 | set(LCLIBRARY_USE_GUROBI "@LCLIBRARY_USE_GUROBI@") 9 | set(LCLIBRARY_USE_LKH "@LCLIBRARY_USE_LKH@") 10 | set(LCLIBRARY_USE_GLKH "@LCLIBRARY_USE_GLKH@") 11 | -------------------------------------------------------------------------------- /lclibrary_config.h.in: -------------------------------------------------------------------------------- 1 | #define lclibrary_VERSION_MAJOR @lclibrary_VERSION_MAJOR@ 2 | #define lclibrary_VERSION_MINOR @lclibrary_VERSION_MINOR@ 3 | 4 | #cmakedefine LCLIBRARY_USE_GLPK 5 | #cmakedefine LCLIBRARY_USE_LKH 6 | #cmakedefine LCLIBRARY_USE_GLKH 7 | #cmakedefine LCLIBRARY_USE_GUROBI 8 | #cmakedefine LCLIBRARY_GLKH_PATH @LCLIBRARY_GLKH_PATH@ 9 | -------------------------------------------------------------------------------- /main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | project(lclibrary_main VERSION 1.0) 4 | 5 | set(CMAKE_CXX_STANDARD 17) 6 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 7 | 8 | include(GNUInstallDirs) 9 | 10 | find_package(yaml-cpp REQUIRED) 11 | find_package(lclibrary REQUIRED) 12 | 13 | if(LCLIBRARY_USE_GLPK) 14 | add_executable(slc ${CMAKE_CURRENT_SOURCE_DIR}/slc.cc) 15 | target_link_libraries(slc PUBLIC lclibrary glpk yaml-cpp) 16 | endif() 17 | if(LCLIBRARY_USE_GUROBI) 18 | link_directories($ENV{GUROBI_HOME}/lib) 19 | target_include_directories(slc PRIVATE $ENV{GUROBI_HOME}/include/) 20 | endif() 21 | install(TARGETS slc DESTINATION ${CMAKE_INSTALL_BINDIR}/) 22 | 23 | add_executable(mlc ${CMAKE_CURRENT_SOURCE_DIR}/mlc.cc) 24 | target_link_libraries(mlc PUBLIC lclibrary yaml-cpp) 25 | if(LCLIBRARY_USE_GUROBI) 26 | target_include_directories(mlc PRIVATE $ENV{GUROBI_HOME}/include/) 27 | endif() 28 | install(TARGETS mlc DESTINATION ${CMAKE_INSTALL_BINDIR}/) 29 | -------------------------------------------------------------------------------- /main/mlc.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * Solve MLC 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #ifdef LCLIBRARY_USE_GUROBI 35 | #include 36 | #endif 37 | 38 | int main (int argc, char **argv) { 39 | if(argc < 2) { 40 | std::cerr << "Usage: " << argv[0] << " g; 99 | 100 | if(lclibrary::GraphCreateWithCostFn(config, g)) { 101 | std::cerr << "Graph creation failed\n"; 102 | return 1; 103 | } 104 | g->PrintNM(); 105 | 106 | if(g->IsDepotSet() == false){ 107 | std::cerr << "Depot is not set. Depot is required for MLC\n"; 108 | return 1; 109 | } 110 | 111 | std::unique_ptr mlc_solver; 112 | 113 | if(config.solver_mlc == "ilp_gurobi") { 114 | #ifndef LCLIBRARY_USE_GUROBI 115 | std::cerr << "Gurobi not configured\n"; 116 | return 1; 117 | #endif 118 | } 119 | 120 | int solver_status = 1; 121 | if(config.solver_mlc == "mem" or config.solver_mlc == "ilp_gurobi") { 122 | mlc_solver = std::make_unique (g); 123 | } 124 | 125 | if(mlc_solver == nullptr) { 126 | std::cerr << "Invalid MLC solver\n"; 127 | return 1; 128 | } 129 | 130 | mlc_solver->Use2Opt(config.use_2opt); 131 | solver_status = mlc_solver->Solve(); 132 | 133 | if(config.solver_mlc == "ilp_gurobi") { 134 | std::vector route_list; 135 | mlc_solver->GetRoutes(route_list); 136 | mlc_solver.reset(nullptr); 137 | #ifdef LCLIBRARY_USE_GUROBI 138 | if(argc == 5) { 139 | mlc_solver = std::make_unique (g, route_list, config.ilp_time_limit, lower_bound); 140 | } else { 141 | mlc_solver = std::make_unique (g, route_list, config.ilp_time_limit); 142 | } 143 | solver_status = mlc_solver->Solve(); 144 | if(solver_status == 1) { 145 | std::cout << "ILP did not converge. Time limit reached\n"; 146 | } 147 | #endif 148 | } 149 | 150 | auto t_end_all = std::chrono::high_resolution_clock::now(); 151 | double elapsed_time_ms = std::chrono::duration(t_end_all - t_start_all).count(); 152 | 153 | std::cout << std::boolalpha; 154 | std::cout << config.problem << ": " << config.solver_mlc << ": solution connectivity check " << mlc_solver->CheckSolution() << std::endl; 155 | 156 | mlc_solver->RouteOutput(config); 157 | 158 | if(config.route_output.agg_results) { 159 | std::string result_filename = config.sol_dir + "results"; 160 | std::cout << result_filename << std::endl; 161 | std::ofstream result_file; 162 | if(config.route_output.append) { 163 | result_file.open(result_filename, std::ios_base::app); 164 | } else { 165 | result_file.open(result_filename); 166 | } 167 | 168 | result_file << g->GetN() << " " << g->GetM() << " " << g->GetMnr() << " " << g->GetLength() << " " << lclibrary::GetNumCCRequiredGraph(g); 169 | 170 | if(config.solver_mlc == "mem") { 171 | result_file << " " << mlc_solver->GetRouteCost() << " " << mlc_solver->GetNumOfRoutes() << " " << elapsed_time_ms << " " << solver_status << " " << mlc_solver->CheckSolution() << std::endl; 172 | } 173 | 174 | if(config.solver_mlc == "ilp_gurobi") { 175 | result_file << " " << mlc_solver->GetRouteCost() << " " << mlc_solver->GetNumOfRoutes() << " " << mlc_solver->GetObjBound() << " " << elapsed_time_ms << " " << solver_status << " " << mlc_solver->CheckSolution()<< std::endl; 176 | } 177 | 178 | result_file.close(); 179 | } 180 | 181 | } 182 | -------------------------------------------------------------------------------- /main/slc.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * Solve SLC 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | int main (int argc, char **argv) { 35 | if(argc < 2) { 36 | std::cerr << "Usage: " << argv[0] << " g; 81 | 82 | if(lclibrary::GraphCreateWithCostFn(config, g)) { 83 | std::cerr << "Graph creation failed\n"; 84 | return 1; 85 | } 86 | 87 | if(g->IsDepotSet()){ 88 | if(g->CheckDepotRequiredVertex() == lclibrary::kFail) { 89 | std::cerr << "Depot is not a required vertex\n"; 90 | return 1; 91 | } 92 | } 93 | 94 | std::unique_ptr slc_solver; 95 | 96 | if(config.solver_slc == "ilp_gurobi") { 97 | #ifndef LCLIBRARY_USE_GUROBI 98 | std::cerr << "Gurobi not configured\n"; 99 | return 1; 100 | #endif 101 | } 102 | 103 | int solver_status = 1; 104 | if(config.solver_slc == "beta2_atsp" or config.solver_slc == "ilp_gurobi") { 105 | slc_solver = std::make_unique (g); 106 | } else if(config.solver_slc == "beta2_gtsp"){ 107 | slc_solver = std::make_unique (g); 108 | } else if(config.solver_slc == "beta3_atsp"){ 109 | slc_solver = std::make_unique (g); 110 | } else if(config.solver_slc == "ilp_glpk") { 111 | slc_solver = std::make_unique (g); 112 | } 113 | 114 | if(slc_solver == nullptr) { 115 | std::cerr << "Invalid SLC solver\n"; 116 | return 1; 117 | } 118 | 119 | slc_solver->Use2Opt(config.use_2opt); 120 | solver_status = slc_solver->Solve(); 121 | 122 | if(config.solver_slc == "ilp_gurobi") { 123 | std::string ws_file = config.database.dir + "/gurobi_warmstart"; 124 | slc_solver->WriteRouteData(ws_file); 125 | slc_solver.reset(nullptr); 126 | #ifdef LCLIBRARY_USE_GUROBI 127 | slc_solver = std::make_unique (g, ws_file, config.ilp_time_limit); 128 | solver_status = slc_solver->Solve(); 129 | if(solver_status == 1) { 130 | std::cout << "ILP did not converge. Time limit reached\n"; 131 | } 132 | #endif 133 | std::filesystem::remove(ws_file); 134 | } 135 | 136 | auto t_end_all = std::chrono::high_resolution_clock::now(); 137 | double time_all = std::chrono::duration(t_end_all-t_start_all).count(); 138 | double elapsed_time_ms = std::chrono::duration(t_end_all - t_start_all).count(); 139 | 140 | 141 | std::cout << std::boolalpha; 142 | std::cout << config.problem << ": " << config.solver_slc << ": solution connectivity check " << slc_solver->CheckSolution() << std::endl; 143 | 144 | slc_solver->RouteOutput(config); 145 | 146 | if(config.route_output.agg_results) { 147 | std::string result_filename = config.sol_dir + "results"; 148 | std::cout << result_filename << std::endl; 149 | std::ofstream result_file; 150 | if(config.route_output.append) { 151 | result_file.open(result_filename, std::ios_base::app); 152 | } else { 153 | result_file.open(result_filename); 154 | } 155 | 156 | result_file << g->GetN() << " " << g->GetM() << " " << g->GetMnr() << " " << g->GetLength() << " " << lclibrary::GetNumCCRequiredGraph(g); 157 | 158 | if(config.solver_slc == "beta2_atsp" or config.solver_slc == "beta2_gtsp" or config.solver_slc == "beta3_atsp") { 159 | std::vector comp_t; 160 | std::vector costs; 161 | slc_solver->GetComputationTimes(comp_t); 162 | slc_solver->GetCosts(costs); 163 | result_file << " " << config.use_2opt << " " << slc_solver->GetNumLocalMoves() << " " << comp_t[0] << " " << comp_t[1] << " " << comp_t[2] << " " << comp_t[3] << " " << time_all; 164 | result_file << " " << costs[0] << " " << costs[1] << std::endl; 165 | } 166 | 167 | if(config.solver_slc == "ilp_gurobi" or config.solver_slc == "ilp_glpk") { 168 | result_file << " " << slc_solver->GetRouteCost() << " " << elapsed_time_ms << " " << solver_status << " " << slc_solver->CheckSolution() << std::endl; 169 | } 170 | 171 | result_file.close(); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | project(py_lclibrary VERSION 1.0) 4 | 5 | set(CMAKE_CXX_STANDARD 17) 6 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 7 | 8 | include(GNUInstallDirs) 9 | 10 | find_package(Python COMPONENTS Interpreter Development REQUIRED) 11 | 12 | message("Installing for python version: ${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}") 13 | 14 | find_package(lclibrary REQUIRED) 15 | find_package(Boost COMPONENTS system python numpy REQUIRED) 16 | 17 | Python_add_library(py_lclibrary ${PROJECT_SOURCE_DIR}/src/slc.cc) 18 | 19 | target_compile_options(py_lclibrary PRIVATE -O3 -Wall -pedantic) 20 | 21 | target_link_libraries(py_lclibrary PUBLIC lclibrary ${Boost_LIBRARIES} ${Python_LIRARIES} glpk) 22 | target_include_directories(py_lclibrary PUBLIC ${Boost_INCLUDE_DIRS} ${Python_INCLUDE_DIRS}) 23 | 24 | install(TARGETS py_lclibrary LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) 25 | 26 | install (FILES ${PROJECT_SOURCE_DIR}/rpp_3by2.py 27 | DESTINATION "${CMAKE_INSTALL_BINDIR}" PERMISSIONS 28 | OWNER_WRITE OWNER_READ OWNER_EXECUTE 29 | GROUP_WRITE GROUP_READ GROUP_EXECUTE) 30 | -------------------------------------------------------------------------------- /python/rpp_3by2.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import sys 3 | import numpy as np 4 | 5 | path = Path(__file__) 6 | path_lib = path.parent.parent.joinpath('lib') 7 | path_lib_abs = str(path_lib.resolve()) 8 | sys.path.insert(1, path_lib_abs) 9 | 10 | import py_lclibrary 11 | 12 | dt = np.dtype('int32') 13 | vertex_ids = np.array([5, 1, 2, 4], dt) 14 | 15 | 16 | edges_tail_ids = np.array([5, 1, 2], dt) 17 | edges_head_ids = np.array([2, 4, 1], dt) 18 | edges_req = np.array([True, True, False], np.dtype(bool)) 19 | edges_costs = np.array([10, 12.5, 8]) 20 | 21 | 22 | route_edges = py_lclibrary.SolveRPP(vertex_ids, edges_tail_ids, edges_head_ids, edges_req, edges_costs) 23 | print(type(route_edges)) 24 | print(route_edges.size) 25 | print(route_edges.dtype) 26 | print(route_edges) 27 | -------------------------------------------------------------------------------- /python/src/slc.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * Python wrapper for Vertex class in include/lclibrary/core/vertex.h 4 | * 5 | * @author Saurav Agarwal 6 | * @contact sagarw10@uncc.edu 7 | * @contact agr.saurav1@gmail.com 8 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 9 | * 10 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 11 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 12 | * 13 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 14 | * 15 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 16 | * 17 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 18 | * 19 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | using namespace boost::python; 34 | namespace b_np = boost::python::numpy; 35 | 36 | void VertexVecFromBnpArray(b_np::ndarray const &np_vertex_ids, std::vector &vertex_list) { 37 | int *np_vertex_ids_ptr = reinterpret_cast(np_vertex_ids.get_data()); 38 | int num_vertices = np_vertex_ids.shape(0); 39 | vertex_list.reserve(num_vertices); 40 | for(int i = 0; i < num_vertices; ++i) { 41 | vertex_list.push_back(lclibrary::Vertex(np_vertex_ids_ptr[i])); 42 | } 43 | } 44 | 45 | void EdgeVecFromBnpArray(b_np::ndarray const &edges_tail, b_np::ndarray const &edges_head, b_np::ndarray const &edges_req, b_np::ndarray const &edges_cost, std::vector &edge_list) { 46 | int* edges_tail_ptr = reinterpret_cast(edges_tail.get_data()); 47 | int* edges_head_ptr = reinterpret_cast(edges_head.get_data()); 48 | bool* edges_req_ptr = reinterpret_cast(edges_req.get_data()); 49 | double* edges_cost_ptr = reinterpret_cast(edges_cost.get_data()); 50 | int num_edges = edges_cost.shape(0); 51 | edge_list.reserve(num_edges); 52 | for(int i = 0; i < num_edges; ++i) { 53 | edge_list.push_back(lclibrary::Edge(edges_tail_ptr[i], edges_head_ptr[i], edges_req_ptr[i])); 54 | edge_list.back().SetCosts(edges_cost_ptr[i]); 55 | } 56 | } 57 | 58 | b_np::ndarray SolveRPP(b_np::ndarray const &vertex_ids, b_np::ndarray const &edges_tail, b_np::ndarray const &edges_head, b_np::ndarray const &edges_req, b_np::ndarray const &edges_cost) { 59 | std::vector vertices; 60 | std::vector edge_list; 61 | VertexVecFromBnpArray(vertex_ids, vertices); 62 | EdgeVecFromBnpArray(edges_tail, edges_head, edges_req, edges_cost, edge_list); 63 | auto graph = std::make_shared (vertices, edge_list); 64 | lclibrary::SLC_RPP slc_rpp(graph); 65 | slc_rpp.Solve(); 66 | lclibrary::Route route; 67 | slc_rpp.GetRoute(route); 68 | boost::python::tuple shape = boost::python::make_tuple(route.GetRouteLength(), 3); 69 | b_np::dtype dtype = b_np::dtype::get_builtin(); 70 | b_np::ndarray np_edges = b_np::zeros(shape, dtype); 71 | shape = boost::python::make_tuple(route.GetRouteLength()); 72 | dtype = b_np::dtype::get_builtin(); 73 | int edge_count = 0; 74 | for(auto route_it = route.GetRouteStart(); route_it != route.GetRouteEnd(); ++route_it) { 75 | auto e = *route_it; 76 | np_edges[edge_count][0] = int(e.GetTailVertexID()); 77 | np_edges[edge_count][1] = int(e.GetHeadVertexID()); 78 | np_edges[edge_count][2] = int(e.GetReq()); 79 | ++edge_count; 80 | } 81 | return np_edges; 82 | 83 | } 84 | 85 | b_np::ndarray SolveSLC_Beta2_atsp(b_np::ndarray const &vertex_ids, b_np::ndarray const &edges_tail, b_np::ndarray const &edges_head, b_np::ndarray const &edges_req, b_np::ndarray const &edges_cost) { 86 | std::vector vertices; 87 | std::vector edge_list; 88 | VertexVecFromBnpArray(vertex_ids, vertices); 89 | EdgeVecFromBnpArray(edges_tail, edges_head, edges_req, edges_cost, edge_list); 90 | auto graph = std::make_shared (vertices, edge_list); 91 | lclibrary::SLC_Beta2ATSP slc_solver(graph); 92 | slc_solver.Use2Opt(false); 93 | auto solver_status = slc_solver.Solve(); 94 | if(solver_status) { 95 | std::cerr << "SLC Beta2 ATSP failed\n"; 96 | } 97 | lclibrary::Route route; 98 | slc_solver.GetRoute(route); 99 | boost::python::tuple shape = boost::python::make_tuple(route.GetRouteLength(), 3); 100 | b_np::dtype dtype = b_np::dtype::get_builtin(); 101 | b_np::ndarray np_edges = b_np::zeros(shape, dtype); 102 | shape = boost::python::make_tuple(route.GetRouteLength()); 103 | dtype = b_np::dtype::get_builtin(); 104 | int edge_count = 0; 105 | for(auto route_it = route.GetRouteStart(); route_it != route.GetRouteEnd(); ++route_it) { 106 | auto e = *route_it; 107 | np_edges[edge_count][0] = int(e.GetTailVertexID()); 108 | np_edges[edge_count][1] = int(e.GetHeadVertexID()); 109 | np_edges[edge_count][2] = int(e.GetReq()); 110 | ++edge_count; 111 | } 112 | return np_edges; 113 | 114 | } 115 | 116 | BOOST_PYTHON_MODULE(py_lclibrary) { 117 | Py_Initialize(); 118 | b_np::initialize(); 119 | class_ ("Vertex", init ()) 120 | .def("GetID", &lclibrary::Vertex::GetID) 121 | .def("SetID", &lclibrary::Vertex::SetID); 122 | 123 | class_ ("Edge", init ()) 124 | .def("GetCost", &lclibrary::Edge::GetCost) 125 | .def("SetCosts", &lclibrary::Edge::SetCosts) 126 | .def("GetTailVertexID", &lclibrary::Edge::GetTailVertexID) 127 | .def("GetHeadVertexID", &lclibrary::Edge::GetHeadVertexID); 128 | 129 | def("SolveRPP", &SolveRPP); 130 | } 131 | -------------------------------------------------------------------------------- /src/core/adjacency_list_generation.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains functions to generate adjacency list of graph 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #include 25 | 26 | namespace lclibrary { 27 | 28 | int Graph::AdjacencyListGeneration() { 29 | for (auto &v:vertex_list_) { 30 | v->ClearAdjacentList(); 31 | } 32 | for(auto const &e:required_edge_list_) { 33 | Vertex *v1, *v2; 34 | if(GetVertex(e->GetTailVertexID(), v1) or GetVertex(e->GetHeadVertexID(), v2)) { 35 | std::cerr << "Edge list error" << std::endl; 36 | return kFail; 37 | } 38 | v1->AddEdge(e); 39 | } 40 | for(auto const &e:non_required_edge_list_) { 41 | Vertex *v1, *v2; 42 | if(GetVertex(e->GetTailVertexID(), v1) or GetVertex(e->GetHeadVertexID(), v2)) { 43 | std::cerr << "Edge list error" << std::endl; 44 | return kFail; 45 | } 46 | v1->AddEdge(e); 47 | } 48 | return kSuccess; 49 | } 50 | 51 | } // namespace lclibrary 52 | -------------------------------------------------------------------------------- /src/core/graph_file_parser.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains file parsers to create graphs 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #include 25 | 26 | namespace lclibrary { 27 | 28 | void VertexParser (std::vector &vertex_list, std::ifstream &vertex_list_infile, const bool is_with_lla) { 29 | size_t vertex_ID; 30 | double lat, lng, alt, x, y; 31 | if (is_with_lla) { 32 | while(vertex_list_infile >> vertex_ID >> x >> y >> lat >> lng >> alt) { 33 | Vertex new_vertex(vertex_ID); 34 | new_vertex.SetLLA(lat, lng, alt); 35 | new_vertex.SetXY(x, y); 36 | vertex_list.push_back(new_vertex); 37 | } 38 | } 39 | else { 40 | while(vertex_list_infile >> vertex_ID >> x >> y) { 41 | Vertex new_vertex(vertex_ID); 42 | new_vertex.SetXY(x, y); 43 | vertex_list.push_back(new_vertex); 44 | } 45 | } 46 | } 47 | 48 | void FileParser (std::shared_ptr &g, std::ifstream &vertex_list_infile, std::ifstream &edge_list_infile, const bool is_with_lla, const bool is_with_cost, bool filter_vertices) { 49 | std::vector vertex_list; 50 | VertexParser (vertex_list, vertex_list_infile, is_with_lla); 51 | std::vector edge_list; 52 | size_t m = 0, m_nr = 0; 53 | EdgeParser (edge_list, edge_list_infile, is_with_cost, m); 54 | if(filter_vertices == true) { 55 | std::vector filtered_vertex_list; 56 | for(const auto &v:vertex_list) { 57 | bool found = false; 58 | for(const auto &e:edge_list) { 59 | if(v.GetID() == e.GetTailVertexID() or v.GetID() == e.GetHeadVertexID()) { 60 | found = true; 61 | break; 62 | } 63 | } 64 | if(found == true) { 65 | filtered_vertex_list.push_back(v); 66 | } 67 | } 68 | vertex_list = filtered_vertex_list; 69 | } 70 | g = std::make_shared (vertex_list, edge_list, m, m_nr); 71 | } 72 | 73 | void FileParser (std::shared_ptr &g, std::ifstream &vertex_list_infile, std::ifstream &req_edge_list_infile, std::ifstream &non_req_edge_list_infile, const bool is_with_lla, const bool is_with_cost, const bool filter_vertices) { 74 | std::vector vertex_list; 75 | VertexParser (vertex_list, vertex_list_infile, is_with_lla); 76 | std::vector edge_list; 77 | size_t m = 0, m_nr = 0; 78 | EdgeParser (edge_list, req_edge_list_infile, non_req_edge_list_infile, is_with_cost, m, m_nr); 79 | g = std::make_shared (vertex_list, edge_list, m, m_nr); 80 | } 81 | 82 | void EdgeParser (std::vector &edge_list, std::ifstream &edge_list_infile, const bool is_with_cost, size_t &m) { 83 | size_t tail_v_ID, head_v_ID; 84 | if (is_with_cost) { 85 | double service_cost, service_cost_rev, deadhead_cost, deadhead_cost_rev; 86 | while(edge_list_infile >> tail_v_ID >> head_v_ID >> service_cost >> service_cost_rev >> deadhead_cost >> deadhead_cost_rev){ 87 | edge_list.push_back(Edge(tail_v_ID, head_v_ID, true, service_cost, service_cost_rev, deadhead_cost, deadhead_cost_rev)); 88 | ++m; 89 | } 90 | } 91 | else { 92 | while(edge_list_infile >> tail_v_ID >> head_v_ID){ 93 | edge_list.push_back(Edge(tail_v_ID, head_v_ID, true)); 94 | ++m; 95 | } 96 | } 97 | } 98 | 99 | void EdgeParser (std::vector &edge_list, std::ifstream &req_edge_list_infile, std::ifstream &non_req_edge_list_infile, const bool is_with_cost, size_t &m, size_t &m_nr) { 100 | size_t tail_v_ID, head_v_ID; 101 | EdgeParser (edge_list, req_edge_list_infile, is_with_cost, m); 102 | if (is_with_cost) { 103 | double deadhead_cost, deadhead_cost_rev; 104 | while(non_req_edge_list_infile >> tail_v_ID >> head_v_ID >> deadhead_cost >> deadhead_cost_rev){ 105 | edge_list.push_back(Edge(tail_v_ID, head_v_ID, false, deadhead_cost, deadhead_cost_rev)); 106 | ++m_nr; 107 | } 108 | } 109 | else { 110 | while(non_req_edge_list_infile >> tail_v_ID >> head_v_ID){ 111 | edge_list.push_back(Edge(tail_v_ID, head_v_ID, false)); 112 | ++m_nr; 113 | } 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/core/graph_io.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains functions for Graph IO 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #include 25 | 26 | namespace lclibrary { 27 | 28 | /*! Create graph with only required edges */ 29 | int CreateGraph( 30 | std::shared_ptr &g, 31 | const std::string &vertex_list_file_name, 32 | const std::string &edge_list_file_name, 33 | const bool is_with_lla, 34 | const bool is_with_cost, 35 | const bool filter_vertices){ 36 | 37 | std::ifstream vertex_list_infile (vertex_list_file_name); 38 | std::ifstream edge_list_infile (edge_list_file_name); 39 | 40 | if( !vertex_list_infile ) { 41 | std::cerr << "Cannot open " << vertex_list_file_name << std::endl; 42 | return kFail; 43 | } 44 | if( !edge_list_infile ) { 45 | std::cerr << "Cannot open " << edge_list_file_name << std::endl; 46 | return kFail; 47 | } 48 | 49 | FileParser(g, vertex_list_infile, edge_list_infile, is_with_lla, is_with_cost, filter_vertices); 50 | 51 | vertex_list_infile.close(); 52 | edge_list_infile.close(); 53 | return kSuccess; 54 | } 55 | 56 | /*! Create graph with required and non-required edges */ 57 | int CreateGraph( 58 | std::shared_ptr &g, 59 | const std::string &vertex_list_file_name, 60 | const std::string &req_edge_list_file_name, 61 | const std::string &non_req_edge_list_file_name, 62 | const bool is_with_lla, 63 | const bool is_with_cost){ 64 | 65 | std::ifstream vertex_list_infile (vertex_list_file_name); 66 | std::ifstream req_edge_list_infile (req_edge_list_file_name); 67 | std::ifstream non_req_edge_list_infile (non_req_edge_list_file_name); 68 | 69 | if( !vertex_list_infile ) { 70 | std::cerr << "Cannot open " << vertex_list_file_name << std::endl; 71 | return kFail; 72 | } 73 | if( !req_edge_list_infile ) { 74 | std::cerr << "Cannot open " << req_edge_list_file_name << std::endl; 75 | return kFail; 76 | } 77 | 78 | if( !non_req_edge_list_infile ) { 79 | std::cerr << "Cannot open " << non_req_edge_list_file_name << std::endl; 80 | return kFail; 81 | } 82 | FileParser(g, vertex_list_infile, req_edge_list_infile, non_req_edge_list_infile, is_with_lla, is_with_cost); 83 | 84 | vertex_list_infile.close(); 85 | req_edge_list_infile.close(); 86 | non_req_edge_list_infile.close(); 87 | return kSuccess; 88 | } 89 | 90 | /*! Write graph info */ 91 | void WriteGraphInfo (std::shared_ptr G, 92 | const std::string &filename) { 93 | std::ofstream info_file(filename); 94 | info_file << "No. of nodes: " << G->GetN() << std::endl; 95 | info_file << "No. of required edges: " << G->GetM() << std::endl; 96 | info_file << "No. of non-required edges: " << G->GetMnr() << std::endl; 97 | info_file << "Length of the network (m): " << G->GetLength() << std::endl; 98 | info_file << "No. of connected components in required graph: " << GetNumCCRequiredGraph(G); 99 | info_file.close(); 100 | } 101 | 102 | /*! Write node data to file */ 103 | void WriteNodes( 104 | std::shared_ptr g, 105 | const std::string filename, 106 | const bool is_with_lla) { 107 | 108 | std::ofstream out_file (filename); 109 | out_file.precision(16); 110 | double lla[3]; 111 | Vec2d xy; 112 | auto n = g->GetN(); 113 | for(size_t i = 0; i < n; ++i){ 114 | g->GetVertexXY(i, xy); 115 | if(is_with_lla) { 116 | g->GetVertexLLA(i, lla); 117 | out_file << g->GetVertexID(i) <<" "<< xy.x <<" " << xy.y <<" " << lla[0] <<" " << lla[1] <<" " << lla[2]<<"\n"; 118 | } 119 | else { 120 | out_file << g->GetVertexID(i) <<" "<< xy.x <<" " << xy.y <<"\n"; 121 | } 122 | } 123 | out_file.close(); 124 | } 125 | 126 | /*! Write edge data to file */ 127 | void WriteRequiredEdges(std::shared_ptr g, const std::string filename) { 128 | 129 | std::ofstream out_file (filename); 130 | out_file.precision(16); 131 | size_t m = g->GetM(); 132 | size_t t_ID, h_ID; 133 | for (size_t i = 0; i < m; ++i) { 134 | g->GetVerticesIDOfEdge(i, t_ID, h_ID); 135 | out_file << t_ID << " " << h_ID << " " << g->GetServiceCost(i)<< " " << g->GetReverseServiceCost(i) << " " << g->GetDeadheadCost(i) << " " << g->GetReverseDeadheadCost(i); 136 | out_file<<"\n"; 137 | } 138 | out_file.close(); 139 | } 140 | 141 | void WriteNonRequiredEdges(std::shared_ptr g, const std::string filename) { 142 | std::ofstream out_file (filename); 143 | out_file.precision(16); 144 | size_t m_nr = g->GetMnr(); 145 | size_t t_ID, h_ID; 146 | for (size_t i = 0; i < m_nr; ++i) { 147 | g->GetVerticesIDOfEdge(i, t_ID, h_ID, kIsNotRequired); 148 | out_file << t_ID << " " << h_ID << " " << g->GetDeadheadCost(i,kIsNotRequired)<< " " << g->GetReverseDeadheadCost(i,kIsNotRequired); 149 | out_file<<"\n"; 150 | } 151 | out_file.close(); 152 | } 153 | 154 | void DepotListParser(const std::string &depot_filename, std::vector &depot_ids) { 155 | std::ifstream in_file (depot_filename); 156 | size_t depot; 157 | while(in_file >> depot) { 158 | depot_ids.push_back(depot); 159 | } 160 | in_file.close(); 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /src/core/graph_utilities.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the LineCoverage-library. 3 | * The file contains utilities functions for graphs 4 | * 5 | * TODO: 6 | * 7 | * @author Saurav Agarwal 8 | * @contact sagarw10@uncc.edu 9 | * @contact agr.saurav1@gmail.com 10 | * Repository: https://github.com/UNCCharlotte-Robotics/LineCoverage-library 11 | * 12 | * Copyright (C) 2020--2022 University of North Carolina at Charlotte. 13 | * The LineCoverage-library is owned by the University of North Carolina at Charlotte and is protected by United States copyright laws and applicable international treaties and/or conventions. 14 | * 15 | * The LineCoverage-library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 16 | * 17 | * DISCLAIMER OF WARRANTIES: THE SOFTWARE IS PROVIDED "AS-IS" WITHOUT WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE OR OF NON-INFRINGEMENT. YOU BEAR ALL RISK RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE OR HARDWARE. 18 | * 19 | * SUPPORT AND MAINTENANCE: No support, installation, or training is provided. 20 | * 21 | * You should have received a copy of the GNU General Public License along with LineCoverage-library. If not, see . 22 | */ 23 | 24 | #include 25 | 26 | namespace lclibrary { 27 | 28 | void AddCompleteNonRequiredEdges(std::shared_ptr &G) { 29 | auto n = G->GetN(); 30 | size_t m_nr = n * (n - 1)/2; 31 | std::vector edge_list; 32 | edge_list.reserve(m_nr); 33 | for(size_t i = 0; i < n; ++i) { 34 | for (size_t j = i + 1; j < n; ++j) { 35 | Edge new_edge(G->GetVertexID(i), G->GetVertexID(j), false, 0, 0); 36 | edge_list.push_back(new_edge); 37 | } 38 | } 39 | G->AddEdge(edge_list, size_t(0), m_nr); 40 | } 41 | 42 | void AddReducedCompleteNonRequiredEdges(std::shared_ptr &G) { 43 | auto n = G->GetN(); 44 | auto m = G->GetM(); 45 | size_t m_nr = n * (n - 1)/2 - m; 46 | std::vector edge_list; 47 | edge_list.reserve(m_nr); 48 | for(size_t i = 0; i < n; ++i) { 49 | for (size_t j = i + 1; j < n; ++j) { 50 | bool existing = false; 51 | for(size_t k = 0; k < m; ++k) { 52 | size_t t, h; 53 | G->GetVerticesIndexOfEdge(k, t, h, kIsRequired); 54 | if((t == i and h == j) or (t == j and h == i)) { 55 | existing = true; 56 | break; 57 | } 58 | } 59 | if(existing == true) { 60 | continue; 61 | } 62 | Edge new_edge(G->GetVertexID(i), G->GetVertexID(j), false, 0, 0); 63 | edge_list.push_back(new_edge); 64 | } 65 | } 66 | G->AddEdge(edge_list, size_t(0), m_nr); 67 | } 68 | 69 | int ComputeAllEdgeCosts(std::shared_ptr &G, EdgeCost &edge_cost_computer) { 70 | double cost, cost_rev; 71 | size_t m = G->GetM(); 72 | for(size_t i = 0; i < m; ++i) { 73 | Edge e; 74 | G->GetEdgeData(i, e, true); 75 | if (edge_cost_computer.ComputeServiceCost(e, cost, cost_rev)) { 76 | std::cerr << "Error computing Edge Cost\n"; 77 | return kFail; 78 | } 79 | G->SetServiceCost(i, cost, cost_rev); 80 | if (edge_cost_computer.ComputeDeadheadCost(e, cost, cost_rev)) { 81 | std::cerr << "Error computing Edge Cost\n"; 82 | return kFail; 83 | } 84 | G->SetDeadheadCost(i, cost, cost_rev); 85 | } 86 | size_t m_nr = G->GetMnr(); 87 | for(size_t i = 0; i < m_nr; ++i) { 88 | Edge e; 89 | G->GetEdgeData(i, e, false); 90 | if (edge_cost_computer.ComputeDeadheadCost(e, cost, cost_rev)) { 91 | std::cerr << "Error computing Edge Cost\n"; 92 | return kFail; 93 | } 94 | G->SetDeadheadCost(i, cost, cost_rev, false); 95 | } 96 | return kSuccess; 97 | } 98 | 99 | } /* lclibrary */ 100 | -------------------------------------------------------------------------------- /utils/leaflet_geojson_viz/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Road Network Visualizer 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /utils/leaflet_geojson_viz/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0; 3 | margin: 0; 4 | } 5 | 6 | html, body, #map { 7 | height: 100%; 8 | width: 100%; 9 | } 10 | 11 | .leaflet-fade-anim .leaflet-tile,.leaflet-zoom-anim .leaflet-zoom-animated { will-change:auto !important; } 12 | 13 | .download-icon { 14 | background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDQzMy41IDQzMy41IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0MzMuNSA0MzMuNTsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxnIGlkPSJmaWxlLWRvd25sb2FkIj4KCQk8cGF0aCBkPSJNMzk1LjI1LDE1M2gtMTAyVjBoLTE1M3YxNTNoLTEwMmwxNzguNSwxNzguNUwzOTUuMjUsMTUzeiBNMzguMjUsMzgyLjV2NTFoMzU3di01MUgzOC4yNXoiIGZpbGw9IiMwMDAwMDAiLz4KCTwvZz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K); 15 | background-size: 16px 16px; 16 | background-repeat: no-repeat; 17 | background-position: center; 18 | cursor: pointer; 19 | } 20 | 21 | .leaflet-div-icon { 22 | background-color: #f4f4f4; 23 | border: 1px solid #666; 24 | border-radius: 50%; 25 | display: inline-block; 26 | } 27 | 28 | .leaflet-editing-icon { 29 | background-color: #f4f4f4; 30 | border: 1px solid #666; 31 | border-radius: 50%; 32 | display: inline-block; 33 | } 34 | -------------------------------------------------------------------------------- /utils/leaflet_osm_viz/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Road Network Visualizer 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /utils/leaflet_osm_viz/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0; 3 | margin: 0; 4 | } 5 | 6 | html, body, #map { 7 | height: 100%; 8 | width: 100%; 9 | } 10 | 11 | .leaflet-fade-anim .leaflet-tile,.leaflet-zoom-anim .leaflet-zoom-animated { will-change:auto !important; } 12 | 13 | .download-icon { 14 | background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDQzMy41IDQzMy41IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA0MzMuNSA0MzMuNTsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8Zz4KCTxnIGlkPSJmaWxlLWRvd25sb2FkIj4KCQk8cGF0aCBkPSJNMzk1LjI1LDE1M2gtMTAyVjBoLTE1M3YxNTNoLTEwMmwxNzguNSwxNzguNUwzOTUuMjUsMTUzeiBNMzguMjUsMzgyLjV2NTFoMzU3di01MUgzOC4yNXoiIGZpbGw9IiMwMDAwMDAiLz4KCTwvZz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K); 15 | background-size: 16px 16px; 16 | background-repeat: no-repeat; 17 | background-position: center; 18 | cursor: pointer; 19 | } 20 | 21 | .leaflet-div-icon { 22 | background-color: #f4f4f4; 23 | border: 1px solid #666; 24 | border-radius: 50%; 25 | display: inline-block; 26 | } 27 | 28 | .leaflet-editing-icon { 29 | background-color: #f4f4f4; 30 | border: 1px solid #666; 31 | border-radius: 50%; 32 | display: inline-block; 33 | } 34 | --------------------------------------------------------------------------------