基于Floyd算法的校园导航系统(Python版)

本文档详述了一个使用Python编程语言开发的校园导航系统,系统基于Floyd算法实现查询两点最短路径和多路径信息。系统包含查询学校地图、景点信息、最短路径等功能,界面友好且具有良好的人机交互。开发者在找不到Python版本的校园导航系统实例后,决定自己动手编写,实现了包括景点信息存储、最短路径计算等多个模块。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Tips:这个系统是学校《大数据应用开发语言》的大作业,本身想直接在网上copy一下,结果发现校园导航系统的c/java等版本很多很多,而python版本非常之少,于是只能自己写一个简单版本的了。包含三个模块:查询学校地图模块、查询两点最短路径、查询多路径信息。


前言

随着社会经济的发展,政府对教育建设的投资越来越大。众多高校开始扩建工程,校园占地面积大,楼宇种类多。体现出国家对教育的重视程度逐年上升,科教兴国战略时首当其冲。面对越来越大的学校,“迷路”成为众多高校新生不得面临的话题,这便需要校园导航系统来解决师生如何查询楼宇、如何快速到达目的地问题。
本系统采取基于Floyd算法来完成查询两点最短路径、查询多路径信息等问题。


一、题目

功能描述:设计你的学校的校园景点,所含景点不少于10个.有景点名称,代号,简介等信息; 为来访客人提供图中任意景点相关信息的查询.测试数据:由读者根据实际情况指定.

二、需求分析

1.要求

(1)用Python语言实现程序设计;
(2)进行相关信息处理;
(3)画出查询模块的流程图;
(4)系统的各个功能模块要求用函数的形式实现;
(5)界面友好(良好的人机互交),程序要有注释。

2.运行环境

(1)MacOS Big Sur 11.6.2系统
(2)PyCharm CE 2021

3.开发语言

大数据开发语言(Python)

三、概要设计

1.系统流程图

系统流程图

2.函数流程图

函数流程图

四、详细设计

1.类的分析与设计

定义一个Attractions类来实现输入和存放景点编号、名称。

class Attractions:
     num = 0   #景点编号
     name = '' #景点名称

定义一个Campus类来存放校园无向图的边和节点,并给各结点定义名称。

class Campus:
    att = ["","南大门","行政楼","三号楼","四号楼","图书馆","西大门","7号楼","八号楼","九号楼","操场","体育馆","大操场"]   #景点
    edges = [[INF] * M] * M  #边
    Nodes_Num = 0
    edges_Num = 0   #总结点数,总边数

定义一个Passing类来存放路径栈、路径数、栈顶数

class passing():
    pathStack = [[0]*M] ##路径栈
    top = 0
    count = 0  #栈顶位置,路径数
    visited = [[False]*M] #判断是否已经经过

定义一个DIS类来存放path路径和distence目的地。

class DIS:
    distence = [[0] * M] * M                                                   #距离向量
    path = [[0] * M] * M

2.函数的分析与设计

定义函数getCampus()来读取本地map.txt地图信息,将读出来的数据放在Nodes_Num数组和edges二维数组中。

def getCampus(g):
    file = r'./map.txt'
    with open(file) as f:
        i = 0
        for line in f:
            if i == 0:
                tmp1,tmp2 = line.split(',')
                g.Nodes_Num = int(tmp1)
                g.edges_Num = int(tmp2)
                i = 1
            else:
                x, y, w = line.split(',')
                g.edges[int(x)][int(y)] = g.edges[int(y)][int(x)] = int(w)

定义check函数来判断输入字符是否合规,如果输入正确返回True,错误返回False。

def check(ch):
    if ch < 0 or ch > 12:
        print("\n您的输入有误,请输入0~12之间的数字!")
        return False
    else:
        return True

定义getinf()函数来查询想要了解的景点信息

def getinf(g):
    poi = int(input("请输入您想了解到景点,0结束:"))
    while poi != 0:
        print("以下是该景点信息:")
        print(g.inf[poi])
        poi = int(input("请输入您想了解到景点,0结束:"))

定义Search函数来实现查询景点功能

def Search(g):
    number = 0
    while True:
        putMap()
        print("请问您想查看哪个景点(请输入景点编号,输入0结束):")
        input(number)
        # system("cls") #清空屏幕
        if(check(number)):
            if(number == 0):
                break
            else:
                print("景点编号:{}".format(g.att[number].num))
                print("景点名称:{}".format(g.att[number]))

定义shrotPath最短路径函数中用三个for循环语句就能实现。

