多くのドライバーにとって交通渋滞は苦痛な現象である。苦痛となる要因は主に中々前に進めないもどかしさと、ブレーキによるストレスだと思われる。現在、 交通渋滞に関する研究が進んでいるが、渋滞を消滅させることはできていない。極端なことを言えば、ドライバー全員が同時に発車、加速、停車をすれば渋滞は発生しないが、そのようなことは不可能だろう。なぜなら、個々で運転の仕方が異なるからである。のろのろ進む車が速度の速い車にスピードを合わせるべきという意見がある。それゆえ、速度の遅い車が渋滞に悪影響を与えているという声がよく挙がるが、果たしてそうだろうか。
そこで、netlogoという自然と社会現象をシミュレーションできるプログラム環境を用いることで、渋滞を再現する。本研究では心理的要素を取り入れ、ドライバーを3種類に分けた。また、そのタイプの混在が渋滞の原因に関係があるという仮説をnetlogoというシミュレーション環境を用いて立証することを目的とした。
渋滞とは、NEXCOでは時速40キロメートル程度以下で低速走行あるいは低発進を繰り返す車列が、長さ1キロメートル程度以上かつ15分以上継続した状態、と定められている。[1]
ある区間に、車がどれだけいるのかを表す量を密度とする。密度と速度には図1のような関係があり、曲線の頂点を臨海密度と呼ぶ。また、渋滞に関して次のようなことを定義されている。密度が臨海密度以上のときが、渋滞している状態である。非渋滞時では密度が増加すると、比例して速度も増加するという関係がある。渋滞時では密度が増加すると、速度は低下する。渋滞時の関係を以下の式で表すことができる。
y=a^2/x
図1. 速度と密度の関係
NetLogoは自然現象や社会現象をシミュレーションするためのプログラム可能なモデリング環境である。NetLogoはLogoやStarLogoなどのマルチエージェントモデリング言語群を基にした次世代の環境である。
NetLogoでは、「タートル」と呼ばれるNetlogoの世界の中心的な役割を担うオブジェクトを画面上に表示できる。また、数千のタートルを制御でき、さらに各タートルは命令を並列に実行できる。特にnetlogoではタートルの活躍を助長する「パッチ」と呼ばれるセルオートマトンがある。これはタートル同様、命令を実行することができる。パッチは移動することはできないが、各々整数の座標を持っている。タートルはこのパッチの上を移動する。これらのパッチやタートルをコントロールする「オブザーバ」と呼ばれるものがある。オブザーバはタートルを新しく作ったり、タートルやパッチの活動を常に監視している。利用者は、ボタンなどに関連付けられたオブザーバのプログラムを用いてプログラムを操作する。
本稿では、ドライバーの運転心理を積極心理型、消極型心理、環境依存型心理の3つに分け、車の運転モデルとして定義する。それぞれの運転心理の説明は以下に行う。一方、各車に「patience」という変数を実装した。このpatienceはブレーキを踏み、減速する度に-1される。patienceが0になると、その車は車線変更をする。patienceが0に近いほど、そのドライバーはストレスを感じているということである。
積極型心理は早く目的地に着きたいために、速い運転をしようとする心理で、前方に車がいるときは、隣の車線が空いていれば車線変更を行って走行しようとする。前方、隣の車線が共に空いていなければ、減速する。強気やせっかちな性格や急いで走ろうとする運転手が積極型心理の対象となる。また、スポーツカーのような速い速度で走る車や走り屋と呼ばれるようなドライバーもこの対象である。
積極型心理は、全ての車線において加速・減速・車線変更を実行する。これらの行動は、周りに車が存在するかどうかで決定される。それぞれの状況における行動を図2に示す。
図2. 積極型心理の行動パターン
積極型心理のドライバーは、パターン1やパターン4のように、周りに車が存在しなければ、どの車線においても加速を行う。また、パターン3やパターン6のように、前方は空いているが隣の車線に車が存在する場合は加速を行う。一方、パターン2やパターン5のように、前方に車が存在する場合は減速を行う。また、隣の車線が空いているときは車線変更を行う。
消極型心理は、常に左側車線を走り続ける。生真面目な性格や安全運転を意識する運転手が消極型心理の対象となる。
消極型心理の行動を図3に示す。
図3. 消極型心理の行動パターン
消極型心理はどんな状況であろうが常に走行車線を走行する。前方に車が存在しなければ加速を行う。一方、前方に車が存在するときは減速を行う。このとき隣の車線が空いている場合でも、車線変更はしない。
周りの状況に応じて適切な運転を試みようとする心理で、混雑していると判断した状況下では周りに合わせて走行を試み、混雑でないと判断した状況では加速を試みる。運転慣れや協調性のある運転手であり、最も一般的なものである。
本実験では、周りの状況に応じて積極型心理と消極型心理に移行する。まず、自身が走行車線にいるか判断をし、追い越し車線なら積極型心理に移行する。走行車線の場合、前方に車がいるかどうか判断し、前方が空いているなら消極型心理へ移行する。前方が空いていない場合、追い越し車線前方に車がいるかどうか判断し、空いていないなら消極型心理へ移行する。追い越し車線前方が空いているなら積極型心理へ移行する。環境依存型心理のフローチャートを図4に示す。
図4. 環境依存型のフローチャート
netlogoのシステムは、インターフェイスタブ、情報タブ、コードタブの三つから構成されている。インターフェイスタブでは、パラメータを設定するためのスライダやボタン、数値をプロットできるグラフ、モニタなどが配置されている。また、タートルの動きを表示できるワールドウィンドウがある。情報タブでは、このモデルが何なのか、どのように使用すればよいのかなどの説明が記載されている。コードタブでは、ソースコードが記述されている。
インターフェイスタブを図5に示す。
図5. インターフェイス
図5に示されているタブはシミュレーションを実行するタブであり、ここには様々なUIが設置されている。UIには、ボタン、スライダ、モニタ、プロットなどがある。スライダは主に、変数の数値を設定することができる。本実験では積極型、消極型、環境依存型の車の車両数や、加速度、減速度、patienceなどの変数を設定できる。モニタは指定した変数の表示、プロットは時系列データの表示をしている。これらのインターフェイスのおかげで、時系列的に変化する平均速度や密度を観察することができる。ボタンは、主にシミュレーションの実行を開始するトリガーである。
netlogoのシミュレーションは、基本的にsetupボタンとgoボタンによって実行される。setupボタンを押すと、コードタブに記述されているto setupが実行される。setupのプログラムコードを図6に示す。
図6. setup
clear-allはタートル、パッチ、plotの描画などすべてを初期化する命令である。set-default-shape turtles”car”は、生成されたタートルの形を車に描きなおしている。draw-roadはパッチの配置、つまり道路の描画を行っている。create-or-remove-carsでは、タートルの生成を行っている。各タートルの具体的な数は、スライダーにて設定する。reset-ticksはtickの値を0にしている。tickは並列に命令を実行できるシステムの役割を果たしている。例えば、処理を終えたturtle 0はturtle 1の処理を終えるまで待機し、turtle 1の処理が終わると描画が行われる。この一連の動作が1ticksである。つまりtickはタートルやパッチの同期を行っているのである。インターフェイスタブのsetupボタンのとなりにgo onceボタンがあるが、これはtickを1だけ進めることができるボタンである。
次にgoボタンであるが、こちらも同様にボタンを押すとコードタブのto goが実行される。to goではタートル達への命令が記述されている。goボタンを押すことにより、タートルの行動が開始される。
次に各タイプのプログラムについて説明する。積極型心理の車のプログラムコードを図7に示す。
図7. 積極型心理のプログラム
patienceは全車が持っている変数で、この値が0になるとその車は車線変更を行う。一方、消極型心理のプログラムにはif patience <= 0 [choose-new-lane]が無い。この違いにより積極型心理と消極型心理の差別化を行っている。
環境依存型心理の車のプログラムコードを図8に示す。
図8. 環境依存型心理のプログラム
car-aheadは前方にいる車を、car-overは追い越し車線前方にいる車を表している。ここの記述は、図4のフローチャートの通りである。posi-nomalは積極型心理へ、nega-nomaは消極型心理への移行を表している。posi-nomalは図7のpositiveのプログラムに、後ろに車が存在するならpatienceを1減らす、という命令を追加している。
積極型心理の車と、環境依存型心理の車の比率を変えて実験を行う。まず積極型心理の車を0%に設定してシミュレーションを実行させ、積極型を10%ずつ増加させていき、100%まで増加させる。車の合計数は20とする。
高速道路の長さは40パッチ分、車の長さは1パッチ分である。車の最高速度は積極型心理が0.40とした。この0.40とは、1ticksで0.40パッチ分前方に移動するということである。また、環境依存型心理が0.35としている。加速度は0.005、減速度は0.01、patienceの最大値は30と設定した。
積極型心理:環境依存型心理=0%:100%の場合を図9に示す。
図9. 積極型心理:環境依存型心理=0%:100%の場合
積極型心理:環境依存型心理=10%:90%の場合を図10に示す。
図10. 積極型心理:環境依存型心理=10%:90%の場合
積極型心理:環境依存型心理=80%:20%の場合を図11に示す。
図11. 積極型心理:環境依存型心理=80%:20%の場合
積極型心理:環境依存型心理=90%:10%の場合を図12に示す。
図12. 積極型心理:環境依存型心理=90%:10%の場合
図9では、平均速度にバラつきがほぼ見られず、速度が変化していない。ゆえに渋滞が無く、滞りなく走行できていることが分かる。図12も同様に渋滞が起きていないことが言えるだろう。一方、図10と図11では平均速度にバラつきが見える。これは先程とは逆に、速度を上げたり落としたりを繰り返しているので、気持ちよく走行できていないということである。小さな渋滞が発生していることを表しているだろう。
図9と図12では、平均速度にバラつきが見られず渋滞の発生も確認できなかった。図9では環境依存型心理の車の割合が100%であり、図12では積極型心理の車の割合が90%であった。よって、車の割合が積極型心理の車、または環境依存型心理の車に偏重する場合、平均速度にバラつきがないと言える。
図10と図11では、平均速度にバラつきが現れた。図10は、積極型の割合が10%、環境依存型の割合が90%であり、図9の場合より積極型の割合が10%高くなっている。図11は、積極型の割合が80%、環境依存型の割合が20%であり、図12の場合より環境依存型の割合が10%高くなっている。よって、もう一方のタイプの車の割合が増えると、平均速度にバラつきが現れることが分かる。
以上のことから、複数タイプが混在すると、道路交通に悪影響を与えやすいということが言えるだろう。
本実験では、ドライバーが複数タイプ存在していることが渋滞の原因である、という仮説を立証するために実験を行った。その結果、積極型心理と環境依存型が混在すればするほど速度にバラつきが現れる、という結果を得られた。これは複数のタイプの混在が渋滞に影響を与えることを意味している。
しかし今回は消極型心理の車には触れなかったし、現実の交通事情はもっと複雑であるため、この仮説を世間に強要することはできない。今後の研究として運転心理の見直しや、道路の形状を考慮することが重要である。
1 globals [
2 selected-car
3 lanes
4
5 density
6 mean-density
7 sum-density
8 mean-pat
9 sum-pat
10 mean-speed
11 sum-sp
12 ]
13
14 breed[positivecars positivecar]
15 breed[negativecars negativecar]
16 breed[nomalcars nomalcar]
17
18 turtles-own [
19 speed
20 top-speed
21 target-lane
22 patience
23 ]
24
25 to setup
26 clear-all
27 set-default-shape turtles "car"
28 draw-road
29 create-or-remove-cars
30 set sum-pat 0
31 reset-ticks
32 end
33
34 to create-or-remove-cars
35
36 let road-patches patches with [ member? pycor lanes ]
37 if number-of-positivecars + number-of-negativecars
38 + number-of-nomalcars & count road-patches [
39 set number-of-negativecars count road-patches
40 ]
41
42 create-positivecars (number-of-positivecars - count positivecars) [
43 set color red
44 move-to one-of free road-patches
45 set target-lane pycor
46 set heading 90
47 set top-speed 0.4 + random-float 0.1
48 set speed 0.3
49 set patience random max-patience
50 ]
51 create-negativecars (number-of-negativecars - count negativecars)[
52 set color blue
53 move-to one-of free road-patches with[pycor = 1]
54 set target-lane 1
55 set heading 90
56 set top-speed 0.3 + random-float 0
57 set speed 0.2
58 set patience random max-patience
59 ]
60 create-nomalcars (number-of-nomalcars - count nomalcars) [
61 set color green
62 move-to one-of free road-patches
63 set target-lane pycor
64 set heading 90
65 set top-speed 0.35 + random-float 0
66 set speed 0.25
67 set patience random max-patience
68 ]
69
70 if count turtles > number-of-positivecars
71 + number-of-negativecars + number-of-nomalcars [
72 let n count turtles - number-of-positivecars
73 - number-of-negativecars - number-of-nomalcars
74 ask n-of n [ other turtles ] of selected-car [ die ]
75 ]
76
77 end
78
79 to-report free [ road-patches ]
80 let this-car self
81 report road-patches with [
82 not any? turtles-here with [ self != this-car ]
83 ]
84 end
85
86 to draw-road
87 ask patches [
88 set pcolor green - random-float 0.5
89 ]
90 set lanes n-values number-of-lanes
91 [ n -> number-of-lanes - (n * 2) - 1 ]
92 ask patches with [ abs pycor <= number-of-lanes ] [
93 set pcolor grey - 2.5 + random-float 0.25
94 ]
95 draw-road-lines
96 end
97
98 to draw-road-lines
99 let y (last lanes) - 1
100 while [ y <= first lanes + 1 ] [
101 if not member? y lanes [
102 ifelse abs y = number-of-lanes
103 [ draw-line y yellow 0 ]
104 [ draw-line y white 0.5 ]
105 ]
106 set y y + 1
107 ]
108 end
109
110 to draw-line [ y line-color gap ]
111 create-turtles 1 [
112 setxy (min-pxcor - 0.5) y
113 hide-turtle
114 set color line-color
115 set heading 90
116 repeat world-width [
117 pen-up
118 forward gap
119 pen-down
120 forward (1 - gap)
121 ]
122 die
123 ]
124 end
125
126 to go
127 ask turtles with [color = red][positive]
128 ask turtles with [color = blue][negative]
129 ask turtles with [color = green][nomal]
130
131
132 set density count turtles with[pxcor < -12]
133
134 let den mean [density] of turtles
135 set sum-density sum-density + den
136 set mean-density sum-density / ((ticks mod 20) + 1)
137 if (ticks + 1) mod 20 = 0[set sum-density 0]
138 if (ticks + 1) mod 20 = 0[set mean-density 0]
139
140 let pat mean [patience] of turtles
141 set sum-pat sum-pat + pat
142 set mean-pat sum-pat / (ticks + 1);mean patienceの平均
143
144 let sp mean [speed] of turtles
145 set sum-sp sum-sp + sp
146 set mean-speed sum-sp / (ticks + 1);mean speedの平均
147
148 tick
149 end
150
151 to reset-patience
152 set patience max-patience
153 end
154 to low-patience
155 if patience <= 0[set patience 1]
156 end
157 to decrease-patience
158 set patience patience - 1
159 if patience <= 0[set patience 0]
160 end
161
162 to positive
163 move-forward
164 if patience <= 0 [ choose-new-lane ]
165 if ycor != target-lane [ move-to-target-lane ]
166 end
167
168 to negative
169 move-forward
170 if ycor != target-lane [ move-to-target-lane ]
171 end
172
173 to nomal
174 let car-ahead one-of nomalcars-on patch-ahead 1
175 let car-over one-of nomalcars-on patch-at 1 -2
176
177 if car-over != nobody
178 [set speed [speed] of car-over slow-down-car]
179 ifelse ycor != 1 ;走行車線かどうかを判定
180 [posi-nomal]
181 [ifelse car-ahead = nobody
182 [nega-nomal]
183 [ifelse car-over != nobody
184 [nega-nomal]
185 [posi-nomal]]]
186 end
187
188 to posi-nomal
189 let car-back one-of nomalcars-on patch-ahead -1
190 move-forward
191 if patience <= 0 [ choose-new-lane ]
192 if ycor != target-lane [ move-to-target-lane ]
193 if car-back != nobody [decrease-patience]
194 end
195
196 to nega-nomal
197 move-forward
198 if ycor != target-lane [ move-to-target-lane ]
199 end
200
201 to move-forward
202 set heading 90
203 speed-up-car
204 let blocking-cars other turtles in-cone (1 + speed * 3) 180
205 with [ y-distance <= 1 ];
206 let blocking-car min-one-of blocking-cars [ distance myself ]
207 ifelse blocking-car != nobody [
208 set speed [ speed ] of blocking-car
209 slow-down-car
210 decrease-patience
211 ]
212 [low-patience
213 if speed = top-speed[reset-patience]]
214 forward speed
215 end
216
217 to slow-down-car
218 set speed (speed - deceleration )
219 if speed < 0 [ set speed 0 ]
220 end
221
222
223
224 to speed-up-car
225 set speed (speed + acceleration)
226 if speed > top-speed [ set speed top-speed ]
227 end
228
229 to choose-new-lane
230 let other-lanes remove ycor lanes
231 if not empty? other-lanes [
232 let min-dist min map [ y -> abs (y - ycor) ] other-lanes
233 let closest-lanes filter [ y -> abs (y - ycor) = min-dist ] other-lanes
234 set target-lane one-of closest-lanes
235 ]
236 end
237
238 to move-to-target-lane
239 set heading ifelse-value (target-lane < ycor) [ 180 ] [ 0 ]
240 let blocking-cars other turtles
241 in-cone (1 + abs (ycor - target-lane)) 180 with [ x-distance <= 1 ]
242 let blocking-car min-one-of blocking-cars [ distance myself ]
243 ifelse blocking-car = nobody [
244 forward 0.2;妨害者がいなければ0.2進む
245 set ycor precision ycor 1
246 ] [
247 ifelse towards blocking-car <= 180
248 [ slow-down-car ] [ speed-up-car ]
249 ]
250 end
251
252 to-report x-distance
253 report distancexy [ xcor ] of myself ycor
254 end
255
256 to-report y-distance
257 report distancexy xcor [ ycor ] of myself
258 end
259
260
261 to-report car-color
262 report one-of [ blue cyan sky ] + 1.5 + random-float 1.0
263 end
264
265 to-report number-of-lanes
266 report 2
267 end
1行目から12行目では、グローバル関数を宣言している。14行目から16行目までのbreedは品種に関するエージェント集合を定義している。18行目から23行目までのturtles-ownは、各タートルが保有する変数を定義している。
25行目から32行目までのto setupはsetupボタンのプログラムで、setupボタンを押すことによりこのプログラムが実行される。プログラムの内容は2.4.3の通りである。
34行目から77行目までは、 create-or-remove-carsという関数の中身である。ここでは主にタートルの生成を行う。letは新しいローカル変数を宣言する。36行目から40行目では、lanesのy座標と同じ座標のパッチをroad-patchesとして宣言している。全車両がroad-patches、つまり道路のパッチ数より多くなった場合、消極型心理の車を道路のパッチ数と同じにする処理をしている。
42行目から50行目までは積極型心理の車の生成、51行目から59行目までは消極型心理の車の生成、60行目から68行目までは環境依存型心理の車の生成を行う。積極型心理の車、消極型心理の車、環境依存型心理の車をそれぞれパラメータ付きで生成している。
70行目から75行目では、数えたタートルの数が、設定したタートルの数より多くなった場合、余分なタートルを消滅させるという処理を行っている。
79行目から84行目では、タートルがランダムに設置されたとき、2つ以上のタートルが同じパッチ上に存在してしまう状況を排除する処理をしている。
86行目から96行目では、芝生と道路の描画を行っている。今回は二車線なので道路の幅は3パッチ分である。95行目のdraw-road-linesは、98行目から108行目までの関数を呼び出している。
98行目から108行目までのdraw-road-lines関数と110行目から124行目までのdraw-line関数では、道路の白色の破線、黄色の連続線を描画する。今回は1匹のタートル生成し、道路に破線と連続線を描画している。
126行目から149行目は、goボタンのプログラムである。127行目から129行目までは、各タイプの車にpositive関数、negative関数、nomal関数を呼び出させている。
132行目から146行目では密度、patience、speedの値をインターフェイスのモニタやプロットに表示させる処理を行っている。148行目のtickは、tickを1進めるという処理を行う。
151行目から160行目ではpatienceの内部処理について記述されている。reset-patience関数は、patienceの値を最大値にする。Low-patience関数は、pacienceの値が0以下の場合patienceに1を代入する。decrease-patience関数は、pactienceの値から1を引き、また、patineceの値が0以下の場合patienceに0を代入する。
162行目から166行目までは積極型心理の車の処理内容である。後ほど説明するmove-forward関数を呼び出す。また、patienceの値が0以下ならば車線変更をする。
168行目から171行目までは消極型心理の車の処理内容である。積極型心理と同様にmove-forward関数を呼び出す。消極型心理は車線変更を行わないのでpatienceの処理は無い。
173行目から186行目までは環境依存型心理の車の処理内容である。174行目のcar-aheadには実行を行っているタートルのx座標+1のエージェント集合を、175行目のcar-overには実行を行っているタートルからx座標+1、y座標-2のエージェント集合をそれぞれ代入している。car-aheadは自身の前方、car-overは追い越し車線前方のタートルを代入しているということである。
177行目から186行目まででは、環境依存型心理が積極型に移行するか、消極型に移行するか判定を行っている。181行目では前方にタートルが存在しなければ消極型に移行するという処理を行っている。
188行目から194行目までは環境依存型心理の車が積極型心理に移行した時の処理内容を、196行目から199行目までは消極型心理に移行した時の処理内容を記述している。193行目では自身の1パッチ後ろにタートルが存在するなら、decrease-patienceを呼び出させている。
201行目から215行目まではmove-forward関数である。move-forward関数は全タートルに呼び出される関数であり、車の基本的な動きを再現するための処理内容が記述されている。202行目のset heading 90はnetlogoの世界で真東に、タートルの向きを変えさせている。また、204行目と205行目では、タートルに角度は180度で(1+speed*3)パッチ分の視野を与えている。
簡単に言えばこの関数では、タートルの視野の範囲に他のタートルが存在するなら減速、他のタートルが存在しないなら加速、という処理を行わせている。
217行目から220行目までは減速の処理内容が記述されている。224行目から227行目までは加速の処理内容が記述されている。
229行目から250行目までは車線変更の処理内容が記述されている。
252行目から254行目は自身から相手のx座標の距離を、256行目から258行目は自身から相手のy座標の距離を測定するための処理である。
261行目から263行目は車の色を青色に設定する処理を行っているが、今回は使用しなかった。
265行目から267行目は車線の数を指定できる。今回は二車線道路の再現であったので、report 2としている。