数据结构与算法:图的邻接矩阵邻接表表示:最短路径求解 大作业

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ClamReason/article/details/80544080

为了这个作业我把《算法导论》的 22章“图的基本算法”23章“最小生成树”24章“单源最短路径”25章“每对顶点间的最短路径”全部看了一边,光是理论就看了一周的时间(晚上看的啊)

主要内容:

1 城市之间的有向道路

2 两个城市之间的最短路径(经过的城市数量)

3 两个城市之间的最短路程(道路长度之和)

4 顺序遍历所有城市

5 从一个城市出发到另一个城市最短回路

6 自动跑完测试用例

7 打印城市和道路

百度云

完全是对着书上的伪代码实现,不得不承认,此书理论相当棒,伪代码超简单,给实现带来了相当的方便。

扫描二维码关注公众号,回复: 3055087 查看本文章

头文件:

#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 .....

请按任意键继续. . .


猜你喜欢

转载自blog.csdn.net/ClamReason/article/details/80544080