Python 交通仿真建模(1)

问题描述

道路网络可以建模为图形。图中的节点表示交点和位置。每个节点都分配了一个ID号,以便于识别。节点之间的边表示道路。该图是有方向的,因为道路可以允许在一个方向行驶,但不能在另一个方向行驶(例如单向街道)。一个示例路网如下所示

在这里插入图片描述
在此示例网络中,黄色正方形表示交点,而蓝色圆圈表示位置。车辆将离开一个位置节点,可能穿过多个十字路口,然后到达另一个位置节点。
还要注意的是,并非通过交叉口的每条路线都可以同时通过。例如,上图中的十字路口0不太可能允许一辆车在另一辆车从1行驶到4的同时从2行驶到3,因为这会导致碰撞。

为了描述这种行为,我们可以考虑一个特定的交通信号,它确定了在任何时间点可以通过交叉口的哪些路径。这可以建模为(源、目标)对的列表。

例如,[(5,6),(6,5)]是交叉口4的交通信号,指示车辆可以从节点5行驶到节点6或从节点6行驶到节点5。然后,我们可以将交叉口描述为一个交通信号列表,每个信号都处于活动状态一个时间步,并在最终信号完成后循环回到第一个交通信号。

问题1

Write a function path_cost(path, intersections, road_times). If it is possible to traverse the path starting at timestep 0 without being stopped at any intersections then the function should return the total number of timesteps taken. If not, it should return None. You may assume that the path is a valid, traversable path.

您还可以进一步假设,穿过一个交通信号良好的十字路口需要0个时间。只有当车辆在沿道路行驶之前穿过交叉口时,车辆才能在同一时间段内穿过交叉口并沿道路行驶。

样例输入输出

simple_intersections = {0: [[],[(1,2), (2,1)]]}
simple_roads = {(0,1):1, (1,0):1, (0,2):1, (2,0):1}
path_cost([1,0,2], simple_intersections, simple_roads)

步骤:

时间步0:离开节点1前往十字路口0

时间步1:到达节点0,畅通无阻地通过交叉口

时间步2:到达最终位置节点2路径成本([1,0,2]),简单交叉点,

输出:

2

在这里插入图片描述

注释

def path_cost(path, intersections, road_times):
#TODO: Write your function here
#记录当前时间(所需时间),从 0开始
#循环path的index(长度为n的path,循环n-1次),因为只走了 n-1次
# for i in range(len(path) - 1): [0...n-1), i表示src index,i+1表示dest index
for i in range(1, len(path)): # [1...n),i-1表示src index, i表示dest index,
i+1表示dest之后的一个node
#通过indexing,得到src node和dest node的id
#我们走的方向就是,(src id, dest id)
#在road_times这个dictionary里面,找出这个方向所需的时间
#更新当前时间(把原来的时间 +=走这一步所需的时间)
# 如果我们到达的 dest node是一个 intersection
# 判断,在更新后的时间,我们能不能通过这个 intersection
# 计算出我们是如何通过 intersection的(src node, path[i+1]得到
intersection之后的 node)
# 找出当前这个 intersection的 list of traffic signals:dictionary look
up: dest_id
 # 找出当前时间的 traffic:list indexing: 当前时间 % traffic signals的长
度
 # 检查,如果 direction tuple不在当前的 intersetion当前时间的 traffic里
# return None
# loop 结束,意味着我们到达终点
return 当前时间

代码:

from main import load_road_network

def path_cost(path, intersection, road_times):
    '''
    path        :list
    intersection:dict
    road_times  :dict
    '''
    count = 0
    for i in range(1, len(path)):
        for k,v in road_times.items():
            #print(path[i-1],k[0])
            if (path[i-1],path[i]) == k:
                count += v
                src = k
                break
        if src[1] in intersection.keys():
            #if i == len(path) -1:
            #    return count
            deslstall = intersection[src[1]][count%len(intersection[src[1]])]
            if len(deslstall) == 0:
                return None
            deslst = [des[1] for des in deslstall]
            if path[i+1] not in deslst:
                return None
        #print('count:',count)
    return count


print(path_cost([5,0,1,2,8], 
{0: [[(5, 1), (1, 5)], [(6, 1), (1, 6)]], 1: [[(0, 2)], [(2, 0)]], 2: [[(7, 1), (1, 7)], [(8, 1), (1, 8)]]}, 
{(0, 5): 1, (5, 0): 1, (6, 1): 2, (1, 6): 2, (1, 2): 4, (2, 1): 4, (7, 2): 1, (2, 7): 1, (2, 8): 1, (8, 2): 1, (0, 1): 3, (1, 0): 3}))


simple_intersections = {0: [[],[(1,2), (2,1)]]}
simple_roads = {(0,1):1, (1,0):1, (0,2):1, (2,0):1}
print(path_cost([1,0,2], simple_intersections, simple_roads))

simple_intersections = {0: [[(1,2), (2,1)], []]}
simple_roads = {(0,1):1, (1,0):1, (0,2):1, (2,0):1}
print(path_cost([1,0,2], simple_intersections, simple_roads))

intersection,road_times = load_road_network('road_sample.txt')
print(path_cost([2,0,4,6], intersection, road_times))

intersection,road_times = load_road_network('road_sample.txt')
road_times[(2,0)] = road_times[(0,2)] = 2
print(path_cost([2,0,4,6], intersection, road_times))

未完待续

后面还有三个问题
在这里插入图片描述
根据文章反馈更新。。。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会长胖的斜杠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值