多地图间最短路径之节点算法

 前段时间在做一个游戏的跨地图寻路,地图结构及寻路思路说明如下:

       地图 表主要字段列表:

`m_id` int(11) unsigned NOT NULL auto_increment,
`m_name` varchar(32) NOT NULL default '' COMMENT '地图名称',
`m_type` tinyint(3) unsigned NOT NULL default '0' COMMENT '地图类型 0非场景地图 1野外 2普通 3家园 4帮会 5副本',
`m_grade` tinyint(3) unsigned NOT NULL default '0' COMMENT '地图分级 0场景地图 1场景区域点 2区域 3世界',
`g1_id` int(11) unsigned NOT NULL default '0' COMMENT '所属场景区域点ID',
`g2_id` int(11) unsigned NOT NULL default '0' COMMENT '所属区域ID',  
`m_land` varchar(16) NOT NULL default '' COMMENT '着陆点x,y; 区域地图和区域点地图的m_land存在该区域的着陆地图节点,场景地图的m_land存放该场景的着陆坐标点x,y',
`m_link` varchar(64) NOT NULL default '' COMMENT '连接场景ID和传送点ID',

 
 
 
 
 
 
 

世界地图(m_grade=3)=>区域地图(m_grade=2)=>场景区域点(m_grade=1)=>场景地图(m_grade=0)

        只有场景地图才属于实际地图,玩家可进入;其它地图只提供地图关联,不可进入;

        设计寻路流程:

  1. 判断当前地图与目标地图是否是场景地图(m_grade=0),仅场景地图间可寻路;        
  2. 判断两地图是否属于同一区域(g2_id),不属于同一区域则需要根据区域间的连接关系(m_link)进行寻路,寻路后则根据在区间内的路径终点取其着陆点(m_land)即区域点地图;      
  3. 判断两地图是否属于同一区域点(g1_id),不属于同一区域则需要根据区域间的连接关系(m_link)进行寻路,寻路后则根据在区间内的路径终点取其着陆点(m_land)即区域地图;
  4. 根据区域间的连接关系(m_link)进行寻路,寻路结果如下:result('list':[(地图ID_1,传送点1),(地图ID_2,传送点2),(地图ID_3,传送点3),...],'land':着陆点[区域场景为坐标,其它为地图ID]);       

注:        

  • 在区域和区域点间寻路时,如果不能到达(无连接关系或关系断开),则会返回直接到达的数据,且传送点为0,如:result('list':[(起始点,0),(终点,0)],‘land’:终点的着陆点)  
  • 在场景内着陆坐标为0则,由自动选择可移动的坐标点        @param int current 当前场景        @param int target 目标场景        @return: dict result{'err':int,'path':dict} err:成功=0,         失败:地图不存在=1,地图不可到达=2,地图区域没关连=3,地图区域点没关连=4,地图没有关连=5,地图数据不完整=6

以上是我们游戏的跨地图寻路设置思路,在游戏初始化时,会将所有地图以节点方式来存储,每个节点的子节点即是当前地图的连接场景ID,寻路时将在节点间计算最短路径

以下代码为python实现的节点间寻路算法,代码中包含了必要的注释和例子,在节点间寻路完闭后可将节点列表的值 与地图ID作相应处理,即可得到地图的路径、着陆点、坐标等信息,具体依具需求而定

#coding:utf-8
#多地图间最短路径之节点算法

import copy
'''
#树形节点查询算法
节点,存放子节点
@author:yangxs yang.net618@gmail.com
'''
class Node(object):
    def __init__(self,id,subnode):
        self.id = id
        if len(subnode)>0:
            self.__subnode = subnode
        else:
            self.__subnode = None

    def getSubnode(self):
        return self.__subnode

