这个是留学生作业,不会给任何人看源码的。
为了这个作业我把《算法导论》的 22章“图的基本算法”23章“最小生成树”24章“单源最短路径”25章“每对顶点间的最短路径”全部看了一边,光是理论就看了一周的时间(晚上看的啊)
主要内容:
1 城市之间的有向道路
2 两个城市之间的最短路径(经过的城市数量)
3 两个城市之间的最短路程(道路长度之和)
4 顺序遍历所有城市
5 从一个城市出发到另一个城市最短回路
6 自动跑完测试用例
7 打印城市和道路
完全是对着书上的伪代码实现,不得不承认,此书理论相当棒,伪代码超简单,给实现带来了相当的方便。
另一个简单单纯实现两定点见距离的:https://blog.csdn.net/weixin_40825228/article/details/80761343
头文件:
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <sstream>
#include <vector>
class AdjacencyMatrixGraph
{
public:
class Edge
{
friend std::istream& operator>>(std::istream& _is, Edge& _vertex);
public:
Edge(int _x, int _y, float _distance) :startIndex(_x), endIndex(_y), distance(_distance){}
Edge(int _x, int _y) :Edge(_x, _y, 0){}
Edge(void) :Edge(0, 0){}
public:
int startIndex;
int endIndex;
float distance;
};
class Vertex
{
public:
enum class Color { WHITE, GRAY, BLACK};
public:
Vertex() :index(-1),parent(-1), distance(0.0), color(Color::WHITE){}
Vertex(int _index) :index(_index), parent(-1), distance(0.0), color(Color::WHITE){}
public:
friend std::ostream& operator<<(std::ostream& _os, const Vertex& _vertex);
friend std::istream& operator>>(std::istream& _is, Vertex& _vertex);
friend bool operator == (const Vertex& _lhs, const Vertex& _rhs) { return _rhs.index == _lhs.index; }
public:
int index;
int parent;
float distance;
std::string airportCode;
std::string cityName;
public: //DFS
Color color;
int time_stated;
int time_finished;
};
public:
AdjacencyMatrixGraph();
~AdjacencyMatrixGraph();
public:
std::shared_ptr<Vertex>& GetVertex(int index);
std::shared_ptr<Vertex> GetVertex(const std::string& _code);
std::vector<std::shared_ptr<Vertex>> GetAllVertex(void) const;
const std::vector<std::vector<float>>& GetAdjacencyMatrix(void) const;
const std::vector<std::vector<int>>& GetAdjArray(void) const;
const std::vector<int>& GetAdjArray(int _index) const;
void AddVertex(const Vertex& _vertex);
void AddEdge(const Edge& _edge);
void Delete(const Edge& _edge);
float GetDistance(int _startIndex, int _endIndex) { return m_adjacencyMatrix[_startIndex][_endIndex]; }
size_t GetVertexCount(void) const;
private:
std::vector<std::vector<float>> m_adjacencyMatrix;
std::vector<std::vector<int>> m_adjList;
std::vector<std::shared_ptr<Vertex>> m_allVertex;
};
void LoadAirPortsFirst(const std::string& _filName, AdjacencyMatrixGraph& _graph);
void LoadFlightsSecond(const std::string& _filName, AdjacencyMatrixGraph& _graph);
void SaveRevisedFlightsData(const std::string& _filName, AdjacencyMatrixGraph& _graph);
void SaveRevisedAirportsData(const std::string& _filName, AdjacencyMatrixGraph& _graph);
void DeleteFlight(AdjacencyMatrixGraph& _graph, int _startIndex, int _endIndex);
void DeleteFlight(AdjacencyMatrixGraph& _graph, const std::string& _startCode, const std::string& _endCode);
void DeleteFlight(AdjacencyMatrixGraph& _graph);
void AddFlight(AdjacencyMatrixGraph& _graph);
void AddFlight(AdjacencyMatrixGraph& _graph, const std::string& _startCode, const std::string& _endCode, float distance);
void AddVertex(AdjacencyMatrixGraph& _graph);
void AddVertex(AdjacencyMatrixGraph& _graph, const std::string& _code, const std::string& _cityName);
void Relax(AdjacencyMatrixGraph& _graph, const AdjacencyMatrixGraph::Vertex& _u, AdjacencyMatrixGraph::Vertex& _v);
void RelaxByStep(AdjacencyMatrixGraph& _graph, const AdjacencyMatrixGraph::Vertex& _u, AdjacencyMatrixGraph::Vertex& _v);
void Dijkstra(AdjacencyMatrixGraph& _graph, const AdjacencyMatrixGraph::Vertex& _startVertex,
std::function<void(AdjacencyMatrixGraph& _graph, const AdjacencyMatrixGraph::Vertex& _u, AdjacencyMatrixGraph::Vertex& _v)>);
void FindCheapestRoundtrip(AdjacencyMatrixGraph& _graph);
void FindCheapestRoundtrip(AdjacencyMatrixGraph& _graph, const std::string& _startCode, const std::string& _endCode);
void PrintAirPortsAandFlightInfor(const AdjacencyMatrixGraph& _graph);
void PrintAirPortsAllVertexs(const AdjacencyMatrixGraph& _graph);
void PrintAirPortsAllFlights(const AdjacencyMatrixGraph& _graph);
void PrintOneAirPorts(const AdjacencyMatrixGraph& _graph, const std::string& _code);
std::pair<bool, std::list<int>> ExistCheapestFlight(AdjacencyMatrixGraph& _graph, const AdjacencyMatrixGraph::Vertex& _startVertex, const AdjacencyMatrixGraph::Vertex& _endVertex);
std::string CreatePathKey(const std::list<int>& _listIndex);
void PrintCheapestFlight(AdjacencyMatrixGraph& _graph, const AdjacencyMatrixGraph::Vertex& _startVertex, const AdjacencyMatrixGraph::Vertex& _endVertex);
void DepthFirstSearchVisit(AdjacencyMatrixGraph& _graph, AdjacencyMatrixGraph::Vertex& _u, int& _curTime, std::list<int>& _seq);
void DepthFirstSearch(AdjacencyMatrixGraph& _graph, const AdjacencyMatrixGraph::Vertex& _startVertex, std::list<int>& _seq);
main文件:
#include "AdjacencyMatrixGraph.h"
#include <iostream>
#include <string>
#include <map>
#include <list>
int main(int argc, char*argv[])
{
AdjacencyMatrixGraph graph;
try
{
LoadAirPortsFirst("P4Airports.txt", graph);
LoadFlightsSecond("P4Flights.txt", graph);
std::string menu;
while (true)
{
std::cout << "Choose your menu please:" << std::endl
<< "0. Display all airports and flights information" << std::endl
<< "1. Display one airport information" << std::endl
<< "2. Find a cheapest flight from one airport to another airport" << std::endl
<< "3. Add a flight from one airport to another airport" << std::endl
<< "4. Delete a flight from one airport to another airport" << std::endl
<< "5. Find a cheapest roundtrip from one airport to another airport" << std::endl
<< "6. Find a flight with fewest stops from one airport to another airport" << std::endl
//<< "7. Find all flights from one airport to another airport" << std::endl
<< "8. Find an order to visit all airports starting from an airport" << std::endl
<< "9. Add a new airport" << std::endl
<< "10. Run all test cases for developer(not user)" << std::endl
<< "Q. Exit and save data" << std::endl
;
std::cin >> menu;
if (menu == "Q" || menu == "q")
{
SaveRevisedFlightsData("P4FlightsRev1.txt", graph);
SaveRevisedAirportsData("P4AirportsRev1.txt", graph);
std::cout << "Thank you for your use. Bye!" << std::endl;
return 0;
}
else if (menu == "0")
{
PrintAirPortsAandFlightInfor(graph);
}
else if (menu == "1")
{
std::cout << "Input the 3-letter airport code:" << std::endl;
std::string code;
std::cin >> code;
PrintOneAirPorts(graph, code);
}
else if (menu == "2")
{
int size = graph.GetAllVertex().size();
std::cout << "Input the start airport[0-" << graph.GetAllVertex().size() << ")" << std::endl;
int start = 0;
std::cin >> start;
if (start < 0 || start >= size)
{
std::cout << "Invalid start airport !" << std::endl;
continue;
}
std::cout << "Input the end airport(differ from start)[0-" << graph.GetAllVertex().size() << ")" << std::endl;
int end = 2;
std::cin >> end;
if (end < 0 || end >= size || end == start)
{
std::cout << "Invalid end airport !" << std::endl;
continue;
}
Dijkstra(graph, start, Relax);
PrintCheapestFlight(graph, start, end);
}
else if (menu == "3")
{
AddFlight(graph);
}
else if (menu == "4")
{
DeleteFlight(graph);
}
else if (menu == "5")
{
FindCheapestRoundtrip(graph);
}
else if (menu == "6")
{
int size = graph.GetAllVertex().size();
std::cout << "Input the start airport[0-" << graph.GetAllVertex().size() << ")" << std::endl;
int start = 0;
std::cin >> start;
if (start < 0 || start >= size)
{
std::cout << "Invalid start airport !" << std::endl;
continue;
}
std::cout << "Input the end airport(differ from start)[0-" << graph.GetAllVertex().size() << ")" << std::endl;
int end = 2;
std::cin >> end;
if (end < 0 || end >= size || end == start)
{
std::cout << "Invalid end airport !" << std::endl;
continue;
}
Dijkstra(graph, start, RelaxByStep);
PrintCheapestFlight(graph, start, end);
}
else if (menu == "8")
{
std::string startCode, endCode;
std::cout << "Input the start airport code" << std::endl;
std::cin >> startCode;
auto start = graph.GetVertex(startCode);
if (graph.GetVertex(startCode) == nullptr)
{
std::cout << "Invalid input: "
<< "Check it and input it again please. " << std::endl;
continue;
}
auto startIndex = start->index;
std::list<int> visitSeq;
DepthFirstSearch(graph, *start, visitSeq);
if (visitSeq.size() < graph.GetAllVertex().size())
{
std::cout << "Unavailable! No order to visit all airports !\n";
continue;
}
std::cout << "Visit path from " << start->airportCode <<":\n";
for (auto itr = visitSeq.begin(); itr != visitSeq.end(); ++itr)
{
std::cout << "DepthFirstSearchVisit:" << *itr << std::endl;
}
std::cout << "\n";
}
else if (menu == "9")
{
AddVertex(graph);
}
else if (menu == "10")
{
std::cout << "Test case is start running....." << std::endl;
std::cout << "1. Run option 0" << std::endl;
PrintAirPortsAandFlightInfor(graph);
std::cout << "2. Display airport information for SFO" << std::endl;
PrintOneAirPorts(graph, "SFO");
std::cout << "3. Find the cheapest flight from LAX to JFK" << std::endl;
auto start = graph.GetVertex("LAX");
auto end = graph.GetVertex("JFK");
Dijkstra(graph, *start, Relax);
PrintCheapestFlight(graph, *start, *end);
std::cout << "4. Find the cheapest flight from JFK to LAX" << std::endl;
start = graph.GetVertex("JFK");
end = graph.GetVertex("LAX");
Dijkstra(graph, *start, Relax);
PrintCheapestFlight(graph, *start, *end);
std::cout << "5. Delete a flight between LAX and SFO" << std::endl;
DeleteFlight(graph, "LAX", "SFO");
PrintAirPortsAandFlightInfor(graph);
std::cout << "6. Add a flight between DFW and JFK for $200.00" << std::endl;
AddFlight(graph, "DFW", "JFK", 200);
PrintAirPortsAandFlightInfor(graph);
std::cout << "7. Find the cheapest roundtrip from LAX to JFK" << std::endl;
FindCheapestRoundtrip(graph, "LAX", "JFK");
std::cout << "8. Run option 0" << std::endl;
PrintAirPortsAandFlightInfor(graph);
std::cout << "9. Quit" << std::endl;
SaveRevisedFlightsData("P4FlightsRev1.txt", graph);
SaveRevisedAirportsData("P4AirportsRev1.txt", graph);
std::cout << "Thank you for your use. Bye!" << std::endl;
std::cout << "Test case is finished running ....." << std::endl;
return 0;
}
}
}
catch (std::exception e)
{
std::cout << "exception occurred["<<e.what()<<"]! main return." << std::endl;//there is some bug in this program
}
return 0;
}
实现和输出:
Choose your menu please:
0. Display all airports and flights information
1. Display one airport information
2. Find a cheapest flight from one airport to another airport
3. Add a flight from one airport to another airport
4. Delete a flight from one airport to another airport
5. Find a cheapest roundtrip from one airport to another airport
6. Find a flight with fewest stops from one airport to another airport
9. Add a new airport
10. Run all test cases for developer(not user)
Q. Exit and save data
10
Test case is start running.....
1. Run option 0
All airports in Graph:
0[airport]LAX [cityname]Los Angeles
1[airport]SFO [cityname]San Francisco
2[airport]DFW [cityname]Denver
3[airport]ORD [cityname]Chicago
4[airport]BOS [cityname]Boston
5[airport]JFK [cityname]New York
6[airport]MIA [cityname]Miami
7[airport]MSY [cityname]New Orlean
8[airport]SEA [cityname]Seatle
All flights in Graph:
0 1 2 3 4 5 6 7 8
0 0 0 189 0 0 0 0 0 200
1 79 0 0 0 0 0 0 0 0
2 199 99.99 0 0 0 0 0 0 0
3 0 0 50 0 179 0 0 0 0
4 0 0 0 149 0 99 0 0 0
5 0 0 0 99 0 0 49 220 0
6 0 0 0 0 0 0 0 50 0
7 190 0 109 0 0 0 0 0 0
8 0 0 0 179.5 0 0 0 0 0
2. Display airport information for SFO
1[airport]SFO [cityname]San Francisco
3. Find the cheapest flight from LAX to JFK
cheapest flight(0,5) = $657.5
cheapest flight(0,5) path:
0[airport]LAX [cityname]Los Angeles
8[airport]SEA [cityname]Seatle
3[airport]ORD [cityname]Chicago
4[airport]BOS [cityname]Boston
5[airport]JFK [cityname]New York
4. Find the cheapest flight from JFK to LAX
cheapest flight(5,0) = $289
cheapest flight(5,0) path:
5[airport]JFK [cityname]New York
6[airport]MIA [cityname]Miami
7[airport]MSY [cityname]New Orlean
0[airport]LAX [cityname]Los Angeles
5. Delete a flight between LAX and SFO
All airports in Graph:
0[airport]LAX [cityname]Los Angeles
1[airport]SFO [cityname]San Francisco
2[airport]DFW [cityname]Denver
3[airport]ORD [cityname]Chicago
4[airport]BOS [cityname]Boston
5[airport]JFK [cityname]New York
6[airport]MIA [cityname]Miami
7[airport]MSY [cityname]New Orlean
8[airport]SEA [cityname]Seatle
All flights in Graph:
0 1 2 3 4 5 6 7 8
0 0 0 189 0 0 0 0 0 200
1 79 0 0 0 0 0 0 0 0
2 199 99.99 0 0 0 0 0 0 0
3 0 0 50 0 179 0 0 0 0
4 0 0 0 149 0 99 0 0 0
5 0 0 0 99 0 0 49 220 0
6 0 0 0 0 0 0 0 50 0
7 190 0 109 0 0 0 0 0 0
8 0 0 0 179.5 0 0 0 0 0
6. Add a flight between DFW and JFK for $200.00
All airports in Graph:
0[airport]LAX [cityname]Los Angeles
1[airport]SFO [cityname]San Francisco
2[airport]DFW [cityname]Denver
3[airport]ORD [cityname]Chicago
4[airport]BOS [cityname]Boston
5[airport]JFK [cityname]New York
6[airport]MIA [cityname]Miami
7[airport]MSY [cityname]New Orlean
8[airport]SEA [cityname]Seatle
All flights in Graph:
0 1 2 3 4 5 6 7 8
0 0 0 189 0 0 0 0 0 200
1 79 0 0 0 0 0 0 0 0
2 199 99.99 0 0 0 200 0 0 0
3 0 0 50 0 179 0 0 0 0
4 0 0 0 149 0 99 0 0 0
5 0 0 0 99 0 0 49 220 0
6 0 0 0 0 0 0 0 50 0
7 190 0 109 0 0 0 0 0 0
8 0 0 0 179.5 0 0 0 0 0
7. Find the cheapest roundtrip from LAX to JFK
cheapest flight(0,5) = $389
cheapest flight(0,5) path:
0[airport]LAX [cityname]Los Angeles
2[airport]DFW [cityname]Denver
5[airport]JFK [cityname]New York
cheapest flight(5,0) = $289
cheapest flight(5,0) path:
5[airport]JFK [cityname]New York
6[airport]MIA [cityname]Miami
7[airport]MSY [cityname]New Orlean
0[airport]LAX [cityname]Los Angeles
cheapest total cost = $678
8. Run option 0
All airports in Graph:
0[airport]LAX [cityname]Los Angeles
1[airport]SFO [cityname]San Francisco
2[airport]DFW [cityname]Denver
3[airport]ORD [cityname]Chicago
4[airport]BOS [cityname]Boston
5[airport]JFK [cityname]New York
6[airport]MIA [cityname]Miami
7[airport]MSY [cityname]New Orlean
8[airport]SEA [cityname]Seatle
All flights in Graph:
0 1 2 3 4 5 6 7 8
0 0 0 189 0 0 0 0 0 200
1 79 0 0 0 0 0 0 0 0
2 199 99.99 0 0 0 200 0 0 0
3 0 0 50 0 179 0 0 0 0
4 0 0 0 149 0 99 0 0 0
5 0 0 0 99 0 0 49 220 0
6 0 0 0 0 0 0 0 50 0
7 190 0 109 0 0 0 0 0 0
8 0 0 0 179.5 0 0 0 0 0
9. Quit
SaveRevisedFlightsData to P4FlightsRev1.txt finished!
SaveRevisedAirportsData to P4AirportsRev1.txt finished!
Thank you for your use. Bye!
Test case is finished running .....
请按任意键继续. . .