/*** * 13. Kurier ma za zadanie zawieść towar do klientów w różnych lokalizacjach i powrócić do miejsca, z którego wyjechał. Kurier musi odwiedzić każdego klienta raz i tylko raz. Należy znaleźć zamkniętą najkrótszą drogę, która umożliwia odwiedzenie wszystkich klientów. W pliku wejściowym zapisane są długości dróg pomiędzy miastami. Drogi zapisane są w następujący sposób: ( - : ). Niektóre drogi nie są symetryczne, tzn. jest pewna różnica między drogą tam a z powrotem. Zapis ( -> : ), oznacza długość drogi jednokierunkowej od klienta C do klienta D. Poszczególne drogi są rozdzielone przecinkami. Nie jest podana liczba dróg. Jeżeli nie jest możliwe wyznaczenie drogi, program zgłasza odpowiedni komunikat. Przykładowy plik wejściowy: (1 - 2 : 4.5), (4 -> 3 : 4.5), (4 - 2 : 0.4) W pliku wynikowym należy zapisać drogę kuriera (kolejność odwiedzania klientów i długość drogi). Program uruchamiany jest z linii poleceń z potrzebnymi przełącznikami, natomiast uruchomienie programu bez parametrów powoduje wypisanie krótkiej instrukcji 1 2 3 4 1 4.5 2 4.5 0.4 3 4.5 4 0.4 **/ #include #include #include #include "include/cxxopts.hpp" #include "include/types.hpp" #include #include #include #include #include double nieskończoność=std::numeric_limits::max(); using namespace std; cxxopts::Options options("Kurier", "Program rozwiązujący problem kuriera"); /* * * Parsujemy A, B, rodzaj korelacji , dystans * * */ typedef std::map> mapa; mapa mapaOdległości; /* * @brief Funkcja czyszcząca stringi z niepotrzebnych znaków */ void czyscStringa( string &str, char* znakiDoCzyszczenia ) { for ( unsigned int i = 0; i < strlen(znakiDoCzyszczenia); ++i ) { str.erase( remove(str.begin(), str.end(), znakiDoCzyszczenia[i]), str.end() ); } } void dijkstruj(mapa doDijkstrnięcia){ for(auto miasto : doDijkstrnięcia) { // doDijkstrnięcia.rbegin() } } /** * @brief Funkcja parsująca dane wejściowe. * * @details Funkcja pobiera dane wejściowe z przekazanej ścieżki do pliku. Plik zawiera długości dróg pomiędzy poszczególnymi miastami w formacie ( - : ). * * @param inputFile Ścieżka do pliku wejściowego * * @return iterator pliku */ void parseInput(string inputFile) { ifstream file(inputFile); std::string token,miastoA,miastoB,dystans,rodzajRelacji; while(std::getline(file, token, ',')) { czyscStringa(token, "(:)"); istringstream tokenstream(token); tokenstream >> miastoA >> rodzajRelacji >> miastoB >> dystans; if (rodzajRelacji.compare("-")==0) { // Jeśli drugie miasto zaczyna się od znaku '-', to znaczy, że jest to droga dwukierunkowa. // Dodajemy odległość do mapy dla obu kierunków. mapaOdległości[miastoA][miastoB] = stod(dystans); mapaOdległości[miastoB][miastoA] = stod(dystans); } else if (rodzajRelacji.compare("->")==0) { // Jeśli drugie miasto zaczyna się od znaku '>', to znaczy, że jest to droga jednokierunkowa. // Dodajemy odległość tylko w jednym kierunku. mapaOdległości[miastoA][miastoB] = stod(dystans); mapaOdległości[miastoB][miastoA] = nieskończoność; } } } /** * @brief Główna funkcja. * */ int main (int argc, char *argv[]) { options.add_options() ("d,debug", "Włącza tryb debugowania") // a bool parameter ("h,help", "Pokazuje pomoc") // a bool parameter ("i,input", "Nazwa pliku wejściowego", cxxopts::value()) ("o,output", "Nazwa pliku wyjściowego", cxxopts::value()) ("v,verbose", "Pokazuje tok działania programu", cxxopts::value()->default_value("false")); auto result = options.parse(argc, argv); // Jeżeli przełącznik -h jest ustawiony albo nie podano argumetów, wyświetla pomoc. if (result.count("help") || argc == 1) { std::cout << options.help() << std::endl; exit(0); } bool debug = result["debug"].as(); string plikWejsciowy; string plikWyjsciowy; if (result.count("input") && result.count("output")) { plikWejsciowy = result["input"].as(); parseInput(plikWejsciowy); dijkstruj(mapaOdległości); plikWyjsciowy = result["output"].as(); } else { std::cout << std::endl << "Błąd - nie podano wymaganych parametrów" << std::endl << std::endl << std::endl << options.help() << std::endl; exit(3); } if (debug == true) { for (int i = 0; i < argc; i++) { std::cout << argv[i] << std::endl; } } exit(0); }