def shortPath(g,dis):
    for i in range(1,g.Nodes_Num+1):                                #初始化距离向量矩阵与路径向量矩阵
        for j in range(1,g.Nodes_Num+1):
            dis.distence[i][j] = g.edges[i][j]
            if i != j and dis.distence[i][j] != INF:
                dis.path[i][j] = i  #表示如果i和j相邻,i到j需要经过i
            else:
                dis.path[i][j] = -1                                 #否则用 -1代表当前两点不可达

    for k in range(1,g.Nodes_Num+1):                                #递推求解每两景点的最短路径
        for i in range(1,g.Nodes_Num+1):
            for j in range(1,g.Nodes_Num+1):
                if dis.distence[i][j] > (dis.distence[i][k] + dis.distence[k][j]):  #如果发现引入k点可以使得路径更短
                    dis.distence[i][j] = dis.distence[i][k] + dis.distence[k][j]    #更新最短路径长度
                    dis.path[i][j] = k

定义最佳路径函数bestPath来实现最佳路径功能

def bestPath(g,dis):
    vNum = [0,0,0,0,0,0,0,0,0,0,0,0,0]
    count = 1                                       #记录用户输入的编号信息
    len = 0                                                        #统计全程路径总长
    vNum[count] = int(input("             请输入你要游览的景点的编号(输入0结束输入):"))


    while vNum[count] != 0 and count <= 12:
        if vNum[count] == 0:
            break
        count += 1
        vNum[count] = int(input("             请输入你要游览的景点的编号(输入0结束输入):"))

    print("             已为您挑选最佳访问路径:")
    i = 1
    while vNum[i] > 0 and vNum[i + 1] > 0 :          #遍历所有输入的景点
        print("{}->".format( g.att[vNum[i]]),end='')                      #输出路径上的起点
        Floyd_Print(g,dis, vNum[i],vNum[i + 1])                      #利用Floyd算法得到这两点之间的最短路径
        len += dis.distence[vNum[i]][vNum[i + 1]]             #算出最短路长度
        i += 1
    print(g.att[vNum[count - 1]])                 #输出路径上的终点
    print("             全程总长为:{}m".format(len))

用打印函数print_shortPath()和Floyd_Path()通过递归实现打印两点间的最短路径,并将结果显示到控制台上。

def Floyd_Print(g,dis,start,end):
                                                #递归基:如果两点相邻或者两点不可达,结束递归
    if dis.path[start][end] == -1 or dis.path[start][end] == end or dis.path[start][end] == start:
        return
    else:
        Floyd_Print(g,dis, start, dis.path[start][end])                 #将中间点作为终点继续打印路径
        print('{}->'.format(g.att[dis.path[start][end]]),end='')         #打印中间景点名字
        Floyd_Print(g, dis,dis.path[start][end], end)                 #将中间点作为起点继续打印路径

#输出并打印两点间的最短路径
def print_shortPath(g,dis):
    start = int(input("         请输入起点编号:"))
    end = int(input("         请输入终点编号:"))
    print("             {}到{}的最短距离是{}M".format(g.att[start],g.att[end],dis.distence[start][end]))
    print("             最佳游览路线:",end='')
    print('{}->'.format(g.att[start]),end='')                                       #输出路径上的起点
    Floyd_Print(g,dis,start, end)                                               #输出路径上的中间点
    print(g.att[end])                                     #输出路径上的终点

五、具体代码实现

import os
M = 15 # 校园景点数量
INF = 0x3f3f3f3f


class Campus:
    att = ["","北大门","行政楼","信工楼","教学主楼","图书馆","西大门","师院宾馆","体育楼","北苑食堂","澡堂","宿舍区","大操场"]   #景点
    inf = [['']] * M
    edges = [[INF] * M] * M  #边
    Nodes_Num = 0
    edges_Num = 0   #总结点数,总边数

