紅綠燈

派猴子來的救兵

 

這是什麼鬼

有天衝到十字路口, 但是剛剛變成紅燈,等了20秒. 接下來還有十幾個路口, 就想此次紅燈等了20秒, 會不會一連串的紅燈把這20秒放大了, 致使到最後耽誤了幾分鐘.有點像蝴蝶效應.python

一直感觀認爲第一個路口耽誤的時間會放大, 不知道有沒有別人和我同樣的第一感?app

寫了一個程序驗證了一下, 由於和第一感不同, 因此也不確認程序模擬的對不對...dom

初始化20個紅綠燈, 隨機紅燈時長和綠燈時長. 過馬路須要6秒.lua

兩組作爲對比, 一個是當前就在第一個路口, 另外一個作對比的是20秒後到了第一個路口.spa

和我以前想的不同, 遲到的人很快就在下一個路口或者是再下個路口和與另外一組的人追平了. 極少極少有時間被放大的狀況(以致於我根本沒有觀察到這種狀況)code

大規模模擬下來, 平均來看, 在第一個路口晚N秒徹底不影響20個路口以後的最終到達時間.blog

模擬結果

模擬的結果以下, 20個紅綠燈, 過馬路都是6秒, 結果第一行表明程序開始就在第一個路口, 第二行表明等了一秒纔到路口, 20行表明過了20秒纔到第一個路口. 考慮到第一個路口以前多出的時間, 最後一行僅比第一行多用了20秒不到(有沒有哪裏搞錯了?)utf-8

% python testTrafficLight.py -c 20 -w 6 -f 20 -cmd test
433.329
435.082
436.183
437.105
437.728
438.53
440.029
441.116
441.263
441.538
442.96
443.805
445.111
446.188
448.241
449.592
450.386
451.389
452.043
453.071

來看一個具體的例子

"隨機"生成5個路口. 假設每一個路口都須要6秒. 咱們是第0秒就趕到了第一個路口能夠立刻過紅綠燈了. 結果以下:get

[[27, 67, 72], [34, 47, 36], [56, 64, 11], [21, 66, 38], [62, 20, 36]]  #隨機生成的路口
0 [[27, 67, 72], [34, 47, 36], [56, 64, 11], [21, 66, 38], [62, 20, 36]] # 第0秒出如今第1個路口
wait_time: 6 #過馬路用了6秒
6 [[27, 67, 78], [34, 47, 42], [56, 64, 17], [21, 66, 44], [62, 20, 42]] # 如今在第二個路口了
wait_time: 6
12 [[27, 67, 84], [34, 47, 48], [56, 64, 23], [21, 66, 50], [62, 20, 48]]
wait_time: 39
51 [[27, 67, 29], [34, 47, 6], [56, 64, 62], [21, 66, 2], [62, 20, 5]]
wait_time: 25
76 [[27, 67, 54], [34, 47, 31], [56, 64, 87], [21, 66, 27], [62, 20, 30]]
wait_time: 38
114

"隨機"生成和以前同樣的5個路口. 一樣每一個路口都須要6秒. 咱們是20秒以後才趕到了第一個路口, 很不巧綠燈不到6秒了, 只能等紅燈. 結果以下:cmd

[[27, 67, 72], [34, 47, 36], [56, 64, 11], [21, 66, 38], [62, 20, 36]] #隨機生成的路口
20 [[27, 67, 92], [34, 47, 56], [56, 64, 31], [21, 66, 58], [62, 20, 56]] # 20秒後出如今第1個路口
wait_time: 35 #過馬路用了35秒
55 [[27, 67, 33], [34, 47, 10], [56, 64, 66], [21, 66, 6], [62, 20, 9]] # 如今在第二個路口了
wait_time: 30
85 [[27, 67, 63], [34, 47, 40], [56, 64, 96], [21, 66, 36], [62, 20, 39]]
wait_time: 6
91 [[27, 67, 69], [34, 47, 46], [56, 64, 102], [21, 66, 42], [62, 20, 45]]
wait_time: 6
97 [[27, 67, 75], [34, 47, 52], [56, 64, 108], [21, 66, 48], [62, 20, 51]]
wait_time: 17
114

能夠看到第一我的前2個路口都過得很快, 沒有等, 只用了12秒. 但在後面3個路口不巧遭遇了紅燈, 被第2我的遇上了..

完整代碼

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import random
import argparse
from copy import deepcopy


def init(c, maxred, minred, maxgreen, mingren):
    lights = []
    for i in range(c):
        green_time = random.randint(minred, maxred)
        #green_time = 20
        red_time = random.randint(mingren, maxgreen)
        #red_time = 75
        light = [green_time, red_time, random.randint(0, green_time+red_time)]
        lights.append(light)
    return lights


def evaluate(f, w, lights):
    all_wait_time = f
    for l in lights:
        l[-1] = (l[-1]+f) % (sum(l[:2]))

    for i in range(len(lights)):

        light = lights[i]

        if light[-1] < light[0]:  # red
            wait_time = light[0]-light[-1]+w
        elif light[-1]+w > light[0]+light[1]: #green time is not enough
            wait_time = light[0]+light[1]-light[-1]+light[0]+w
        else:
            wait_time = w

        all_wait_time += wait_time

        for l in lights:
            l[-1] = (l[-1]+wait_time) % (l[0]+l[1])

    return all_wait_time


def main():
    random.seed(1)
    lights = init(
        args.c,
        args.maxred,
        args.minred,
        args.maxgreen,
        args.mingren)

    print evaluate(args.f, args.w, lights)


def test():
    s = [0]*args.f

    for i in range(1000):
        lights = init(
            args.c,
            args.maxred,
            args.minred,
            args.maxgreen,
            args.mingren)
        for j in range(args.f):
            all_wait_time = evaluate(j, args.w, deepcopy(lights))
            s[j] += all_wait_time

    for idx,e in enumerate(s):
        print 1.0*e/1000


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-cmd", default="main")
    parser.add_argument("-l", default="DEBUG")
    parser.add_argument(
        "-c",
        type=int,
        default=10,
        help="how many traffic lights,default 10")
    parser.add_argument(
        "-f",
        type=int,
        default=10,
        help="how long should the first light take")
    parser.add_argument(
        "-w",
        type=int,
        default=5,
        help="how long should one light take")
    parser.add_argument("-maxred", type=int, default=75)
    parser.add_argument("-minred", type=int, default=20)
    parser.add_argument("-maxgreen", type=int, default=75)
    parser.add_argument("-mingren", type=int, default=20)
    args = parser.parse_args()

    eval(args.cmd)()
相關文章
相關標籤/搜索