1 | \def \obr {05_AlgorithmDescription/fig/} |
---|
2 | \lstset{language=[Visual]C++,showstringspaces=false,numbers=left, numbersep=0pt, tabsize=4, breaklines, breakautoindent=false, captionpos=b} |
---|
3 | \chapter{Popis implementace} |
---|
4 | |
---|
5 | |
---|
6 | |
---|
7 | \section{Použité knihovny} |
---|
8 | |
---|
9 | \subsection{IT++} |
---|
10 | IT++ je knihovna jazyka C++ zahrnující třídy pro matematické výpočty a komunikaci. |
---|
11 | Umožňuje práci s vektory a maticemi podobným způsobem jako v nástroji MATLAB. |
---|
12 | Použity jsou třídy \texttt{vec} a \texttt{Array}. |
---|
13 | |
---|
14 | |
---|
15 | \subsubsection{Třída vec} |
---|
16 | Třída \texttt{vec} reprezentuje vektor hodnot číselného typu \texttt{double}. |
---|
17 | Přetížením operátorů kulatých a hranatých závorek a operátoru \texttt{=} umožňuje jednoduchou inicializaci |
---|
18 | vektoru pomocí textového řetězce a zjednodušuje přístup k jednotlivým hodnotám. |
---|
19 | Kód |
---|
20 | \begin{lstlisting} |
---|
21 | vec a = "0.1 0.2 0.3"; |
---|
22 | cout << a(0) << endl; |
---|
23 | cout << a[1] << endl; |
---|
24 | \end{lstlisting} |
---|
25 | inicializuje vektor o dimenzi 3 s hodnotami 0,1, 0,2 a 0,3 a poté |
---|
26 | vypíše první a druhý prvek vektoru. |
---|
27 | |
---|
28 | \subsubsection{Třída Array} |
---|
29 | Tato šablonová třída umožňuje pracovat s polem o proměnných předem daného libovolného typu. |
---|
30 | Rozměr pole se může v průběhu programu měnit. |
---|
31 | |
---|
32 | |
---|
33 | \subsection{BDM} |
---|
34 | Knihovna BDM (Bayesian Decision Making) je navržena pro programy používající |
---|
35 | Bayesovu statistiku. Zde jsou použity hlavně třídy \texttt{Datalink}, \texttt{RV}, \texttt{UI} a \texttt{Setting} |
---|
36 | sloužící pro komunikaci s mikrosimulátorem AIMSUN, načítání hodnot z konfiguračních souborů a komunikaci mezi agenty. |
---|
37 | \\ |
---|
38 | \\ |
---|
39 | V knihovně BDM je také definována třída \texttt{Participant}, implementující metody pro komunikaci |
---|
40 | , od které je odvozena třída našeho agenta. |
---|
41 | |
---|
42 | |
---|
43 | \subsubsection{Třída RV} |
---|
44 | Třída \texttt{RV} implementuje pole popisků k vektorům třídy IT++. |
---|
45 | K přístupu k jednotlivým slouží přetížený operátor závorky \texttt{(int index)}. |
---|
46 | K určení veličiny uložené ve vektoru se používají metody |
---|
47 | \begin{description} |
---|
48 | \item [name] jméno veličiny uložené v příslušném vektoru |
---|
49 | \item [length] rozměr RV vektoru |
---|
50 | \item [size(i)] rozměr veličiny, kterou značí popisek na pozici \texttt{i} |
---|
51 | \end{description} |
---|
52 | |
---|
53 | \subsubsection{Třídy UI a Setting} |
---|
54 | UI a Setting slouží mimo jiné k načtení vybraných dat z konfiguračních souborů. |
---|
55 | Kód |
---|
56 | \begin{lstlisting} |
---|
57 | UI::get(inputs,set,"inputs",UI::compulsory); |
---|
58 | \end{lstlisting} |
---|
59 | zapíše na adresu proměnné \texttt{inputs} hodnotu v objektu \texttt{set} třídy \texttt{Setting}, |
---|
60 | označenou jako \texttt{\"inputs\"}. Oběkt \texttt{set} reprezentuje načtený konfigurační soubor. |
---|
61 | \texttt{UI::compulsory} značí, že daná hodnota musí být zadána. |
---|
62 | |
---|
63 | |
---|
64 | |
---|
65 | \subsubsection{Třída datalink} |
---|
66 | Tato třída definuje spojení mezi dvěma vektory, mezi kterými zprostředkovává spojení |
---|
67 | pomocí metody \texttt{filldown}. |
---|
68 | \\ |
---|
69 | \\ |
---|
70 | Následující kód popisuje vytvoření dvou vektorů \texttt{from} a \texttt{to}, |
---|
71 | popsaných \texttt{RV} vektory \texttt{rv\_from} a \texttt{rv\_to}, a zkopání odpovídajících |
---|
72 | údajů z \texttt{from} do \texttt{to} pomocí třídy \texttt{datalink}. Výsledkem je, že vektor |
---|
73 | \texttt{to} bude obsahovat hodnoty 1 a 2. |
---|
74 | |
---|
75 | \begin{lstlisting} |
---|
76 | RV a = RV ( "{ a }"); |
---|
77 | RV b = RV ( "{ b }" ); |
---|
78 | RV c = RV ( "{ c }" ); |
---|
79 | |
---|
80 | RV rv_to = a; |
---|
81 | rv_to.add ( b ); |
---|
82 | |
---|
83 | RV rv_from = rv_to; |
---|
84 | rv_from.to ( c ); |
---|
85 | |
---|
86 | datalink dl ( rv_to, rv_from ); |
---|
87 | vec from ( "1 2 3" ); |
---|
88 | vec to = dl.pushdown ( total ); |
---|
89 | \end{lstlisting} |
---|
90 | |
---|
91 | |
---|
92 | |
---|
93 | |
---|
94 | |
---|
95 | \section{Třída Lane} |
---|
96 | Každá instance třídy Lane reprezentuje jeden dopravní pruh. |
---|
97 | Po inicializaci se do příslušných proměnných uloží textové |
---|
98 | řetězce, podle kterých se přiřazují k pruhu data z detektorů |
---|
99 | a AIMSUNu, jako je na příklad maximální délka |
---|
100 | fronty na dopravním pruhu za jednu simulační periodu. |
---|
101 | |
---|
102 | |
---|
103 | \section{Třída LaneHandler} |
---|
104 | Tato třída zprostředkovává přístup agentovi k ůdajům z jednotlivých pruhů. |
---|
105 | Stará se o zaznamenávání a statistické spracování dat z AIMSUNu. |
---|
106 | Také je zde implementován odhad čekací doby automobilu do průjezdu křižovatkou, |
---|
107 | což je údaj používaný v hodnotící délky cyklu funkci agenta. |
---|
108 | |
---|
109 | \subsection{Fronta} |
---|
110 | Agent předává třídě LaneHandler údaj o maximální délce fronty za vzorkovací periodu. |
---|
111 | Jedná se o největší počet automobilů v příslušném jízdním pruhu, jejichž rychlost reřesahuje |
---|
112 | určitou hodnotu. V našem konkrétním případě je tato mezní rychlost nastavena na 3,6 km/h. |
---|
113 | Tento ůdaj je však pro naše potřeby zkreslený, a to hlavně tím, že ve většině případů se délka cyklu neshoduje |
---|
114 | se vzorkovací periodou. Uvažujme jízdní pruh s poměrem délky zelené 0,5. |
---|
115 | Pokud bude například délka cyklu 180 sekund, a budeme li předpokládat, že začátek jedné periody se bude shodovat s časem, |
---|
116 | kdy na příslušném semaforu naskočí zelená, bude v první vzorkovací periodě pruh průjezdný po dobu 45 sekund, ale |
---|
117 | v další nebude průjezdný vůbec a fronta se za stejné hustoty provozu zvětší. |
---|
118 | |
---|
119 | \subsection{Odhad fronty}\label{ss:odhad_fronty} |
---|
120 | K odhadu fronty je použito metody tzv. exponencionálního zapomínání. Metoda vychází z povoucího průměru |
---|
121 | Který je vhodný pro odhad nekonstantní hodnoty. Označíme si veličinu $\overline{q_i}$ jako plovoucí průměr |
---|
122 | fronty v kroce $i$, kam budeme ukládat posledních $n$ měření. Označme si velikost fronty naměřenou v $i$-tém kroce jako$q_i$. |
---|
123 | V kroce $i+1$ je hodnota hodnota plovoucího průměru přepřičytením poslední naměřené hodnoty rovna |
---|
124 | $$ |
---|
125 | \overline{q_i} = \frac{1}{n} \sum_{j=0}^{n-1} q_{i-j} . |
---|
126 | $$ |
---|
127 | |
---|
128 | Obsahuje tedy všech posledních $n$ naměřených hodnot. $\overline{q_{i+1}}$ se tedy rovná |
---|
129 | $$ |
---|
130 | \overline{q_{i+1}} = \frac{1}{n} ( n \overline{q_i} - q_{i-n+1} + q_{i+1} ) = \overline{q_i} - \frac{1}{n} q_{i-n+1} +\frac{1}{n} q_{i+1}. |
---|
131 | $$ |
---|
132 | Abychom nemuseli ukládat posledních $n$ měření. Zjednodušíme algoritmus tím, že místo kroku $i-n+1$ odečteme od průměru |
---|
133 | jeho hodnotu podělenou délkou průměrovacího okna $n$. Výpočet přejde na tvar |
---|
134 | $$ |
---|
135 | \overline{q_{i+1}} = \frac{1}{n} ( n \overline{q_i} - \overline{q_i} + q_{i+1} ) = \overline{q_i} + \frac{1}{n} (q_{i+1} - \overline{q_i}). |
---|
136 | $$ |
---|
137 | $\frac{1}{n} (q_{i+1} - \overline{q_i}$ je vlastně přírustek v kroku $i+1$, označme si ho jako $\Delta q_{i+1}$, |
---|
138 | a faktor $1/n$ můžeme chápat jako jeho váhu $w$. Po dosazení dostáváme jednoduchý tvar |
---|
139 | $$ |
---|
140 | \overline{q_{i+1}} = \overline{q_i} + w \Delta q_{i+1}. |
---|
141 | $$ |
---|
142 | Průměr s exponenciálním zapomínáním se nazývá proto, že je v něm v $i$-tém kroce uložena i první hodnota, |
---|
143 | má však zanedbatelnou váhu $\left(\frac{n-1}{n}\right)^i$. Jedná se o jaksi zjednodušenou verzi Kalmanova filtru. |
---|
144 | Grafy \ref{fig:q1} a \ref{fig:q2} znázorňují rozdíl mezi okamžitou a filtrovanou délkou fronty při váze $w = 0.2$. |
---|
145 | Graf \ref{fig:q1} pro konstantní délku cyklu 80 sekund, graf \ref{fig:q2} pro délku cyklu peridicky se měnící od 40 |
---|
146 | do 120 sekund. |
---|
147 | |
---|
148 | \begin{figure}[H] |
---|
149 | \begin{center} |
---|
150 | {\includegraphics[width=10cm]{\obr q_scen_01_1h_tc80.eps}} |
---|
151 | \caption{Porovnání okamžité a filtrované délky fronty \newline délka cyklu 80 s}\label{fig:q1} |
---|
152 | \end{center} |
---|
153 | \end{figure} |
---|
154 | |
---|
155 | \begin{figure}[H] |
---|
156 | \begin{center} |
---|
157 | {\includegraphics[width=10cm]{\obr q_scen_01_1h_tc40-120.eps}} |
---|
158 | \caption{Porovnání okamžité a filtrované délky fronty \newline délka cyklu 40-120 s}\label{fig:q2} |
---|
159 | \end{center} |
---|
160 | \end{figure} |
---|
161 | |
---|
162 | |
---|
163 | V reálném případě je potřeba vypočítat délku fronty podle záznamů z detektorů. |
---|
164 | Prostý výpočet délky fronty například jako rozdíl počtu vozidel, která odjela a která přiela však není možný. |
---|
165 | V důsledku problémů popsaných v \ref{sss:zpracovani_dat}. Výpočet délky fronty není předmětem zkoumání této práce. |
---|
166 | Podrobnější pojednání o tomto problému lze najít například v \cite{pecherkova}. |
---|
167 | \\ |
---|
168 | \\ |
---|
169 | Protože časté přenastavování délky cyklu působí řadičům problémy, přenastavuje se tento parametr jednou za časový |
---|
170 | úsek, ktrý je několikanásobně delší než 90 sekund. Je tedy nutné modelovat časový průběh fronty. Při rozšiřování testovacího |
---|
171 | prostředí tento model ovlivní i údaj o počtu vozidel, které přijedou ze sousední křižovatky. Tento ůdaj závisí na délce cyklu |
---|
172 | a není agentovy dostupný přímo. Bude tedy nutné rozšířit komunikaci agentů, popsanou v \ref{ss:komunikace}, o tento údaj. |
---|
173 | |
---|
174 | |
---|
175 | \subsection{Odhad čekací doby}\label{ss:odhad_cekaci_doby} |
---|
176 | Jednou z nejdůležitějších částí logiky, implementovaná v třídě \texttt{LaneHandler} je |
---|
177 | odhad čekací doby vozidel stojících v, nebo přijíždějících do příslušnéjo jízdního pruhu. |
---|
178 | Tento odhad se používá při výběru a ohodnocení délky cyklu. |
---|
179 | \\ |
---|
180 | \\ |
---|
181 | Odahad se provádí zjednodušenou mikrosimulací po čas \texttt{T}. |
---|
182 | Do proměnné \texttt{q} se uloží aktuální hodnota fronty. |
---|
183 | Simulace začíná v čase \texttt{t = 0}. V každém kroku simulace |
---|
184 | se zvětší fronta o hustotu provozu (počt aut za sekundu), odhadovanou z údaů z detektorů, a pokud se čas nachází |
---|
185 | ve průjezdné fázi, zmenší se o konstantu, nazývanou saturovaný tok, která udává maximální počet aut, které projedou |
---|
186 | křižovatkou. K čekací době vozidel, uložené v proměnné \texttt{wt}, se potom přičte délka zbývající fronty a čas |
---|
187 | \texttt{t} se zvětší o jednu sekundu. |
---|
188 | \\ |
---|
189 | \\ |
---|
190 | Odhad probíhá ve dvou fázích, realizovaných cykly typu \texttt{for}. V první běží čas do nevětší části \texttt{T}, |
---|
191 | soudělné s \texttt{tc}, v duhé po zbytek \texttt{T}. níže uvádím popis všech proměnných. |
---|
192 | \begin{description} |
---|
193 | \item[tc] délka cyklu, pro kterou je odhad prováděn (parametr funkce) |
---|
194 | \item[T] doba odhadu |
---|
195 | \item[ro] hustota provozu odhadovaná z dat z detektorů |
---|
196 | \item[cars\_in\_avg] filtrovaná data z detektorů (atribut třídy) |
---|
197 | \item[queue\_avg] filtrovaná naměřená délka fronty (atribut třídy) |
---|
198 | \item[q] délka fronty v průběhu odhadu |
---|
199 | \item[wt] součet čekacích časů |
---|
200 | \item[green\_time\_ratio] poměr délky zelené k délce cyklu (atribut třídy) |
---|
201 | \item[gt] doba, kdy je křižovatka pro pruh průjezdná |
---|
202 | \item[tc\_rest] čas v daném cyklu |
---|
203 | \item[tc\_last] zbytek odhadovací periody |
---|
204 | \item[gt\_last] délka zelené ve zbytku odhadovací periody |
---|
205 | \item[delta] korekční parametr vyjadřuje zkrácení doby průjezdnosti vlivem pomalých rozjezdů a podpbně |
---|
206 | \end{description} |
---|
207 | Odhad je implementován v metodě \texttt{getWT}: |
---|
208 | |
---|
209 | \begin{lstlisting} |
---|
210 | double getWT ( int tc ) { |
---|
211 | const int T = 450; // 5 scyklů |
---|
212 | double ro = cars_in_avg/90; |
---|
213 | double q = queue_avg; |
---|
214 | double wt = 0; |
---|
215 | double gt = tc*green_time_ratio - delta; |
---|
216 | int t_rest; |
---|
217 | int tc_last = T % tc; |
---|
218 | double gt_last = tc_last*green_time_ratio; |
---|
219 | for ( int t = 0; t < (T-tc_last); t++ ) { |
---|
220 | t_rest = t%tc; |
---|
221 | // zelena |
---|
222 | if ((tc-gt)/2<=t_rest&&t_rest<(tc+gt)/2) |
---|
223 | q -= saturated_stream; |
---|
224 | if ( q < 0) |
---|
225 | q = 0; |
---|
226 | wt += q; |
---|
227 | q += ro; |
---|
228 | } |
---|
229 | // zbytek |
---|
230 | for ( int t = 0; t < tc_last; t++ ) { |
---|
231 | // zelena |
---|
232 | if ((tc_last-gt_last)/2<=t&&t<(tc_last+gt_last)/2 ) |
---|
233 | q -= saturated_stream; |
---|
234 | if ( q < 0) |
---|
235 | q = 0; |
---|
236 | wt += q; |
---|
237 | q += ro; |
---|
238 | } |
---|
239 | return wt; |
---|
240 | } |
---|
241 | \end{lstlisting} |
---|
242 | |
---|
243 | |
---|
244 | |
---|
245 | \section{Hlavní smyčka} |
---|
246 | Hlavní smyčka programu se stará o synchronizaci všech potřebných parametrů a provádění iterací. |
---|
247 | Před započetím opakování kroku simulace nastaví podle konfiguračního souboru počáteční parametry mikrosimulátoru dopravy AIMSUN, |
---|
248 | jako jsou délka cyklu a fáze řadičů, inicializuje jednotlivé agenty a zavolá jejich metody \texttt{fromSettings} a \texttt{Validate}. |
---|
249 | |
---|
250 | \subsection{Krok simulace} |
---|
251 | Délka kroku simulace je pevně nastavena na 90 sekund shodně s periodou sběru dat z AIMSUNu. |
---|
252 | V jednom kroku se nejprve načtou data z AIMSUNu do vektoru \texttt{glob\_dt}, který se následně předá |
---|
253 | každému z agentů jako paramentr jejich metody \texttt{adapt}. Následně se zprostředkuje komunikace mezi |
---|
254 | agenty tak, že se naplní fronta zpráv voláním metody \texttt{broadcast} jednotlivých agentů. Z této fronty |
---|
255 | se postupně odebírají zprávy, které se předávají agentům parametrem jejich metody \texttt{receive} |
---|
256 | Po ukončení komunikace naplní vektor výstupů \texttt{glob\_ut} voláním metod \texttt{act} hodotami parametrů |
---|
257 | pro AIMSUN, předá se mu a vyčká se do dalšího kroku. |
---|
258 | |
---|
259 | \section{Třída agenta} |
---|
260 | Třída \texttt{TrafficAgentCycleTime} je odvozena od obecného návrhu agnta \texttt{BaseTrafficAgent}. |
---|
261 | Jsou v ní implementovány metody pro načtení dat, komunikaci a nastavení délky cyklu za účelem řízení |
---|
262 | jedné konkrétní křižovatky. |
---|
263 | |
---|
264 | \subsection{Stručný popis algoritmu} |
---|
265 | Cíl algoritmu je zlepšit dopravní situaci nastavením délky cyklu řadiče na tekouvou |
---|
266 | hodnotu, při níž bude celková čekací doba všech vozidel mininmální. |
---|
267 | Nejprve agent odhadne délku cyklu, která je ideální pro něj, poté vyšle zprávu, zda je tato hodnota |
---|
268 | vyšší nebo nižší než aktuální. Pokud je nadpoloviční většina agentů pro změnu stejným směrem, |
---|
269 | pokouší se najít hodnotu ideální pro všechny. |
---|
270 | |
---|
271 | \subsection{Výpočetní metody} |
---|
272 | |
---|
273 | \subsubsection{Metoda getWT} |
---|
274 | |
---|
275 | Tato metoda vrací součet čekacích dob, sečtený přes všechny dopravní pruhy pro danou délku cyklu předanou parametrem \texttt{tc}. |
---|
276 | V cyklu projde instance tříd \texttt{LAneHandler}, na které má uloženy ukazatele v proměnné \texttt{lanehs} typu |
---|
277 | \texttt{Array<LaneHandler*>}. Pole se inicializuje v metodě \texttt{validate} předka \texttt{BaseTrafficAgent}. |
---|
278 | |
---|
279 | \subsubsection{Metoda findIdealTc}\label{sss:ideal_tc} |
---|
280 | Pro určení, zda vznést návrh na zvýšení či snížení délky cyklu, slouží metoda \texttt{findIdealTc}. |
---|
281 | Ta zjišťuje čekací doby pro všechny možnosti rozsahu od mininmální do maximální hodnoty, určené atributy |
---|
282 | \texttt{minTc} a \texttt{maxTc}. Vrátí takovou délku cyklu, pro kterou je čekací doba nejmenší. |
---|
283 | \\ |
---|
284 | \\ |
---|
285 | Princip použití součtu čekacích dob automaticky upřednostňuje dopravní pruhy s větší |
---|
286 | vytížeností, což je žádoucí. Ostatní pruhy však zcela nepotlačuje. Tímto způsobem by se mělo |
---|
287 | dosáhnout optimální hodnoty pro celou křižovatku. |
---|
288 | |
---|
289 | \subsection{Přepsané metody předka} |
---|
290 | Hlavní smyčka progaramu automaticky volá v každém cyklu metody určené |
---|
291 | k načtení dat, komunikaci a nastavení dalšího řízení. |
---|
292 | |
---|
293 | |
---|
294 | |
---|
295 | \subsubsection{Metoda validate} |
---|
296 | K předání požadovaných hodnot parametrů v průběhu vsimulace slouží vektor \texttt{actions}. |
---|
297 | Významy těchto hodnot vysvětluje \texttt{rv\_actions} třídy \texttt{RV}. V metodě \texttt{validate}, |
---|
298 | která se volá na začátku simulace, přidáme do \texttt{rv\_actions} hodntu \texttt{Tc}. Tím |
---|
299 | vlastně sdělíme AIMSUNu, že budeme přenastavovat délku cyklu. Protože délka jednotlivých fází se nepřenastavuje automaticky, |
---|
300 | přidáme do \texttt{rv\_actions} také označení těchto fází. Vpraxi je tento postup realizován kódem |
---|
301 | \begin{lstlisting} |
---|
302 | rv_action = RV("Tc",1); |
---|
303 | rv_action.add( RV(stage_names, ones_i(stage_names.length()))); |
---|
304 | \end{lstlisting} |
---|
305 | kde je v proměnné \texttt{stage\_names} uložen seznam fází. |
---|
306 | \\ |
---|
307 | \\ |
---|
308 | Následující metody se volají v každém cyklu simulace. |
---|
309 | |
---|
310 | |
---|
311 | |
---|
312 | \subsubsection{Metoda adapt} |
---|
313 | Na začátku každého simulačního cyklu se jako první volá u všech agentů metoda \texttt{adapt}. |
---|
314 | V parametru se jí předá adresa vektrou výstupních údajů simulace \texttt{glob\_dt}, k jejichž zpracování je metoda určena. |
---|
315 | Zde se předávají údaje z detektorů a délky front istancím třídy \texttt{LaneHandler} a poté se volá jejich metoda |
---|
316 | \texttt{countAvgs}, která počítá filtrované hodnoty způsobem popsaným v sekci \ref{ss:odhad_fronty}. |
---|
317 | |
---|
318 | |
---|
319 | \subsubsection{Metoda receive a broadcast} \label{ss:komunikace} |
---|
320 | Po načtení a zpracování dat začíná komunikace. Ta je realizována metodami |
---|
321 | \texttt{broadcas} a \texttt{receive}, které se volají střídavě. Přesněji řečeno, |
---|
322 | hlavni smyčka nejprve volá metody \texttt{receive} každého agenta tak dlouho, dokud nevyprázdní frontu zpráv. |
---|
323 | Ta je reprezentována polem proměnných typu \texttt{Setting}, které mají nastaveny čtyři parametry: |
---|
324 | |
---|
325 | \begin{description} |
---|
326 | \item [from] určuje od koho zpráva přichází |
---|
327 | \item [to] má hodnotu jména agenta, pro kterého je zpráva určena |
---|
328 | \item [what] obsahuje co posíláme |
---|
329 | \item [value] obsahuje hodnotu spojenou s tím co posíláme |
---|
330 | \end{description} |
---|
331 | |
---|
332 | Každý agent má v atributu \texttt{name} uloženo jméno křižovatky, kterou ovládá. |
---|
333 | Toto jméno je uloženo v konfiguračním souboru a odpovídá označením ze sekce \ref{ss:oblast_simulace}. |
---|
334 | Pokud je jméno agenta stejné jako parametr zprávy \texttt{to}, vyjme se zpráva z frony a předá se |
---|
335 | metodě \texttt{receive}.V momentě, kdy je fronta prázdná, zavolají se metody \texttt{broadcast} všech agentů. |
---|
336 | Metoda broadcast opět plní frontu zprávami, které chce agent vyslat. Po jejím ukončení se opět volá \texttt{receive}. |
---|
337 | Střídavé volání těchto dvou metod probíhá, dokud \texttt{broadcast} produkuje nějaké zprávy. |
---|
338 | \\ |
---|
339 | \\ |
---|
340 | V našem případě probíhá odesílání ve dvou krocích. V obou se posílají zprávy všem ostatním agentům. |
---|
341 | Nejprve agent sdělí, jestli chce délku cyklu zvýšit, snížit, nebo ponechat stejnou. |
---|
342 | Pokud je pro zvýšení více než polovina agentů, začíná druhá fáze. |
---|
343 | V té každý agent pošle všechny délky cyklu v předem daném rozsahu a k nim očekávané zisky. |
---|
344 | Rozsah je od minimální do stávající při odhlasování snížení a od stávající do maximální při zvýšení. |
---|
345 | Zisk se počítá jako rozdíl čekací doby při navrhované a stávající délce cyklu pomocí metody popsané v \ref{ss:odhad_cekaci_doby}. |
---|
346 | Odeslání těchto zpráv je realizováno kódem |
---|
347 | \begin{lstlisting} |
---|
348 | int broadcast_width = (max_tc - min_tc) + 1; |
---|
349 | |
---|
350 | for ( int i = 0; i < broadcast_width; i++ ) { |
---|
351 | int time_cycle = min_tc + i*stepTc; |
---|
352 | double profit = getProfit(time_cycle); |
---|
353 | |
---|
354 | // send tc |
---|
355 | stringstream time_cycle_stream; |
---|
356 | time_cycle_stream << "tc_" << (i); |
---|
357 | send2allNeighbours( set, time_cycle_stream.str(), time_cycle); |
---|
358 | |
---|
359 | // send profit |
---|
360 | stringstream profit_stream; |
---|
361 | profit_stream << "profit_" << (i); |
---|
362 | send2allNeighbours( set, profit_stream.str(), profit ); |
---|
363 | } |
---|
364 | \end{lstlisting} |
---|
365 | |
---|
366 | Agent tedy vygeneruje pro každou hodnotu délky cyklu index, podle kterého se k ní dá přiřadit hodnota zisku. |
---|
367 | V metodě \texttt{receive} se podle tohoto indexu sčítají zisky do pole \texttt{received\_profit\_sum}. |
---|
368 | |
---|
369 | |
---|
370 | |
---|
371 | \subsubsection{Metoda act}\label{sss:metoda_act} |
---|
372 | Pokud se agenti dohodly na změně délky cyklu, probíhá její přenastavení v metodě act. |
---|
373 | Nejprve se projde pole \texttt{received\_profit\_sum} a vybere se z něj maximum. |
---|
374 | Poté se podle indexu maximálního zisku určí ideální délka fronty. |
---|
375 | \\ |
---|
376 | \\ |
---|
377 | Měření ukázala, že časté změny cyklu působí emulátorům řadičů problémy. |
---|
378 | Proto se ideální hodnota průměruje plovoucím průměrem a nastavuje se jednou za 5 cyklů. |
---|
379 | |
---|
380 | |
---|
381 | |
---|
382 | |
---|