def putMap():
    print("                                                                                                                 ")
    print("                                                盐城师范学院(通榆校区)校园导游图                                                    ")
    print("                                                                                                                 ")
    print("                                                                                                                 ")
    print("        ===================================================================================================      ")
    print("                   2:行政楼                 ----6:西大门                                                          ")
    print("                     /    \\                /    |    \\                                                         ")
    print("                    /      \\              /     |     \\                                                        ")
    print("                   /        -----         |     |      ----- 7:师院宾馆------                                     ")
    print("                  /               \\       |     |              |   |        |                                   ")
    print("                 /              3:信工楼---     |      ---------   |        |                                     ")
    print("         ===================================================================================================     ")
    print("                |                  |    |       |    /            |      9: 北苑食堂                                 ")
    print("                |                  |    |       |   /             |             \\                               ")
    print("                |                  /     \\      |  /              |              --10: 澡堂                     ")
    print("           1:北大门               /        -5:图书馆              |                       |                        ")
    print("                 \\              /              |                 /                        |                      ")
    print("                  \\            /               |                /        /------------11:体育馆                  ")
    print("        ===================================================================================================       ")
    print("                      4: 教学主楼-----------------                 |      /                     |                     ")
    print("                           |                                    |     /                      |                    ")
    print("                           |                                8: 体育楼-------                 |                     ")
    print("                           |                                                |                |                    ")
    print("                            --------------------------------------------12:大操场-------------                     ")
    print("                                                                                                                  ")
    print("        ===================================================================================================      ")


def putMenu():
    print("")
    print("                      *     *       ********     *            *            ********                        ")
    print("                      *     *       *            *            *           *        *                       ")
    print("                      *******       *******      *            *           *        *                       ")
    print("                      *     *       *            *            *           *        *                       ")
    print("                      *     *       ********     *******      *******      ********                        ")
    print("                                                                                                   ")
    print("                                                                                                   ")
    print("       = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =")
    print("       = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =")
    print("       = =                                                                                   = =")
    print("       = =                           欢迎使用盐城师范学院(通榆校区)校园导航系统                            = =")
    print("       = =                                                                                   = =")
    print("       = =                                   请选择服务:                                     = =")
    print("       = =                                                                                   = =")
    print("       = =             1.学校信息                          4.退出系统                        = =")
    print("       = =                                                                                   = =")
    print("       = =             2.寻找两景点之间的最短路径                                            = =")
    print("       = =                                                                                   = =")
    print("       = =             3.寻找多景点之间所有路径                                              = =")
    print("       = =                                                                                   = =")
    print("       = =                                                                                   = =")
    print("       = =                                                                                   = =")
    print("       = =                                                                                   = =")
    print("       = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =")
    print("       = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =")
    print()
    op = input("             请根据你的需求选择操作:")
    return op




def getCampus(g):
    file = r'./map.txt'
    inff = r'./information.txt'
    for i in range(1,g.Nodes_Num+1):
        for j in range(1,g.Nodes_Num+1):
            if i == j:
                g.edges[i][j] = 0

    with open(file) as f:
        i = 0
        for line in f:
            if i == 0:
                tmp1,tmp2 = line.split(',')
                g.Nodes_Num = int(tmp1)
                g.edges_Num = int(tmp2)
                i = 1
            else:
                x, y, w = line.split(',')
                g.edges[int(x)][int(y)] = g.edges[int(y)][int(x)] = int(w)
    with open(inff) as f:
        for line in f:
            tmp1,tmp2 = line.split(' ')
            poi = int(tmp1)
            g.inf[poi] = tmp2
def getinf(g):
    poi = int(input("请输入您想了解到景点,0结束:"))
    while poi != 0:
        print("以下是该景点信息:")
        print(g.inf[poi])
        poi = int(input("请输入您想了解到景点,0结束:"))

def check(ch):
    if ch < 0 or ch > 12:
        print("\n您的输入有误,请输入0~12之间的数字!")
        return False
    else:
        return True


def Search(g):
    number = 0
    while True:
        putMap()
        print("请问您想查看哪个景点(请输入景点编号,输入0结束):")
        input(number)
        # system("cls") #清空屏幕
        if(check(number)):
            if(number == 0):
                break
            else:
                print("景点编号:{}".format(g.att[number].num))
                print("景点名称:{}".format(g.att[number]))

class passing():
    pathStack = [[0]*M] ##路径栈
    top = 0
    count = 0  #栈顶位置,路径数
    visited = [[False]*M] #判断是否已经经过

