1. 程式人生 > >元胞自動機在交通系統中的應用

元胞自動機在交通系統中的應用

最近要寫一篇有關元胞自動機的論文,但是之前的理解不夠深刻,因此在網上找到了北交賈斌、高自友等老師寫的《基於元胞自動機的交通系統建模與模擬》。

因此先把VRP放放,寫點讀書筆記,然後是基於MicroCity的元胞自動機實現。開始吧! 努力奮鬥。

上篇: 元胞自動機的基礎知識

元胞自動機應用廣泛,所以先學習元胞自動機是啥吧。

第一章 緒論

1、Wolfram發起“科學革命”,用簡單的電腦程式,也就是元胞自動機,取代數學方程。

2、元胞自動機(cellular automata or cellular automaton,CA)實質上是定義在一個具有離散、有限狀態的元胞組成的元胞空間上,按照一定的區域性規則,在離散的時間維度上演化的動力學系統。

3、Conway的生命遊戲機(game of life)

      咱們這個遊戲機可帶勁了,世界是一個類似於棋盤的二維方形網格,每個格子代表一個元胞,元胞具備兩種狀態,活(實心)or死(空白),然後這個世界有三條規則:

  1. 生存:對一個活的元胞,如果它的鄰居中有兩個或三個元胞是活的,那麼該元胞將繼續生存下去;
  2. 死亡:對一個活的元胞,i.如果它的鄰居中有四個或四個以上的元胞是活的,那麼該元胞將由於擁擠而死去,ii.如果它的鄰居中只有一個或沒有活的元胞,那麼該元胞將由於孤立無援而死去;
  3. 繁殖:對一個空的元胞,如果它的鄰居中有3個活的元胞,則變成一個活元胞。

OK,咱們開啟MicroCity開始編寫。

assert(loadstring(''))

  1. Grid:是MicroCity裡的格子型別,也可看做一種資料結構型別,橫座標為X軸,縱座標為Y軸,是離散的,座標(0,0)的cell中心為(0,0),從-0,5到0.5,如果cellsize=1時。
  2. 建立Xmax=10,Xmin=0的格子,會有11個
  3. 還有其他的function,具體看程式碼
local MakeGrid      = AddModule('Grid','CreateWorld')
local Sim           = AddModule('Simulation','Start')
local world_sim 	= AddParameter(MakeGrid, nil, "node", "Simulation Parameters")
WORLDSIZE			= AddParameter(MakeGrid, world_sim, "value", "Size of the Game World", 50)

local game_sim      = AddParameter(Sim, nil, "node", "Simulation Parameters")
DENSITY			    = AddParameter(Sim, game_sim, "value", "Density of the World at Beginning %", 50)
SEED 				= AddParameter(Sim, game_sim, "string", "Seed of Random Number Generation", "os.time()")
UPDATEINTV			= AddParameter(Sim, game_sim, "value", "Graphics Update Interval (in seconds)", 800)	

function Grid()
    local world = CreateGrid('Nature', 'int', WORLDSIZE+1, WORLDSIZE+1)
end 

local function GetNeighbors(x, y)
    local num = 0
    for i=-1,1 do
        for j=-1,1 do
            num = GetValue(world, x+i, y+j)==1 and num+1 or num 
        end 
    end 
    return num - GetValue(world, x, y) 
end

function Simulation()
    math.randomseed(assert(loadstring('return' .. SEED)))
    world = GetControl('grid.sgrd')
    size  = GetGridMaxXY(world) - 1 
    
    --initiate
    local cellMap = {}
    for i=1,size do
        cellMap[i] = {}
        for j=1,size do 
            cellMap[i][j] = 0
        end 
    end
    for i=1,math.ceil(size*size*DENSITY/100) do
        local x,y = math.random(size), math.random(size)
        SetValue(world, 1, x, y)
        cellMap[x][y] = 1
    end 
    ---------main sim--------------- 
    while GetReady() do
        Update(world)
        Sleep(UPDATEINTV)
        ----------rules---------------
        for i=1,size do 
            for j=1,size do
                local neighbors = GetNeighbors(i, j)
                if GetValue(world, i, j)==1 then 
                    cellMap[i][j] = neighbors>1  and neighbors<4 and 1 or 0
                else
                    cellMap[i][j] = neighbors==3 and 1 or 0
                end 
            end 
        end 
        for i=1,size do
            for j=1,size do
                SetValue(world, cellMap[i][j], i, j)
            end 
        end 
    end     
end 

這是個練蠱的遊戲,我只跑了一次,左下角那個電梯F很有意思。裡面有blinker、bolck、beehive、boat等,感興趣的同學可以自己寫個,研究研究,書中有具體的分析。不過為了論文的進度,咱們不能只玩遊戲了。