時(shí)控制:從排隊(duì)模型到Python實(shí)現(xiàn))
簡介這是2008年全國研究生數(shù)學(xué)建模競賽的獲獎(jiǎng)?wù)撐木劢钩鞘械缆方煌ㄐ盘枌?shí)時(shí)控制問題適合備戰(zhàn)數(shù)學(xué)建模比賽特別是“華為杯”的師生學(xué)習(xí)。論文面向單個(gè)交叉路口、線狀區(qū)域和網(wǎng)絡(luò)區(qū)域三類場景構(gòu)建了以總延誤時(shí)間最小為目標(biāo)的實(shí)時(shí)配時(shí)模型并給出動(dòng)態(tài)調(diào)整信號燈周期與綠信比的算法針對泊松分布車流設(shè)計(jì)了實(shí)時(shí)交通流序列生成方案通過與韋伯斯特算法及固定配時(shí)方案對比驗(yàn)證了實(shí)時(shí)算法的有效性。資源包含1個(gè)PDF文件整體約782KB內(nèi)容涵蓋摘要、問題重述、模型建立與求解、實(shí)驗(yàn)對比及對交通管理部門的應(yīng)用建議結(jié)構(gòu)完整便于研讀。已有93人學(xué)習(xí)下載適合需要參考完整賽題論文結(jié)構(gòu)、模型推導(dǎo)與算法實(shí)現(xiàn)思路的參賽者。1. 城市道路交通信號實(shí)時(shí)控制競賽論文里的建模思路為什么到今天還能用2008年全國研究生數(shù)學(xué)建模競賽的題目里有一道“城市道路交通信號實(shí)時(shí)控制問題”當(dāng)時(shí)很多人拿到題先想上復(fù)雜模型真正拿獎(jiǎng)的幾篇反而都在做同一件事把路口排隊(duì)看成隨時(shí)間變化的量用信號燈調(diào)節(jié)放水速率。我得承認(rèn)第一次讀到這個(gè)思路時(shí)覺得太簡單可后來在模擬項(xiàng)目X里復(fù)現(xiàn)了一版才發(fā)現(xiàn)這個(gè)“簡單”恰好是工程上最穩(wěn)的起點(diǎn)。這篇文章會(huì)沿著這條線講清楚排隊(duì)、延誤、綠信比之間到底怎么算怎么用Python寫一個(gè)最小實(shí)時(shí)控制算法以及從競賽仿真走到真實(shí)路口時(shí)會(huì)踩到哪些坑。適合正在做課程設(shè)計(jì)、論文仿真或者想評估自適應(yīng)信號控制值不值得上的工程人員。2. 先看模型排隊(duì)、延誤與綠信比的數(shù)學(xué)關(guān)系2.1 把路口看成一個(gè)動(dòng)態(tài)輸入輸出系統(tǒng)我第一次把信號控制問題交給新手梳理時(shí)聽到最多的答案是“能不能直接上強(qiáng)化學(xué)習(xí)”。但競賽題給的控制對象根本不需要那么重。把單個(gè)交叉口拆開本質(zhì)是一個(gè)多服務(wù)臺排隊(duì)系統(tǒng)車輛到達(dá)形成輸入綠燈放行形成輸出排隊(duì)長度就是兩者之差。用累積到達(dá)曲線A(t)和累積離開曲線D(t)表示任意時(shí)刻t的排隊(duì)車輛數(shù)就是N(t)A(t)-D(t)。D(t)不是想放多少就放多少綠燈期間它受飽和流率S限制紅燈期間D(t)基本保持水平。這個(gè)水池模型雖然簡單卻抓住了實(shí)時(shí)控制最核心的控制量每個(gè)相位獲得的有效綠燈時(shí)間g_e。g_e越大該方向累計(jì)離開曲線越陡排隊(duì)下降越快但路口的總周期是有限的給了南北方向就少了東西方向。實(shí)時(shí)控制要做的事是根據(jù)當(dāng)前各方向排隊(duì)N(t)的測量值在下一周期重新分配g_e。這一句話就是“實(shí)時(shí)”和“定時(shí)”的全部區(qū)別。要提一個(gè)容易忽略的細(xì)節(jié)到達(dá)率q和飽和流率S必須換算到同一時(shí)間單位。競賽題目里通常給的是小時(shí)流量而仿真步長是秒我見過不少人在這一步把單位搞錯(cuò)導(dǎo)致排隊(duì)一直不散。后面的代碼里我會(huì)先把每小時(shí)流量除以3600再進(jìn)入步進(jìn)循環(huán)。還有一個(gè)工程習(xí)慣到達(dá)率不要用瞬時(shí)值最好取過去5分鐘的平均否則檢測器一個(gè)抖動(dòng)就會(huì)讓算法誤判成過飽和。2.2 目標(biāo)函數(shù)最小延誤與最短排隊(duì)不是一回事很多方案把“排隊(duì)長度最短”直接當(dāng)成優(yōu)化目標(biāo)這樣做出來的配時(shí)在仿真里很漂亮現(xiàn)場卻經(jīng)常出現(xiàn)綠燈空放。原因在于排隊(duì)長度是狀態(tài)量延誤才是用戶真正感受到的損失。延誤在數(shù)學(xué)上等于排隊(duì)長度對時(shí)間的積分D∫N(t)dt也就是A(t)與D(t)曲線之間圍出的面積。兩條曲線分開的面積越大每個(gè)駕駛員平均等待越久。舉一個(gè)極端例子南北方向排隊(duì)40輛東西方向排隊(duì)10輛。如果按排隊(duì)比例分配綠燈南北會(huì)拿到接近八成的綠燈時(shí)間。但假如東西方向排隊(duì)車輛已經(jīng)等了很久南北方向是新排過來的那么按延誤積分計(jì)算東西方向反而需要優(yōu)先放行。這就是“最小化排隊(duì)長度”和“最小化延誤”在數(shù)學(xué)上的差異。競賽優(yōu)秀論文里比較穩(wěn)的寫法是把延誤作為主目標(biāo)再用排隊(duì)長度做約束或代理工程實(shí)現(xiàn)時(shí)則用排隊(duì)長度代替延誤因?yàn)闄z測器不容易直接測延誤。如果再進(jìn)一步可以把延誤按車內(nèi)人數(shù)加權(quán)比如公交相位權(quán)重放大到普通車輛的2.5倍這就有了公交優(yōu)先的雛形。競賽論文里很多隊(duì)伍在這一點(diǎn)上做文章但我建議先把不加權(quán)版本跑通再加權(quán)重不然你分不清改善來自算法還是來自權(quán)重。停車次數(shù)也可以作為目標(biāo)但它對配時(shí)變化不敏感優(yōu)化時(shí)經(jīng)常推不出穩(wěn)定梯度。我的習(xí)慣是仿真評價(jià)用延誤在線控制用排隊(duì)長度驗(yàn)收看通過量和滿載率不要只盯一個(gè)數(shù)字。2.3 約束條件周期時(shí)長、相位結(jié)構(gòu)與最小綠燈實(shí)時(shí)控制不是隨意改綠燈必須留在信號控制的基本框架里。首先是周期時(shí)長C也就是一組相位完整輪轉(zhuǎn)所需時(shí)間。C太長紅燈方向延誤變大C太短黃燈和清空時(shí)間占比變大通行能力反而下降。經(jīng)典Webster公式給了一個(gè)很好用的初始周期C0(1.5L5)/(1-Y)。其中L是一個(gè)周期的總損失時(shí)間Y是各相位關(guān)鍵流量比之和也就是每個(gè)相位到達(dá)率與飽和流率的比值中的關(guān)鍵值求和。舉個(gè)例子某個(gè)二相位路口只有南北直行和東西直行南北到達(dá)率900veh/h飽和流率1800veh/h流量比0.5東西到達(dá)率600veh/h飽和流率1800veh/h流量比0.33則Y0.83。每相位損失時(shí)間3秒L6秒。C0(1.5*65)/(1-0.83)14/0.17約82秒。這說明實(shí)時(shí)調(diào)整的周期應(yīng)當(dāng)圍繞82秒浮動(dòng)而不是每兩秒變一次周期否則損失時(shí)間會(huì)吃掉通行能力。周期之外還有幾個(gè)硬約束最小綠燈時(shí)間必須滿足行人過街和安全清空最大綠燈時(shí)間防止某個(gè)方向無限等下去黃燈和全紅清空時(shí)間一般固定不參與優(yōu)化。實(shí)時(shí)算法可以把這些約束全寫進(jìn)優(yōu)化器也可以像我后面的最小實(shí)現(xiàn)那樣先按排隊(duì)比例算綠信比再強(qiáng)制限制到最小和最大綠燈區(qū)間內(nèi)。實(shí)際路口多數(shù)時(shí)候不需要秒級最優(yōu)穩(wěn)定不犯規(guī)比極致最優(yōu)更重要。相位結(jié)構(gòu)也要先說死先放誰后放誰、左轉(zhuǎn)是否單獨(dú)放這些都是控制算法的“邊界”不是讓算法自己發(fā)明的東西。3. 用Python復(fù)現(xiàn)一個(gè)最小實(shí)時(shí)信號控制算法3.1 先定義輸入到達(dá)率、飽和流率與相位結(jié)構(gòu)在實(shí)際項(xiàng)目中輸入來自線圈檢測器、視頻檢測器或卡口數(shù)據(jù)。這里先做二相位路口的簡化演示南北方向和東西方向輪流獲得綠燈黃燈清空時(shí)間固定。代碼開頭把所有量定義清楚# city_signal.py # 一個(gè)簡化二相位路口NS 表示南北方向EW 表示東西方向 # 到達(dá)率單位 veh/h由檢測器統(tǒng)計(jì)最近5分鐘平均流量換算而來 arrival_rate {NS: 900, EW: 600} # 飽和流率單位 veh/h綠燈完全啟亮?xí)r車道能通過的最大流量 # 一般城市直行車道取 1800 左右混行或上下坡需要實(shí)測修正 sat_flow {NS: 1800, EW: 1800} # 損失時(shí)間黃燈 全紅清空單位秒 # 這個(gè)值安全相關(guān)實(shí)時(shí)控制里不壓縮 lost_time {NS: 3, EW: 3} # 初始周期單位秒可以由 Webster 公式估算后人工設(shè)定 cycle 60這段代碼只定義數(shù)據(jù)不執(zhí)行任何控制邏輯。arrival_rate是每小時(shí)的車輛數(shù)但仿真步進(jìn)要按秒算所以后面函數(shù)里我會(huì)先做一次單位換算。sat_flow是最容易被誤用的參數(shù)很多人把理想條件下的1800直接套到所有路口遇到機(jī)非混行、車道變窄、公交車??繒r(shí)實(shí)際通行能力會(huì)掉到1500甚至更低。lost_time包括黃燈和全紅清空時(shí)間它的作用是“占用周期但不產(chǎn)生有效通行”在計(jì)算綠信比時(shí)要先扣除。3.2 用時(shí)間步進(jìn)計(jì)算排隊(duì)長度和延誤有了輸入數(shù)據(jù)下一步是模擬一個(gè)周期內(nèi)排隊(duì)和延誤的變化。核心思路是逐秒推進(jìn)每一秒先讓所有方向都有新到達(dá)再只讓當(dāng)前綠燈方向放行放行量受排隊(duì)車輛數(shù)和飽和流率雙重限制def simulate_one_cycle(cycle, greens, rates, sat_rates, initial_queue, loss_times, phase_order, step1.0): # rates 和 sat_rates 先換算成 veh/s rates {ph: rates[ph] / 3600.0 for ph in rates} sat_rates {ph: sat_rates[ph] / 3600.0 for ph in sat_rates} queue dict(initial_queue) delay_area 0.0 for phase in phase_order: # 先放當(dāng)前相位的有效綠燈 for _ in range(int(greens[phase] / step)): for ph in queue: queue[ph] rates[ph] * step if ph phase: # 放行量不能超過排隊(duì)車輛數(shù)也不能超過飽和流率 discharge min(queue[ph], sat_rates[ph] * step) queue[ph] - discharge delay_area sum(queue.values()) * step # 損失時(shí)間車輛仍然到達(dá)但不允許放行 for _ in range(int(loss_times[phase] / step)): for ph in queue: queue[ph] rates[ph] * step delay_area sum(queue.values()) * step return queue, delay_area這段代碼模擬的是保守策略損失時(shí)間內(nèi)不許放行但到達(dá)還在累計(jì)。這樣排隊(duì)和延誤估計(jì)偏保守在實(shí)時(shí)控制里偏保守通常比偏樂觀安全。min(queue[ph], sat_rates[ph]*step)這行是關(guān)鍵它區(qū)分了兩種狀態(tài)當(dāng)排隊(duì)車輛小于一秒能放行的車輛數(shù)時(shí)綠燈方向在這個(gè)步長內(nèi)可以被清空不會(huì)出現(xiàn)負(fù)排隊(duì)當(dāng)排隊(duì)車輛大于飽和流率時(shí)排隊(duì)會(huì)殘留到下一秒。delay_area累加的是每個(gè)時(shí)刻所有方向排隊(duì)之和單位是veh·s也就是延誤面積這個(gè)值可以在不同配時(shí)方案之間做對比。調(diào)用時(shí)傳入一個(gè)周期內(nèi)的綠燈時(shí)長字典。注意cycle參數(shù)目前只用于約束檢查后面分配綠信比時(shí)會(huì)用到。如果想跑多個(gè)周期就把上一個(gè)周期的返回queue作為下一個(gè)周期的initial_queue這樣能觀察排隊(duì)是否會(huì)達(dá)到動(dòng)態(tài)平衡。3.3 綠信比分配把排隊(duì)長度變成綠燈時(shí)間定時(shí)控制是每個(gè)周期都按同一張綠信比表走實(shí)時(shí)控制則要根據(jù)當(dāng)前狀態(tài)每周期重算。這里我給出一個(gè)最簡單也最可解釋的分配方法按各相位當(dāng)前排隊(duì)車輛數(shù)占總排隊(duì)的比例分配可用綠燈時(shí)間同時(shí)強(qiáng)制滿足最小和最大綠燈約束def allocate_greens(queue, cycle, loss_times, min_green10, max_green60): # 扣除損失時(shí)間后真正可以分配給各相位的綠燈時(shí)間 total_loss sum(loss_times.values()) usable cycle - total_loss q_total sum(queue.values()) if q_total 0: # 沒有排隊(duì)時(shí)不能給0綠燈安全起見給最小綠燈 raw {ph: min_green for ph in queue} else: # 按排隊(duì)比例分配可用時(shí)間 raw {ph: usable * queue[ph] / q_total for ph in queue} # 限制在最小和最大綠燈之間 clipped {ph: max(min_green, min(max_green, raw[ph])) for ph in queue} # 如果剪輯后總時(shí)長超過可用時(shí)間按比例壓回去 total_clipped sum(clipped.values()) if total_clipped usable: scale usable / total_clipped greens {ph: clipped[ph] * scale for ph in queue} # 壓縮后可能又低于最小綠燈此時(shí)說明周期余量不足 # 常見處理是延長周期或者允許短時(shí)超時(shí)并記錄違規(guī) greens {ph: max(min_green, greens[ph]) for ph in queue} else: greens clipped return greens這個(gè)函數(shù)輸出的greens就是下一周期要執(zhí)行的綠燈時(shí)長。它的優(yōu)點(diǎn)是邏輯透明現(xiàn)場調(diào)試時(shí)能說清楚“為什么給了南北方向35秒”因?yàn)槟媳迸抨?duì)占比就是那么大。缺點(diǎn)是它只看了當(dāng)前時(shí)刻排隊(duì)沒有預(yù)測未來到達(dá)。如果某個(gè)方向排隊(duì)在10秒后就會(huì)自然消散算法仍然會(huì)給它大量綠燈造成空放。要修正空放一種常見做法是給每個(gè)周期設(shè)置“最小空放檢測”當(dāng)某方向排隊(duì)已經(jīng)在連續(xù)兩個(gè)步長內(nèi)降到0就提前結(jié)束該相位把剩余時(shí)間轉(zhuǎn)給下一相位或讓周期提前結(jié)束。競賽論文里很多優(yōu)秀方案都在這個(gè)細(xì)節(jié)上做文章但實(shí)際落地時(shí)我建議先把固定周期版本跑順再加動(dòng)態(tài)提前結(jié)束邏輯。另一個(gè)工程折中是低頻調(diào)整每個(gè)周期用檢測到的排隊(duì)長度算一次綠燈但限制每次調(diào)整幅度不超過6秒避免兩個(gè)連續(xù)周期的綠燈時(shí)長來回跳。4. 參數(shù)別亂調(diào)信號實(shí)時(shí)控制最關(guān)鍵的三個(gè)參數(shù)4.1 周期時(shí)長C實(shí)時(shí)調(diào)整的邊界在哪周期時(shí)長C決定了每個(gè)方向紅燈等待的上限也決定了通行能力。C太短每天的損失時(shí)間占比太高C太長某一個(gè)方向的延誤會(huì)線性上升。實(shí)時(shí)控制并不意味周期可以隨意變化我一般會(huì)把周期限制在Webster公式計(jì)算值的上下20%范圍內(nèi)。比如剛才例子算出來82秒那么周期只允許在65到98秒之間浮動(dòng)超出這個(gè)范圍就維持上一周期的取值。周期對結(jié)果的影響可以從損失時(shí)間占比理解。若周期40秒損失時(shí)間6秒損失占比15%若周期100秒損失占比只有6%??雌饋泶笾芷诟咝У笾芷跁?huì)拉長紅燈等待導(dǎo)致排隊(duì)出現(xiàn)“整波到達(dá)、整波放行”的脈沖現(xiàn)象。實(shí)際路口的周期調(diào)整還需要和相鄰路口協(xié)調(diào)單獨(dú)縮短某個(gè)路口周期可能讓上游路口綠燈末端放出的車流正好撞上本路口紅燈形成連鎖停車。所以周期不宜每周期都動(dòng)建議每5分鐘或每10分鐘調(diào)整一次。4.2 飽和流率S理論與現(xiàn)實(shí)的偏差飽和流率是排隊(duì)模型的“放水口徑”1800 veh/h只是教科書默認(rèn)值。車道寬度3.5米以下、有路邊停車、大型車混入、上下坡、雨天濕滑都會(huì)讓實(shí)際飽和流率下降。我在模擬項(xiàng)目X里遇到過一件事把某路口的飽和流率按1800代入算法算出來的綠燈時(shí)間總是偏短排隊(duì)在高峰期間不斷累積后來實(shí)測發(fā)現(xiàn)該車道的飽和流率只有1500因?yàn)楣徽倦x停車線太近公交車??繒r(shí)直接堵掉一條車道。校準(zhǔn)飽和流率不需要專業(yè)設(shè)備。在綠燈啟亮后統(tǒng)計(jì)連續(xù)通過停車線的車頭時(shí)距去掉前兩輛啟動(dòng)延遲的數(shù)據(jù)取穩(wěn)定段的平均值再用3600除以平均車頭時(shí)距就得到該車道的實(shí)際飽和流率。注意要分車道統(tǒng)計(jì)左轉(zhuǎn)車道和直行車道的飽和流率差別很大。另一個(gè)容易被忽略的點(diǎn)是飽和流率還會(huì)隨時(shí)間變化晚高峰比早高峰低雨天比晴天低。實(shí)時(shí)控制里最好按天氣和工作日/節(jié)假日分別標(biāo)定一組參數(shù)不要一組參數(shù)跑一年。4.3 最小綠燈時(shí)間安全約束是隱形天花板最小綠燈時(shí)間不是算法參數(shù)是安全底線。它取決于行人過街時(shí)間和車輛清空時(shí)間行人過街需要的最小綠燈約等于過街距離除以行人步行速度老年人多的區(qū)域步行速度要按1.0 m/s甚至更低來算左轉(zhuǎn)車輛清空還需要黃燈前已經(jīng)進(jìn)入路口但還沒通過的車輛駛離。這個(gè)約束直接卡死了實(shí)時(shí)算法的優(yōu)化空間。舉例來說一條雙向六車道的路過街距離約21米按1.2 m/s步行速度算需要17.5秒加上綠燈啟亮后行人反應(yīng)時(shí)間最小綠燈至少20秒。如果算法算出來該相位只需要12秒就能放空排隊(duì)那也必須給滿20秒多出來的8秒就造成空放。這是實(shí)時(shí)控制里最無奈的一類空放它不是算法缺陷而是交通法規(guī)和人因工程強(qiáng)制的開銷。做方案時(shí)要把這部分時(shí)間列為固定損失不要在驗(yàn)收時(shí)把它算作算法失敗。下面是三個(gè)參數(shù)的調(diào)試對照表實(shí)際排障時(shí)按這個(gè)順序查參數(shù)推薦范圍設(shè)定依據(jù)過大后果過小后果周期時(shí)長CWebster值±20%流量比與損失時(shí)間紅燈延誤增大脈沖到達(dá)損失占比高通行能力下降飽和流率S實(shí)測值±5%車頭時(shí)距標(biāo)定綠燈時(shí)間不足排隊(duì)持續(xù)增長綠燈空放周期被浪費(fèi)最小綠燈G_min20秒以上行人過街與清空時(shí)間空放增加周期延長行人安全風(fēng)險(xiǎn)清空不徹底5. 實(shí)時(shí)信號控制避坑指南五條血淚經(jīng)驗(yàn)5.1 檢測器數(shù)據(jù)毛刺導(dǎo)致綠燈時(shí)長來回跳現(xiàn)象前后兩個(gè)周期的綠燈時(shí)長差距超過15秒路口整體通行節(jié)奏混亂駕駛員剛習(xí)慣原來配時(shí)就被打斷。原因檢測器原始數(shù)據(jù)含大量毛刺比如視頻檢測在強(qiáng)光或陰影下會(huì)把一輛車識別成多輛車或者線圈檢測在車輛緩慢通過時(shí)產(chǎn)生重復(fù)觸發(fā)。直接用原始排隊(duì)長度參與分配算子會(huì)把一個(gè)異常峰值當(dāng)作真實(shí)需求。解決進(jìn)入分配函數(shù)之前先把排隊(duì)序列做指數(shù)平滑。我常用的系數(shù)是0.3到0.4也就是當(dāng)前值占三成歷史平滑值占七成。另一個(gè)辦法是采用周期中段采樣在綠燈結(jié)束前5秒讀取排隊(duì)避開剛變燈時(shí)的不穩(wěn)定讀數(shù)。平滑會(huì)損失一點(diǎn)響應(yīng)速度但對真實(shí)路口的收益遠(yuǎn)大于損失。如果發(fā)現(xiàn)毛刺仍然明顯檢查檢測器安裝位置和閾值配置這是數(shù)據(jù)質(zhì)量問題算法救不回來。5.2 排隊(duì)長度估計(jì)偏大原因是時(shí)間窗沒對齊現(xiàn)象算法認(rèn)為南北方向排隊(duì)已經(jīng)溢到上游路口實(shí)際監(jiān)控畫面里排隊(duì)不到20米導(dǎo)致南北相位被連續(xù)給了好幾個(gè)長綠燈東西方向等得怨聲載道。原因排隊(duì)檢測時(shí)刻和信號狀態(tài)沒對齊。如果排隊(duì)檢測點(diǎn)設(shè)在停車線上游80米處車輛正好在紅燈期間排隊(duì)那么讀取到的排隊(duì)包含了本周期剛到達(dá)的車這些車本來就不可能立刻走把它當(dāng)成“壓車”是錯(cuò)誤的。解決把采樣時(shí)刻統(tǒng)一到綠燈結(jié)束前最后一個(gè)步長這時(shí)候排隊(duì)反映的是本周期未被放行的殘留需求最能代表下一個(gè)周期的分配依據(jù)。如果是視頻檢測還要注意檢測區(qū)域是否包含對向待轉(zhuǎn)區(qū)待轉(zhuǎn)區(qū)的車會(huì)被誤判成方向排隊(duì)。這個(gè)問題在競賽仿真里幾乎不會(huì)出現(xiàn)因?yàn)榉抡胬镒x取的是真值而現(xiàn)場檢測器有布設(shè)位置誤差。5.3 仿真效果很好現(xiàn)場卻排隊(duì)溢出現(xiàn)象同一套參數(shù)在仿真里延誤下降20%到了真實(shí)路口反而把排隊(duì)溢回上游相鄰路口的通行能力被倒灌的車流鎖死。原因仿真里的排隊(duì)長度沒有上限車輛可以無限排在任何位置真實(shí)路口的排隊(duì)受路段長度限制溢出后會(huì)把上游路口或相鄰車道的出口堵死。很多競賽論文并沒有建模這個(gè)容量約束因?yàn)轭}目沒有要求但落地時(shí)這恰恰是最致命的一環(huán)。解決給每個(gè)方向的排隊(duì)模型增加容量上限溢出部分直接計(jì)入懲罰。比如某路段只能容納40輛車排隊(duì)超過40輛時(shí)本路口算法必須強(qiáng)制增加該方向綠燈哪怕其他方向延誤上升。更進(jìn)階的做法是讓溢出的方向向協(xié)調(diào)控制模塊發(fā)信號觸發(fā)上游路口截流。沒有容量約束的排隊(duì)模型只能作為理論研究不能直接當(dāng)現(xiàn)場方案。5.4 相位切換時(shí)清空時(shí)間不足造成二次排隊(duì)現(xiàn)象左轉(zhuǎn)綠燈結(jié)束后還有兩三輛左轉(zhuǎn)車滯留在路口中央對向直行已亮綠燈兩股車流在路口內(nèi)互相干擾整個(gè)路口效率驟降。原因?qū)崟r(shí)控制為了省時(shí)間把黃燈和全紅時(shí)間壓縮到接近0。黃燈不是可自由壓縮的損失時(shí)間它是給“已經(jīng)越過停車線但還沒通過路口”的車輛的安全清空期。壓縮清空時(shí)間省下兩三秒代價(jià)是路口內(nèi)部的交通沖突。解決把清空時(shí)間固定為常量完全不參與優(yōu)化。每個(gè)相位切換之前檢查該相位是否已經(jīng)清空可以在綠燈末尾加一個(gè)“滑窗判斷”如果最后3秒的通過流量明顯下降再?zèng)Q定是否提前結(jié)束。這個(gè)邏輯不壓縮清空時(shí)間只壓縮有效綠燈的尾部空放段安全上沒問題。血的教訓(xùn)是不要為了仿真里的延誤數(shù)字去動(dòng)全紅時(shí)間除非你想在驗(yàn)收現(xiàn)場看追尾。5.5 用了延誤目標(biāo)優(yōu)化結(jié)果反而更卡現(xiàn)象算法報(bào)告平均延誤下降了但路口總體通過量也下降了排隊(duì)總長度沒有明顯改善駕駛員體感更差。原因延誤目標(biāo)天然傾向于“把已有的排隊(duì)先清空”因?yàn)樗Wo(hù)的是排隊(duì)面積大的方向。如果某個(gè)方向排隊(duì)時(shí)間久但車輛少延誤積分也會(huì)很大算法會(huì)優(yōu)先給它放行結(jié)果放空后該方向接下來根本沒有車形成空放真正有持續(xù)車流的另一個(gè)方向卻被壓住通過量自然下降。解決把目標(biāo)里加入“通過量”或“放空懲罰”。我常用的做法是在分配綠信比時(shí)先留出8%的可用時(shí)間給絕對主流量方向再對剩余時(shí)間做延誤優(yōu)化。這樣既保留延誤目標(biāo)的好處又避免空放型振蕩。驗(yàn)收時(shí)不要只看延誤要同時(shí)看通過量和排隊(duì)溢出次數(shù)三個(gè)指標(biāo)一起對比才有說服力。競賽里只看延誤的排名沒問題工程現(xiàn)場要看的是運(yùn)行穩(wěn)定性。6. 從競賽論文到現(xiàn)場方案驗(yàn)證與進(jìn)階技巧競賽論文和現(xiàn)場方案的差距主要在驗(yàn)證方法上。拿到一個(gè)實(shí)時(shí)信號控制算法我建議先做固定周期對照實(shí)驗(yàn)選同一路口、同一時(shí)段、同一方向的車流數(shù)據(jù)前一周固定配時(shí)后一周實(shí)時(shí)配時(shí)其他條件盡量不變。對比指標(biāo)選三個(gè)平均延誤、路口總通過量、排隊(duì)溢出次數(shù)。只報(bào)延誤下降是危險(xiǎn)的因?yàn)檠诱`指標(biāo)可以被空放策略“優(yōu)化”得很漂亮。驗(yàn)證時(shí)還要注意樣本量。高峰期交通流每天都不一樣至少要取10個(gè)工作日的數(shù)據(jù)做配對比再用非參數(shù)檢驗(yàn)看差異是否顯著。我見過有人拿了三天數(shù)據(jù)就下結(jié)論結(jié)果第四天一個(gè)雨天全部翻盤。另一個(gè)習(xí)慣是先做“零基線”把實(shí)時(shí)控制算法的調(diào)整幅度調(diào)成0讓它完全按照原固定配時(shí)運(yùn)行確認(rèn)代碼本身不會(huì)引入額外排隊(duì)損耗。這一步能幫你把數(shù)據(jù)采集問題和算法問題分開。進(jìn)階方向上這套排隊(duì)模型可以從單路口擴(kuò)展到相鄰兩三個(gè)路口把下游路口的排隊(duì)長度作為上游路口的配時(shí)輸入?yún)f(xié)調(diào)兩條路的相位差。更實(shí)際的應(yīng)用是給公交車一個(gè)權(quán)重系數(shù)在公交車接近路口時(shí)動(dòng)態(tài)延長綠燈這是競賽里“多目標(biāo)”的自然延伸。但要注意所有進(jìn)階都建立在狀態(tài)檢測穩(wěn)定、基礎(chǔ)參數(shù)校準(zhǔn)完畢的前提下不要在數(shù)據(jù)沒做平滑時(shí)就去調(diào)公交優(yōu)先否則你會(huì)分不清是算法的問題還是數(shù)據(jù)的問題。希望這套從排隊(duì)模型到最小實(shí)現(xiàn)的路徑能幫到你至少在下一次面對信號控制問題時(shí)你知道先看哪個(gè)參數(shù)出了狀況先查哪個(gè)環(huán)節(jié)。本文還有配套的精品資源點(diǎn)擊獲取