# def DFS_AllPath(g,p,start,end):
#     dis=0 #总距离
#     p.pathStack[p.top] = start #将起点入栈
#     p.top += 1
#     p.visited[start] = 1  #表示该点已经访问过
#     for i in range(1,g.Nodes_Num+1): #遍历与这个结点相邻的结点
#         if g.edges[start][i] > 0 and g.edges[start][i] != INF and p.visited[i] == False: #如果与i不是自己并且这个点有可达路径并且未被访问过
#             if i == end: #如果已经到达目的地
#                 print("             第{}条道路:".format(p.count)) #将该路径输出
#                 p.count+=1
#                 for j in range(p.top):
#                     print(g.att[p.pathStack[j]]) #输出该景点
#                     if(j < p.top-1):
#                         dis = dis + g.edges[p.pathStack[j]][p.pathStack[j+1]]
#
#                 dis = dis + g.edges[p.pathStack[p.top-1]][end] #计算最后一个边长1
#                 print(g.att[end])
#                 print("             总长度为: {}m\n".format(len))
#
#             else: #如果还未达到
#                 DFS_AllPath(g,i,end) #递归遍历
#                 p.top -= 1 #出栈
#                 p.visited[i]=0 #释放该节点
#
#
# def print_AllPath(g,p):
#     p.flag=0
#     start = 0 #起点
#     end = 0 #终点
#     p.top = 0   #初始化栈顶
#     p.count = 1 #初始化路径条数
#     flag = 1
#     while True:
#         start = int(input(("\n                请输入起点编号:")))
#         if(check(start)):
#             flag = 1
#             break
#
#     flag=0  #flag重新置0
#     while True:
#         end = int(input(("\n                请输入终点编号:")))
#         if(check(end)):
#             flag = 1
#             break
#     print("")
#     DFS_AllPath(g,p,start,end)
#     print("")



#Floyd算法求两景点间的一条最短的路径
class DIS:
    distence = [[0] * M] * M                                                   #距离向量
    path = [[0] * M] * M

def shortPath(g,dis):
    for i in range(1,g.Nodes_Num+1):                                #初始化距离向量矩阵与路径向量矩阵
        for j in range(1,g.Nodes_Num+1):
            dis.distence[i][j] = g.edges[i][j]
            if i != j and dis.distence[i][j] != INF:
                dis.path[i][j] = i  #表示如果i和j相邻,i到j需要经过i
            else:
                dis.path[i][j] = -1                                 #否则用 -1代表当前两点不可达

    for k in range(1,g.Nodes_Num+1):                                #递推求解每两景点的最短路径
        for i in range(1,g.Nodes_Num+1):
            for j in range(1,g.Nodes_Num+1):
                if dis.distence[i][j] > (dis.distence[i][k] + dis.distence[k][j]):  #如果发现引入k点可以使得路径更短
                    dis.distence[i][j] = dis.distence[i][k] + dis.distence[k][j]    #更新最短路径长度
                    dis.path[i][j] = k                               # 更新最短路径上的经结点


# 递归实现打印两点间的最短路径(不包括起始点)
def Floyd_Print(g,dis,start,end):
                                                #递归基:如果两点相邻或者两点不可达,结束递归
    if dis.path[start][end] == -1 or dis.path[start][end] == end or dis.path[start][end] == start:
        return
    else:
        Floyd_Print(g,dis, start, dis.path[start][end])                 #将中间点作为终点继续打印路径
        print('{}->'.format(g.att[dis.path[start][end]]),end='')         #打印中间景点名字
        Floyd_Print(g, dis,dis.path[start][end], end)                 #将中间点作为起点继续打印路径

#输出并打印两点间的最短路径
def print_shortPath(g,dis):
    start = int(input("         请输入起点编号:"))
    end = int(input("         请输入终点编号:"))
    print("             {}到{}的最短距离是{}M".format(g.att[start],g.att[end],dis.distence[start][end]))
    print("             最佳游览路线:",end='')
    print('{}->'.format(g.att[start]),end='')                                       #输出路径上的起点
    Floyd_Print(g,dis,start, end)                                               #输出路径上的中间点
    print(g.att[end])                                     #输出路径上的终点



def bestPath(g,dis):
    vNum = [0,0,0,0,0,0,0,0,0,0,0,0,0]
    count = 1                                       #记录用户输入的编号信息
    len = 0                                                        #统计全程路径总长
    vNum[count] = int(input("             请输入你要游览的景点的编号(输入0结束输入):"))


    while vNum[count] != 0 and count <= 12:
        if vNum[count] == 0:
            break
        count += 1
        vNum[count] = int(input("             请输入你要游览的景点的编号(输入0结束输入):"))

    print("             已为您挑选最佳访问路径:")
    i = 1
    while vNum[i] > 0 and vNum[i + 1] > 0 :          #遍历所有输入的景点
        print("{}->".format( g.att[vNum[i]]),end='')                      #输出路径上的起点
        Floyd_Print(g,dis, vNum[i],vNum[i + 1])                      #利用Floyd算法得到这两点之间的最短路径
        len += dis.distence[vNum[i]][vNum[i + 1]]             #算出最短路长度
        i += 1
    print(g.att[vNum[count - 1]])                 #输出路径上的终点
    print("             全程总长为:{}m".format(len))


