Bootstrap

C++、Dijkstra实现导航系统设计——课设

1. 程序概述

该导航系统是一个基于无向图模型的简单导航工具,用于在校园内寻找最短路径和距离。该系统采用 Dijkstra 最短路径算法实现,提供插入顶点、删除顶点、添加边、更改边权值、绘制地图以及计算最短路径等功能。

2. 数据结构

2.1 Vertex 结构

struct Vertex {

    string name;

    pair<int, int> coordinates; // 校园坐标

    unordered_map<string, int> neighbors;

};

string name: 顶点的名称。

pair<int, int> coordinates: 顶点的校园坐标。

unordered_map<string, int> neighbors: 存储与该顶点相邻的顶点及对应的权值。

2.2 NavigationSystem 类

class NavigationSystem {

private:

    unordered_map<string, Vertex> graph;

public:

    // 函数成员...

};

unordered_map<string, Vertex> graph: 存储整个导航系统的图,其中键为顶点名称,值为对应的 Vertex 结构。

3. 主要功能函数

3.1 insertVertex

插入一个新的顶点到图中,包括顶点名称、校园坐标。

3.2 deleteVertex

删除指定名称的顶点,同时更新其他顶点的邻接表。

3.3 addEdge

添加一条边连接两个顶点,并指定边的权值。

3.4 changeEdgeWeight

更改两个顶点之间边的权值。

3.5 drawGraph

显示图的表示,包括每个顶点的名称、坐标和邻接表。

3.6 shortestPath

使用 Dijkstra 算法计算两个顶点之间的最短路径和距离。

3.7 displayMenu

显示导航系统的主菜单,包括插入顶点、删除顶点、绘制地图、计算最短路径等选项。

4. 主程序流程

·初始化 NavigationSystem 对象。

·初始化顶点和边。

·进入主循环,显示主菜单,用户选择相应的功能。

·根据用户选择,调用相应的函数进行操作。

·循环执行,直到用户选择退出。

5. 注意事项

·确保插入、删除、修改边等操作时,顶点存在。

·在计算最短路径时,使用 Dijkstra 算法,确保图中没有负权边。

6. 扩展功能

·可以考虑实现其他路径规划算法,如 A* 算法。

·添加异常处理机制,处理用户输入错误等情况。

7. 结语 

该导航系统提供了基本的地图操作和路径查询功能,可以通过扩展和优化进一步提升用户体验。设计时应注意保持代码的清晰性和可维护性。

#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <queue>
#include <climits>
#include <algorithm>

using namespace std;

// 定义顶点结构
struct Vertex {
    string name;
    pair<int, int> coordinates; // 校园坐标
    unordered_map<string, int> neighbors;
};

class NavigationSystem {
private:
    unordered_map<string, Vertex> graph;

public:
    // 插入顶点
    void insertVertex(const string& name, int x, int y) {
        graph[name] = Vertex{name, make_pair(x, y)};
    }

    // 删除顶点
    void deleteVertex(const string& name) {
        graph.erase(name);
        for (auto& vertex : graph) {
            vertex.second.neighbors.erase(name);
        }
    }

    // 添加边
    void addEdge(const string& from, const string& to, int weight) {
        graph[from].neighbors[to] = weight;
        graph[to].neighbors[from] = weight;
    }
// 更改边的权值
void changeEdgeWeight(const string& from, const string& to, int newWeight) {
    if (graph.find(from) != graph.end() && graph.find(to) != graph.end()) {
        graph[from].neighbors[to] = newWeight;
        graph[to].neighbors[from] = newWeight;
    } else if (graph.find(from) != graph.end()) {
        // 新添加的顶点的情况
        graph[from].neighbors[to] = newWeight;
        graph[to].neighbors[from] = newWeight;
    } else if (graph.find(to) != graph.end()) {
        // 新添加的顶点的情况
        graph[from].neighbors[to] = newWeight;
        graph[to].neighbors[from] = newWeight;
    } else {
        cout << "顶点不存在,无法更改权值。" << endl;
    }
}

// 在 NavigationSystem 类中修改 drawGraph 函数
void drawGraph() {
    cout << "------------------------" << endl;
    cout << "   校园地图表示" << endl;
    cout << "------------------------" << endl;

    // 输出顶点信息及邻接表
    for (const auto& vertex : graph) {
        cout << vertex.first << " (" << vertex.second.coordinates.first << ", " << vertex.second.coordinates.second << ")" << endl;
        cout << "相邻顶点: ";
        for (const auto& neighbor : vertex.second.neighbors) {
            cout << neighbor.first << "(" << neighbor.second << ") ";
        }
        cout << "\n------------------------" << endl;
    }
}

    // 最短路径算法
    pair<int, vector<string>> shortestPath(const string& start, const string& end) {
        unordered_map<string, int> distance;
        unordered_map<string, string> previous;
        priority_queue<pair<int, string>, vector<pair<int, string>>, greater<pair<int, string>>> pq;

        for (const auto& vertex : graph) {
            distance[vertex.first] = INT_MAX;
        }

        distance[start] = 0;
        pq.push({0, start});

        while (!pq.empty()) {
            auto current = pq.top().second;
            pq.pop();

            for (const auto& neighbor : graph[current].neighbors) {
                int newDistance = distance[current] + neighbor.second;
                if (newDistance < distance[neighbor.first]) {
                    distance[neighbor.first] = newDistance;
                    previous[neighbor.first] = current;
                    pq.push({newDistance, neighbor.first});
                }
            }
        }

        vector<string> path;
        int totalDistance = distance[end];

        string currentVertex = end;
        while (!previous[currentVertex].empty()) {
            path.push_back(currentVertex);
            currentVertex = previous[currentVertex];
        }
        path.push_back(start);

        reverse(path.begin(), path.end());

        return make_pair(totalDistance, path);
    }