'''
树形结构,查询节点间最短节点数的路径
'''
class Tree(object):
    def __init__(self,nodes):
        #所有节点列表 {node_id:objNode}
        self.__nodes = nodes
        #已经查询过的节点列表
        self.__readyNodes = []
        self.__found = {}

    '''
    查询当前节点到目标节点的最短路径
    @param int current 当前(起始)节点
    @param int target 目标节点
    @return list result 节点路径列表,按起始节点到目标节点的顺序排列
    '''
    def search(self,current,target):
        if current == target:
            result = [current]
        else:
            result = []
            '''确定当前点节点与目标节点是否存在'''
            if self.__nodes.has_key(current) and self.__nodes.has_key(target):
                '''
                    检查当前节点的子节点中是否存在目标节点
                    1、目标节点属于当前节点的子节点,则直接返回[current,target];
                    2、目标节点不属于当前节点的子节点,则在子节点的子节点中继续循环查找目标节点,并记录最短节点数的路径列表;
                '''
                subnodes = self.__nodes[current].getSubnode()
                if subnodes != None:
                    if target in subnodes:
                        result = [current,target]
                    else:
                        self.__readyNodes.append(current)
                        self.__find(current,subnodes,target)
                        if self.__found.has_key(current):
                            result = self.__found[current]
                            result.insert(0,current)
        '''重置已经找到的路径信息'''
        self.__found = {}
        self.__readyNodes = []
        return result

    '''
    在父节点的子节点列表中循环查找目标节点,并记录最短节点列表
    @param int parent 父节点
    @param list nodes 子节点列表
    @param int target 目标节点
    @return: null
    '''
    def __find(self,parent,nodes,target):
        for node in nodes:
            '''节点是否已经查询过'''
            if node in self.__readyNodes:
                if self.__found.has_key(node):
                    result = [node] + copy.deepcopy(self.__found[node])

                    self.__founded(parent,result)
            else:
                if self.__nodes.has_key(node):
                    subnodes = self.__nodes[node].getSubnode()
                    if subnodes:
                        self.__readyNodes.append(node)
                        if target in subnodes:
                            self.__founded(node,[target])
                            self.__founded(parent,[node,target])
                        else:
                            self.__find(node,subnodes,target)
                            if self.__found.has_key(node):
                                result = [node] + copy.deepcopy(self.__found[node])
                                self.__founded(parent,result)

    '''
    更新已经查找到的路径信息,记录最短路径列表
    '''
    def __founded(self,parent,result):
        if self.__found.has_key(parent):
            if len(result)<len(self.__found[parent]):
                self.__found[parent] = result
        else:
            self.__found[parent] = result

map = {1:[2],
	   2:[1,3],
	   3:[2,9,11],
	   4:[5,6],
	   5:[4,7],
	   6:[4,15],
	   7:[5,10],
	   8:[16],
	   9:[3,12],
	   10:[7,11,16],
	   11:[3,10,17],
	   12:[9,13],
	   13:[12,14],
	   14:[13,15],
	   15:[14,6],
	   16:[10,8],
	   17:[11,18],
	   18:[17]}

print map
nodes = {}
for id,subnode in map.iteritems():
	nodes[id] = Node(id,subnode)

tree = Tree(nodes)

result = tree.search(2,16)
print 'result:%s' %result
# result: [2, 3, 11, 10, 16]

result = tree.search(3,18)
print 'result:%s' %result
# result: [3, 11, 17, 18]

result = tree.search(1,18)
print 'result:%s' %result
# result: [1, 2, 3, 11, 17, 18]


此算法改进后可用于公交站点最短寻路算法,暂时无时间修改;

本人能力有限,代码中存在很多改进地方,望各位多指正


QQ:75323501



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BFS(宽度优先搜索)算法常被用于解决迷宫问题中的最路径问题。该算法基于队列的实现方式,可以快速搜索出从起点到达终点的最路径。 具体来说,BFS算法的步骤如下: 1. 创建一个队列,并将起点加入队列中。 2. 创建一个二维数组来记录迷宫中每个位置的状态,例如是否已被访问过或者是墙壁等。 3. 使用循环来遍历队列中的元素,直到队列为空。 4. 在循环中,首先从队列中取出一个节点,并标记该节点为已访问。 5. 然后检查该节点的上、下、左、右四个方向的相邻节点,如果相邻节点是可行的且未被访问过,则将其加入队列中,并记录其距离起点的步数。 6. 重复步骤4和步骤5,直到找到终点或者遍历完所有可行的节点。 7. 如果找到终点,则可以通过回溯找到最路径。 需要注意的是,在BFS算法中,我们需要用一个二维数组来记录每个节点的状态,这样可以避免重复访问节点和处理墙壁等不可行的节点。 总结起来,BFS算法通过队列的方式,逐层遍历迷宫中的节点,直到找到终点。在遍历过程中,通过记录每个节点距离起点的步数,可以求解出最路径。 参考文献: BFS 算法是一种基于队列实现的搜索算法,常用于解决图论问题和迷宫问题。 BFS(Breadth First Search,广度优先搜索)是一种基于队列实现的搜索算法,常用于解决图论问题和迷宫问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值