if __name__ == '__main__':

    g = Campus()
    dis = DIS()
    p = passing()
    getCampus(g)                                                               #从文件读取信息建立校园地图
    shortPath(g,dis)                                                               #通过Floyd求出distence表与path表
    while True :
        op = putMenu()
        while op != '0':                                                  #打印主菜单
            if op == '1':
                putMap()
                getinf(g)
                os.system("pause")
                os.system('cls')
                op = putMenu()
            elif op == "2":
                putMap()
                print_shortPath(g,dis)                                  #两景点间最短路径查询
                os.system("pause")
                os.system('cls')
                op = putMenu()
            elif op == "3":
                putMap()
                bestPath(g,dis)                #多景点间访问最优路线查询
                os.system("pause")
                os.system('cls')
                op = putMenu()
            elif op == '4':
                print("感谢使用!")
                exit()
            else:
                print("             对不起!没有该选项对应的操作.")
                os.system("pause")
                os.system('cls')
                op = putMenu()

information.txt和map.txt文档数据需要自己根据实际情况填写。

information.txt//存放学校地点相关信息
map.txt//存放学校地图(点、边等数据)

运行结果

主界面

主界面

学校信息

学校信息

查询景点

查询景点信息

查询最短路径

查询最短路径

提示:这里对文章进行总结:
在图论的学习中,将每个地点可以近似表示为网络中的一个节点,将位置、位置标号以及相邻位置标号写在矩阵的一行,利用稀疏矩阵进行数据的存取,节约存储空间。从存储空间读取区域内各点信息,根据每个点的邻接点构建邻接矩阵,如果两个节点相邻,则在邻接矩阵中置1,反之置0;再利用公示求得距离,将该距离赋给邻接矩阵中为 1 的值,就得到最短路径算法中的权值矩阵。

如有全部课程设计内容可私(包含、源码、答辩ppt、演示视频、文档),欢迎大家批评指正1

很久没来社区了,今天看到有朋友给我指正的问题,非常感谢下面这位朋友!
在这里插入图片描述
时间过的很快,当初还是在学习阶段,如今已经毕业1年了,现在回看之前写的代码,确实有很多bug和漏洞,现在将更改好的代码附上!
很多同学需要这两个txt文件,所以将两个txt文件也附上,并附上解答

  1. map.txt

这个文件包含景点的数量、路径数量和各个景点之间的边(距离)。格式为 起点,终点,权重。

示例内容:

12,14
1,2,10
1,4,20
2,3,5
3,4,15
2,5,25
3,5,10
4,5,30
5,6,50
6,7,35
5,8,40
8,9,20
9,10,15
9,11,10
8,12,25

•	第一行表示有 12 个景点,14 条路径(边)。
•	接下来的每一行表示从一个景点到另一个景点的距离(权重),例如从景点1到景点2的距离为10。
  1. information.txt

这个文件存储每个景点的详细信息。格式为 景点编号 信息。

示例内容:

1 北大门,位于校园北侧,是通往校园的主要入口。
2 行政楼,处理学校行政事务的中心。
3 信工楼,信息工程学院的主要教学楼。
4 教学主楼,通用教学楼,设有多个教室和实验室。
5 图书馆,学校图书馆,藏书丰富,提供安静的学习环境。
6 西大门,校园西侧的出口,靠近公共交通站点。
7 师院宾馆,学校的官方宾馆,提供住宿服务。
8 体育楼,设有多个运动场馆,提供健身设施。
9 北苑食堂,提供学生和教职工的用餐服务,菜品多样。
10 澡堂,提供公共沐浴服务,供学生使用。
11 宿舍区,学生宿舍,靠近澡堂和食堂。
12 大操场,学校的运动场,举办体育赛事和活动。

•	每一行的格式是 景点编号 后面跟随景点的描述信息。例如,编号1的景点是 “北大门”。

大家可以根据实际的校园结构和需求修改这些文件内容。如果你的景点或路径有变化,只需调整文件的内容。

import os
M = 15  # 校园景点数量
INF = 0x3f3f3f3f


class Campus:
    def __init__(self):
        self.att = ["", "北大门", "行政楼", "信工楼", "教学主楼", "图书馆", "西大门", "师院宾馆", "体育楼", "北苑食堂", "澡堂", "宿舍区", "大操场"]  # 景点
        self.inf = [''] * M
        self.edges = [[INF for _ in range(M)] for _ in range(M)]  # 边
        self.Nodes_Num = 0
        self.edges_Num = 0   # 总结点数,总边数