    // 显示导航系统主页面
    void displayMenu() {
        cout << "||—————————————————————————||" << endl;
        cout << "||                     导航系统                     ||" << endl;
        cout << "||              作者: xxxxxxxxxxxxxx                ||" << endl;
        cout << "||—————————————————————————||" << endl;
        cout << "||1. 插入顶点                                       ||" << endl;
        cout << "||2. 删除顶点                                       ||" << endl;
        cout << "||3. 校园地图表述                                   ||" << endl;
        cout << "||4. 输入目标,显示从东门及南门到目标最短距离及路径 ||" << endl;
        cout << "||5. 输入两坐标,显示两者最短距离及路径             ||" << endl;
        cout << "||6. 添加新插入节点与其他节点之间边的权值           ||" << endl;
        cout << "||0. 退出                                           ||" << endl;
        cout << "||__________________________________________________||" << endl;
    }
};

int main() {
    NavigationSystem navSystem;

    // 初始化顶点
    navSystem.insertVertex("寝室楼1", 1, 1);
    navSystem.insertVertex("寝室楼2", 2, 2);
    navSystem.insertVertex("食堂", 3, 1);
    navSystem.insertVertex("操场", 2, 3);
    navSystem.insertVertex("教学楼", 4, 2);
    navSystem.insertVertex("南门", 1, 4);
    navSystem.insertVertex("东门", 5, 3);
    navSystem.insertVertex("驿站", 6, 4);

    // 初始化边
    navSystem.addEdge("寝室楼1", "食堂", 35);
    navSystem.addEdge("寝室楼1", "教学楼", 45);
    navSystem.addEdge("寝室楼1", "南门", 60);
    navSystem.addEdge("食堂", "教学楼", 45);
    navSystem.addEdge("食堂", "寝室楼2", 100);
    navSystem.addEdge("教学楼", "东门", 200);
    navSystem.addEdge("南门", "教学楼", 10);
    navSystem.addEdge("寝室楼2", "操场", 20);
    navSystem.addEdge("操场", "东门", 10);
    navSystem.addEdge("东门", "驿站", 15);

    int choice;
    do {
        navSystem.displayMenu();
        cout << "请输入您的选择: ";
        cin >> choice;

        switch (choice) {
            case 1: {
                string vertexName;
                int x, y;
                cout << "\n请输入要插入的顶点名称: ";
                cin >> vertexName;
                cout << "请输入顶点的X坐标: ";
                cin >> x;
                cout << "请输入顶点的Y坐标: ";
                cin >> y;
                navSystem.insertVertex(vertexName, x, y);
                cout << "\n顶点已插入成功!\n\n" << endl;
                break;
            }
            case 2: {
                string vertexName;
                cout << "\n请输入要删除的顶点名称: ";
                cin >> vertexName;
                navSystem.deleteVertex(vertexName);
                cout << "\n顶点已删除成功!\n\n" << endl;
                break;
            }
            case 3: // 新添加的选项,用于绘制图形
				{navSystem.drawGraph();
   				break;
			}
            case 4: {
    string destination;
    cout << "请输入目标坐标: ";
    cin >> destination;

    auto resultSouth = navSystem.shortestPath("南门", destination);
    cout << "\n从南门出发的最短距离: " << resultSouth.first << endl;
    cout << "路径: ";
    for (const auto& vertex : resultSouth.second) {
        cout << vertex << " -> ";
    }
    cout << "\n";

    auto resultEast = navSystem.shortestPath("东门", destination);
    cout << "从东门出发的最短距离: " << resultEast.first << endl;
    cout << "路径: ";
    for (const auto& vertex : resultEast.second) {
        cout << vertex << " -> ";
    }
    cout << "\n\n";

    break;
}

            case 5: {
                string start, end;
                cout << "\n请输入起始坐标: ";
                cin >> start;
                cout << "\n请输入目标坐标: ";
                cin >> end;
                auto result = navSystem.shortestPath(start, end);
                cout << "\n最短距离: " << result.first << endl;
                cout << "\n路径: ";
                for (const auto& vertex : result.second) {
                    cout << vertex << " -> ";
                }
                cout <<"\n\n"<< endl;
                break;
            }
            case 6: {
    	string from, to;
    	int newWeight;
    	cout << "\n请输入新的顶点名称: ";
    	cin >> from;
    	cout << "\n请输入目标顶点名称: ";
    	cin >> to;
    	cout << "\n请输入新的权值: ";
    	cin >> newWeight;
    	navSystem.changeEdgeWeight(from, to, newWeight);
    	cout << "\n权值已成功更改!\n\n" << endl;
    	break;
		}
		
            case 0:
                cout << "感谢使用导航系统,再见!" << endl;
                break;
            default:
                cout << "无效的选择,请重新输入。" << endl;
                break;
        }
    } while (choice != 0);

    return 0;
}


 

;