元胞自动机在交通系统中的应用之二【单车道NaSch元胞自动机模型】

前言

想不到元胞自动机看的人更多,就写写吧。
听说有人想要看,今天就抽时间现场写了个NaSch的很简单的代码

第六章 道路交通流中的元胞自动机模型

既然是交通系统中的元胞自动机模型,就需要对现实世界中的交通系统进行分析,了解它的组成和运行机理。而元胞自动机主要的应用领域还是在道路交通流中。包括:

  1. 单车道交通流
  2. 多车道交通流
  3. 双向交通流
  4. 自行车流
  5. 机非混合交通流

当然最简单最基础的就是单车道交通流了,也是其他场景的基础。

6.1 单车道元胞自动机模型

  • 并行更新与顺序更新

  • step 1: 加速

  • step 2 : 减速

  • step 3 : 随机慢化

  • step 4 : 运动
    其实这四步可以归纳成两部分,一是速度状态调整,二是位置状态调整。

  • 边界条件

  1. 周期性边界条件
  2. 开口边界条件
  • 初始状态
local Sim      = AddModule('NaSch','Start')
ROADX          = AddParameter(Sim, nil, 'value', 'The size of the Road at X', 20)
ROADY          = AddParameter(Sim, nil, 'value', 'The size of the Road at Y', 1) 

Vehicle = {}
Vehicle.__index = Vehicle

function Vehicle:new(max_speed, p, x, v)
    local self = {Vmax = max_speed, p = p, x = x, v = v}
    setmetatable(self, Vehicle)
    return self
end 

function Vehicle:setHead(veh)
    self.head = veh
end 

function Vehicle:getDis()
    return self.head.x - self.x - 1
end 

function Vehicle:accelerate()
    self.v = math.min(self.v + 1, self.Vmax)
end 

function Vehicle:brake()
    self.v = math.min(self.v, self:getDis())
end 

function Vehicle:random()
    self.v = math.random() < self.p and math.max(self.v - 1, 0) or self.v
end 

function Vehicle:move()
    self.x = self.x + self.v
end 

function updateRoad()
    for i=0,ROADX do 
        SetValue(road, 0, i, 1)
    end 
    for i=1,#vehicles do
        SetValue(road, 1, vehicles[i].x, 1)
    end     
    Update(road)
end 

function OpenBoundary()
    if vehicles[1].x > ROADX then 
        table.remove(vehicles, 1)
        vehicles[1].head = boundary
    end
end 

function NaSch()
    road = CreateGrid('Nature', 'int', ROADX, ROADY)
    boundary = Vehicle:new(0, 0, ROADX + 2, 0)
    vehicles = {
        Vehicle:new(2, 0.25, 7, 0),
        Vehicle:new(2, 0.25, 6, 1),
        Vehicle:new(2, 0.25, 3, 1),
        Vehicle:new(2, 0.25, 1, 2),
    }
    vehicles[1]:setHead(boundary)
    for i=2,#vehicles do
        vehicles[i]:setHead(vehicles[i-1])
    end 
    local tick = 0

    while GetReady() do
        updateRoad()
        for i=1,#vehicles do 
            vehicles[i]:accelerate()
        end 
        
        for i=1,#vehicles do 
            vehicles[i]:brake()
        end
        
        for i=1,#vehicles do
            vehicles[i]:random()
        end 
        for i=1,#vehicles do
            vehicles[i]:move()
        end 
        
        OpenBoundary()
        
        if tick % 5 == 0 then 
            table.insert(vehicles, Vehicle:new(2, 0.25, 0, 0))
            vehicles[#vehicles].head = vehicles[#vehicles-1] or boundary
        end 
        tick = tick + 1
        Sleep(10000)
    end    
end
发布了11 篇原创文章 · 获赞 27 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/sinat_41644416/article/details/95186602