def putMap():
    print("                                                                                                                 ")
    print("                                                盐城师范学院(通榆校区)校园导游图                                                    ")
    print("                                                                                                                 ")
    print("                                                                                                                 ")
    print("        ===================================================================================================      ")
    print("                   2:行政楼                 ----6:西大门                                                          ")
    print("                     /    \\                /    |    \\                                                         ")
    print("                    /      \\              /     |     \\                                                        ")
    print("                   /        -----         |     |      ----- 7:师院宾馆------                                     ")
    print("                  /               \\       |     |              |   |        |                                   ")
    print("                 /              3:信工楼---     |      ---------   |        |                                     ")
    print("         ===================================================================================================     ")
    print("                |                  |    |       |    /            |      9: 北苑食堂                                 ")
    print("                |                  |    |       |   /             |             \\                               ")
    print("                |                  /     \\      |  /              |              --10: 澡堂                     ")
    print("           1:北大门               /        -5:图书馆              |                       |                        ")
    print("                 \\              /              |                 /                        |                      ")
    print("                  \\            /               |                /        /------------11:体育馆                  ")
    print("        ===================================================================================================       ")
    print("                      4: 教学主楼-----------------                 |      /                     |                     ")
    print("                           |                                    |     /                      |                    ")
    print("                           |                                8: 体育楼-------                 |                     ")
    print("                           |                                                |                |                    ")
    print("                            --------------------------------------------12:大操场-------------                     ")
    print("                                                                                                                  ")
    print("        ===================================================================================================      ")


def putMenu():
    print("")
    print("                      *     *       ********     *            *            ********                        ")
    print("                      *     *       *            *            *           *        *                       ")
    print("                      *******       *******      *            *           *        *                       ")
    print("                      *     *       *            *            *           *        *                       ")
    print("                      *     *       ********     *******      *******      ********                        ")
    print("                                                                                                   ")
    print("                                                                                                   ")
    print("       = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =")
    print("       = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =")
    print("       = =                                                                                   = =")
    print("       = =                           欢迎使用盐城师范学院(通榆校区)校园导航系统                            = =")
    print("       = =                                                                                   = =")
    print("       = =                                   请选择服务:                                     = =")
    print("       = =                                                                                   = =")
    print("       = =             1.学校信息                          4.退出系统                        = =")
    print("       = =                                                                                   = =")
    print("       = =             2.寻找两景点之间的最短路径                                            = =")
    print("       = =                                                                                   = =")
    print("       = =             3.寻找多景点之间所有路径                                              = =")
    print("       = =                                                                                   = =")
    print("       = =                                                                                   = =")
    print("       = =                                                                                   = =")
    print("       = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =")
    print("       = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =")
    print()
    op = input("             请根据你的需求选择操作:")
    return op


def getCampus(g):
    file = r'./map.txt'
    inff = r'./information.txt'
    for i in range(1, g.Nodes_Num+1):
        for j in range(1, g.Nodes_Num+1):
            if i == j:
                g.edges[i][j] = 0

    with open(file) as f:
        i = 0
        for line in f:
            if i == 0:
                tmp1, tmp2 = line.split(',')
                g.Nodes_Num = int(tmp1)
                g.edges_Num = int(tmp2)
                i = 1
            else:
                x, y, w = line.split(',')
                g.edges[int(x)][int(y)] = g.edges[int(y)][int(x)] = int(w)
    with open(inff) as f:
        for line in f:
            tmp1, tmp2 = line.split(' ')
            poi = int(tmp1)
            g.inf[poi] = tmp2


def getinf(g):
    poi = int(input("请输入您想了解到景点,0结束:"))
    while poi != 0:
        print("以下是该景点信息:")
        print(g.inf[poi])
        poi = int(input("请输入您想了解到景点,0结束:"))


def check(ch):
    if ch < 0 or ch > 12:
        print("\n您的输入有误,请输入0~12之间的数字!")
        return False
    else:
        return True


def Search(g):
    while True:
        putMap()
        number = int(input("请问您想查看哪个景点(请输入景点编号,输入0结束):"))
        if check(number):
            if number == 0:
                break
            else:
                print("景点编号:{}".format(number))
                print("景点名称:{}".format(g.att[number]))


class Passing:
    def __init__(self):
        self.pathStack = [0] * M  # 路径栈
        self.top = 0
        self.count = 0  # 栈顶位置,路径数
        self.visited = [False] * M  # 判断是否已经经过


class DIS:
    def __init__(self):
        self.distence = [[0] * M for _ in range(M)]  # 距离向量
        self.path = [[0] * M for _ in range(M)]


# Floyd算法求两景点间的一条最短的路径
def shortPath(g, dis):
    for i in range(1, g.Nodes_Num+1):  # 初始化距离向量矩阵与路径向量矩阵
        for j in range(1, g.Nodes_Num+1):
            dis.distence[i][j] = g.edges[i][j]
            if i != j and dis.distence[i][j] != INF:
                dis.path[i][j] = i  # 表示如果i和j相邻,i到j需要经过i
            else:
                dis.path[i][j] = -1  # 否则用 -1代表当前两点不可达

    for k in range(1, g.Nodes_Num+1):
        for i in range(1, g.Nodes_Num+1):
            for j in range(1, g.Nodes_Num+1):
                if dis.distence[i][j] > dis.distence[i][k] + dis.distence[k][j]:
                    dis.distence[i][j] = dis.distence[i][k] + dis.distence[k][j]
                    dis.path[i][j] = dis.path[k][j]  # 更新路径


# 递归打印从start到end的最短路径
def printpath(start, end, dis):
    if dis.path[start][end] == -1:
        print("无最短路径")
        return
    if dis.path[start][end] == start:
        print("从 {} 到 {} 的最短路径为: {}".format(start, end, start), end=" ")
    else:
        printpath(start, dis.path[start][end], dis)
    print("-> {}".format(end), end=" ")


def check1(start, end):
    if not check(start) or not check(end):
        print("您输入有误,编号超出范围!")
        return False
    elif start == end:
        print("您输入有误,编号相同!")
        return False
    else:
        return True


def start1(g, dis):
    putMap()
    start = int(input("请输入起点景点编号:"))
    end = int(input("请输入终点景点编号:"))
    if check1(start, end):
        shortPath(g, dis)
        printpath(start, end, dis)


def passall(passing, g, a, b):
    passing.top += 1
    passing.pathStack[passing.top] = a
    passing.visited[a] = True
    if a == b:
        print("第%d条路径: " % (passing.count + 1), end="")
        passing.count += 1
        for i in range(1, passing.top+1):
            print(g.att[passing.pathStack[i]], end=" ")
        print()
    else:
        for j in range(1, g.Nodes_Num+1):
            if g.edges[a][j] != INF and not passing.visited[j]:
                passall(passing, g, j, b)

    passing.visited[a] = False
    passing.top -= 1


def start2(g, passing):
    putMap()
    start = int(input("请输入起点景点编号:"))
    end = int(input("请输入终点景点编号:"))
    if check1(start, end):
        print("景点{}到景点{}之间的所有路径如下:".format(start, end))
        passall(passing, g, start, end)


def go(g, dis, passing):
    while True:
        os.system("cls")
        op = putMenu()
        if op == '1':
            Search(g)
            getinf(g)
        elif op == '2':
            start1(g, dis)
        elif op == '3':
            start2(g, passing)
        elif op == '4':
            print("退出成功!感谢您的使用!")
            break
        else:
            print("输入有误,请重新输入!")


def main():
    g = Campus()
    dis = DIS()
    passing = Passing()
    getCampus(g)
    go(g, dis, passing)


if __name__ == '__main__':
    main()```

实现简单的查询,各风景的查询,调用各函数,实现课程设计的目标。其中包含三个功能,一个是直接进入导航系统,利用主函数中已有的数据,进行查询:一个是进行创建数据,本程序中初始数据为农大的导航数据,如果需要也可以自己建立一个;最后一个是退出功能。设计该函数的目的是为了能够多次得应用dijkstra函数进行查询最短路径。同时该函数可以列出各景点的代号和对应的名称,这样大家只要输入代号就行了。方便进行查询。下面分别描述这些函数,建立它们函数原型。 1、主函数 函数原型:void main(void) 功 能:控制程序。 参 数:void 返 回 值:void 要 求:管理菜单命令并完成初始化。 2、菜单选择和处理函数 函数原型:int menu() 功 能:处理选择的菜单命令并接收用户选择的命令代码。 参 数:int 返 回 值:int 工作方式:返回命令代码的整数值,根据命令,调用相应函数。 要 求:只允许选择规定键,如果输入不合要求,则提醒用户重新输入。 3、建立邻接矩阵函数 函数原型:void createadj() 功 能:重新建立一个学生信息的记录。 参 数:void 返 回 值:void 工作方式:在需要的时候就可以有主菜单中调用 void createadj()函数。 要 求:必需输入信息记录,然后才能调用出search()函数进行查询。 4、dijkstra函数 函数原型:void dijkstra(intx,inty) 功 能:求两点间的最短路径 参 数:void 返 回 值:void 工作方式: 该函数被其它一些函数调用。 5、结束程序 函数原型:int Exit() 功 能:使程序正常结束运行 参 数:int 返 回 值:1 工作方式:在操作都完成后,可以调用int Exit()函数,使函数最终返回 1 运行exit(1),程序正常结束。 要 求:运行Exit()函数后可以选择是否要保存,选择y则先保存再返 回1值;如果选择n直接返回1值。详细的程序设计应从下到上,在本设计中就要先设计createadj函数;然后设计dijkstra函数;接着是search函数;menu函数;最后才是main函数。如此设计能大大提升设计速度,因为从下往上使编程时的高试过程简单许多,而做课程设计花费时间最多的就是调试过程。对于各函数的详细设计,各函数的N—S图如下: (1)Createadj函数 (2)Dijkstra函数          (3)Search函数          (4)Menu函数          (5)main函数          2.4 程序编码   把详细设计的结果进一步求精为程序设计语言程序。同时加入一些注解和断言,使程序中逻辑概念清楚;编写过程中参考各种的教材和材料,使程序编写的正确性大有提高,同时也许到许多实践知识,增加了实践经验。 2.5 程序调试与测试    程序编写总是出现各种各样的错误,但是难点不是修改错误,而是找出错误。在大量的源程序中找出错误难度很大,但有了一定的方法,就能节省大量的时间,在这次课程设计中我运用的调试方法主要有2种:     一是借助调试工具。利用Turbo C中提供的程序专门调试工具Debugger程序,可以很容易找出程序中的各种语法错误。但是遇到一些逻辑错误时却又无从着手。这时我就用下面一种方法。     二是在程序中插入打印语句。猜测出大致的错误位置,选则一些主要变量,在关键部位插入打印语句,打印出这个主要变量,看其是否与理论上的一样,在多个位置插入,如果有个位置的值与理论值一样,另一个位置与理论值不一样,则错误就落在这两个位置之间,然后再多测试几个位置缩小范围,直到找出错误。  例如;我在调试main()主函数时,程序能够运行,三个选项都能选择,创建函数能够正常运行,也能正常退出,但在选第一条进入校园导航后,打印出来的列表却是空的,源程序中的初始化数据没有显示出来,我又尝试输入两个结点进行查找,发现没有输出路线,所以我猜测初始化数据没有被正常写入。但不知道为何没有被正常写入,首先怀疑是初始化时附值发生错误,查阅各种资料进行校验,发现没有错误。后来经过综合分析,发现最有可能是n值在search()函数中发生错误,于是我在search()函数中插入打印n 的语句,运行后发现输出的n为0,初始化数据中有11个结点,n应该为11,所以n 在这个地方发生错误,我又在main()主函数中打印出n 的值,n=11,是正确的。所以错误就在search()函数中,也就说是当运行case1,运行到search()函数时,n从11变为0,针对这个错误,我把变量n改为宏定义,因为n 是代表结点个数,不管在哪个函数中它的值都是一样的才对。改完后运行程序,成功! 本设计文件的注释如上,已给出详细的说明,下面仅以文件为单位说明各个函数的作用和特点,在必要的地方给予一定说明。  3.1、guide.h文件 使用条件编译。以下是头文件中语句 /********************************************* *头文件(.h) ********************************************/ #include "stdio.h" #include "conio.h" #include "alloc.h" #define n0 100 #define infi 32767 /*“无穷大*/ int adjmatrix[n0+1][n0+1];     /*邻接矩阵*/ int n=11; struct node             /*表结点*/ { char name[20];       /*下一个表结点与它们之间的距离*/ }place[12]={{"ShiDiGongYuan"},   /*表结点初始化,即写各景点名称*/    {"CangRongGongYu"},    {"YinHuiLou"},    {"TuoHuanGuanChang"},    {"DiBaShiTang"},    {"XiaoYiYuan"},    {"TuShuGuan"},    {"TiYuGuan"},    {"ZhongHuaGuanChang"},    {"ChuangXinLou"},    {"YiFuTuShuGuan"},    {"BoXueLou"}};  void createadj()          /*建立邻接表*/  void dijkstra( int x,int y)     /*dijkstra求最小生树*/  void search()            /*搜索最短路径*/  menu()               /*菜单函数*/          /********************************************* *建立邻接表 ********************************************/ void createadj()  
评论 63
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值