44 | | outputs(indexes(2))= start_time + green_time(0); |
45 | | |
46 | | //} |
47 | | } |
48 | | } |
49 | | } |
50 | | |
51 | | public: |
52 | | int last_offset; |
53 | | int planned_offset; |
54 | | double actual_rating; |
55 | | |
56 | | //! array of existing signal groups |
57 | | Array<string> sgs; |
58 | | //! relative starts of green for signal groups |
59 | | ivec green_starts; |
60 | | |
61 | | //! avarage speed of cars |
62 | | int VP; |
63 | | |
64 | | void validate() { |
65 | | rv_action = RV(name+"_offset", 1); // <======= example |
66 | | |
67 | | for (int i=0; i<sgs.length();i++) { |
68 | | rv_inputs.add(RV(name+"_"+sgs(i),1)); |
69 | | |
70 | | //place for expected inputs |
71 | | //rv_expected_traffic.add(RV(name+"_"+sgs(i)+"_exp",3)); |
72 | | } |
73 | | |
74 | | inputs.set_size(rv_inputs._dsize()); |
75 | | //expected_traffic.set_size(rv_expected_traffic._dsize()); |
76 | | |
77 | | BaseTrafficAgent::validate(); |
78 | | } |
79 | | |
80 | | //! returns index of signal group sg |
81 | | int sg_index(string sg) { |
82 | | for (int i=0;i<sgs.length();i++) { |
83 | | if (sgs(i)==sg) { |
84 | | return i; |
85 | | } |
86 | | } |
87 | | return -1; |
88 | | } |
89 | | |
90 | | void adapt(const vec &glob_dt) { |
91 | | BaseTrafficAgent::adapt(glob_dt); |
92 | | |
93 | | planned_offset=last_offset; |
94 | | } |
95 | | //! counts actual rating using planned_offset and recieved_exps |
96 | | void count_rating() { |
| 53 | outputs(ind(2))= start_time + green_time(0); |
| 54 | } |
| 55 | } |
| 56 | }; |
| 57 | |
| 58 | //! counts planned rating using offset and recieved_exps |
| 59 | double count_rating(const int offset) { |
145 | | actual_rating+=max((t_mixing-t_emptiyng)*lanehs(i)->expected_density(),0.0); |
146 | | } |
147 | | } |
148 | | |
| 117 | rating+=max((t_mixing-t_emptiyng)*lanehs(i)->expected_density(),0.0); |
| 118 | } |
| 119 | return rating; |
| 120 | } |
| 121 | |
| 122 | //! finds best offset using recieved_exps. Returns found offset |
| 123 | int find_best_offset(const int center, int interval) { |
| 124 | //! rating if offset is rised |
| 125 | double rating_p; |
| 126 | //! rating if offset is unchaged (=center) |
| 127 | double rating_c; |
| 128 | //! rating if offset is lowered |
| 129 | double rating_n; |
| 130 | |
| 131 | int new_center; |
| 132 | |
| 133 | rating_p=count_rating(center+interval); |
| 134 | rating_c=count_rating(center); |
| 135 | rating_n=count_rating(center-interval); |
| 136 | |
| 137 | new_center=center; |
| 138 | int max_index=max_of_three(rating_p,rating_c,rating_n); |
| 139 | switch (max_index) { |
| 140 | case 0: |
| 141 | new_center+=interval; |
| 142 | break; |
| 143 | case 1: |
| 144 | break; |
| 145 | case 2: |
| 146 | new_center-=interval; |
| 147 | break; |
| 148 | } |
| 149 | |
| 150 | if (interval>2) { |
| 151 | interval/=2; |
| 152 | new_center=find_best_offset(new_center,interval); |
| 153 | } |
| 154 | |
| 155 | return new_center; |
| 156 | } |
| 157 | |
| 158 | //! finds if changing neighbour's offset could have positive effect, returns found offset change |
| 159 | int find_best_exps(const int offset_change, const string neighbour, double &rating_change) { |
| 160 | //! expectations recieved from neighbour |
| 161 | vec original_exps; |
| 162 | //! expactations after positve change of neighbour's offset |
| 163 | vec positive_exps; |
| 164 | //! expactations after negative change of neighbour's offset |
| 165 | vec negative_exps; |
| 166 | //! rating if offset is rised |
| 167 | double rating_p; |
| 168 | //! rating if offset is unchaged |
| 169 | double rating_c; |
| 170 | //! rating if offset is lowered |
| 171 | double rating_n; |
| 172 | original_exps.set_size(recieved_exps.length()); |
| 173 | |
| 174 | original_exps=recieved_exps; |
| 175 | positive_exps=recieved_exps; |
| 176 | negative_exps=recieved_exps; |
| 177 | |
| 178 | for (int j=0;j<rv_recieved_exps.length();j++) { |
| 179 | int res = rv_recieved_exps.name(j).find("-"+neighbour); |
| 180 | if (res>0) { |
| 181 | ivec ind = rv_recieved_exps.dataind(RV(rv_recieved_exps.name(j),3)); |
| 182 | rating_n=count_rating(planned_offset); |
| 183 | |
| 184 | positive_exps(ind(1))+=offset_change; |
| 185 | positive_exps(ind(2))+=offset_change; |
| 186 | |
| 187 | negative_exps(ind(1))-=offset_change; |
| 188 | negative_exps(ind(2))-=offset_change; |
| 189 | } |
| 190 | } |
| 191 | |
| 192 | rating_c=count_rating(planned_offset); |
| 193 | |
| 194 | recieved_exps=positive_exps; |
| 195 | rating_p=count_rating(planned_offset); |
| 196 | |
| 197 | recieved_exps=negative_exps; |
| 198 | rating_n=count_rating(planned_offset); |
| 199 | |
| 200 | recieved_exps=original_exps; |
| 201 | |
| 202 | int max_index=max_of_three(rating_p,rating_c,rating_n); |
| 203 | switch (max_index) { |
| 204 | case 0: |
| 205 | rating_change=rating_p-rating_c; |
| 206 | return offset_change; |
| 207 | break; |
| 208 | case 1: |
| 209 | rating_change=0; |
| 210 | return 0; |
| 211 | break; |
| 212 | case 2: |
| 213 | rating_change=rating_n-rating_c; |
| 214 | return -offset_change; |
| 215 | break; |
| 216 | } |
| 217 | rating_change=NULL; |
| 218 | return NULL; |
| 219 | } |
| 220 | |
| 221 | //! returns index of signal group sg |
| 222 | int sg_index(const string sg) { |
| 223 | for (int i=0;i<sgs.length();i++) { |
| 224 | if (sgs(i)==sg) { |
| 225 | return i; |
| 226 | } |
| 227 | } |
| 228 | return -1; |
| 229 | } |
| 230 | |
| 231 | //! returns offset value shifted to fit interval <0;cycle_length> |
| 232 | int normalize_offset(int offset) { |
| 233 | while (offset<0 && offset<cycle_length) { |
| 234 | if (offset<0) { |
| 235 | offset+=cycle_length; |
| 236 | } |
| 237 | else { |
| 238 | offset-=cycle_length; |
| 239 | } |
| 240 | } |
| 241 | return offset; |
| 242 | } |
| 243 | |
| 244 | |
| 245 | //! returns index of maximum of entered values |
| 246 | int max_of_three(const double a, const double b, const double c) { |
| 247 | int index = a > b ? 0 : 1; |
| 248 | |
| 249 | if (index == 0) { |
| 250 | index = a > c ? 0 : 2; |
| 251 | } |
| 252 | else { |
| 253 | index = b > c ? 1 : 2; |
| 254 | } |
| 255 | return index; |
| 256 | } |
| 257 | |
| 258 | public: |
| 259 | //! offset set in last simulation step |
| 260 | int last_offset; |
| 261 | //! actual planned offset to set for next simulation step |
| 262 | int planned_offset; |
| 263 | //! rating of actual planned offset |
| 264 | double planned_rating; |
| 265 | |
| 266 | //! array of existing signal groups |
| 267 | Array<string> sgs; |
| 268 | //! relative starts of green for signal groups |
| 269 | ivec green_starts; |
| 270 | |
| 271 | //! avarage speed of cars |
| 272 | int VP; |
| 273 | |
| 274 | void validate() { |
| 275 | rv_action = RV(name+"_offset", 1); // <======= example |
| 276 | |
| 277 | for (int i=0; i<sgs.length();i++) { |
| 278 | rv_inputs.add(RV(name+"_"+sgs(i),1)); |
| 279 | } |
| 280 | inputs.set_size(rv_inputs._dsize()); |
| 281 | |
| 282 | BaseTrafficAgent::validate(); |
| 283 | |
| 284 | for (int i=0;i<lanehs.length();i++) { |
| 285 | ivec index = rv_queues.dataind(RV(lanes(i).queue,1)); |
| 286 | lanehs(i)->queue_index=index(0); |
| 287 | } |
| 288 | |
| 289 | |
| 290 | } |
| 291 | |
| 292 | void adapt(const vec &glob_dt) { |
| 293 | BaseTrafficAgent::adapt(glob_dt); |
| 294 | |
| 295 | for (int i=0;i<lanehs.length();i++) { |
| 296 | lanehs(i)->queue=queues(lanehs(i)->queue_index); |
| 297 | } |
| 298 | |
| 299 | planned_offset=last_offset; |
| 300 | |
| 301 | //set state variables to default values |
| 302 | final_state=false; |
| 303 | new_stable_state=false; |
| 304 | send_requests=false; |
| 305 | need_exps=true; |
| 306 | negot_offset=8; |
| 307 | } |
177 | | |
178 | | } while (!seznam.empty()); |
| 334 | } while (!seznam.empty()); |
| 335 | } |
| 336 | |
| 337 | // broadcast new stable state (new stable expectations) |
| 338 | if (new_stable_state) { |
| 339 | expected_cars(); |
| 340 | for (int i=0;i<neighbours.length();i++) { |
| 341 | Setting &msg = set.add(Setting::TypeGroup); |
| 342 | UI::save ( neighbours(i), msg, "to"); |
| 343 | UI::save ( name, msg, "from"); |
| 344 | UI::save ( (string)"new_stable_state2", msg, "what"); |
| 345 | UI::save ( &(rv_outputs), msg, "rv"); |
| 346 | UI::save ( outputs, msg, "value"); |
| 347 | } |
| 348 | new_stable_state=false; |
| 349 | } |
| 350 | |
| 351 | // broadcast requests to change offset(s) |
| 352 | if (send_requests) { |
| 353 | for (int i=0;i<neighbours.length();i++) { |
| 354 | Setting &msg = set.add(Setting::TypeGroup); |
| 355 | UI::save ( neighbours(i), msg, "to"); |
| 356 | UI::save ( name, msg, "from"); |
| 357 | UI::save ( (string)"offset_change_request", msg, "what"); |
| 358 | UI::save ( &(rv_change_request), msg, "rv"); |
| 359 | UI::save ( change_request, msg, "value"); |
| 360 | } |
| 361 | send_requests=false; |
| 362 | } |
| 363 | |
| 364 | /*if (reset_negot_offset) { |
| 365 | for (int i=0;i<neighbours.length();i++) { |
| 366 | Setting &msg = set.add(Setting::TypeGroup); |
| 367 | UI::save ( neighbours(i), msg, "to"); |
| 368 | UI::save ( name, msg, "from"); |
| 369 | UI::save ( (string)"reset_negot_offset", msg, "what"); |
| 370 | } |
| 371 | }*/ |
| 372 | |
| 373 | |
| 374 | |
| 375 | // reached final offset. Log value? |
| 376 | if (final_state) { |
204 | | count_rating(); |
205 | | //TODO skutecne vyjednavani |
206 | | } |
| 403 | |
| 404 | last_offset=planned_offset; |
| 405 | |
| 406 | planned_offset=find_best_offset(planned_offset,8); |
| 407 | planned_offset=normalize_offset(planned_offset); |
| 408 | |
| 409 | |
| 410 | /*if (planned_offset!=last_offset) { |
| 411 | reset_negot_offset=true; |
| 412 | }*/ |
| 413 | planned_rating=count_rating(planned_offset); |
| 414 | // we have new stable state to broadcast |
| 415 | new_stable_state=true; |
| 416 | } |
| 417 | else if (what=="new_stable_state2") { |
| 418 | rv_recieved_exps=*rv; |
| 419 | recieved_exps=value; |
| 420 | planned_rating=count_rating(planned_offset); |
| 421 | |
| 422 | for (int i=0;i<neighbours.length();i++) { |
| 423 | rv_change_request.add(RV(neighbours(i)+"_change",2)); |
| 424 | change_request.set_size(rv_change_request._dsize()); |
| 425 | ivec ind=rv_change_request.dataind(RV(neighbours(i)+"_change",2)); |
| 426 | // offset change |
| 427 | change_request(ind(0))=find_best_exps(negot_offset,neighbours(i),rating_change); |
| 428 | // rating change |
| 429 | change_request(ind(1))=rating_change; |
| 430 | } |
| 431 | |
| 432 | if (negot_offset>2) { |
| 433 | negot_offset/=2; |
| 434 | send_requests=true; |
| 435 | } |
| 436 | else { |
| 437 | final_state=true; |
| 438 | } |
| 439 | } |
| 440 | else if (what=="offset_change_request") { |
| 441 | double final_rating_diff; |
| 442 | |
| 443 | rv_recieved_changes=*rv; |
| 444 | recieved_changes=value; |
| 445 | |
| 446 | for (int i=0;i<rv_recieved_changes.length();i++) { |
| 447 | |
| 448 | ivec ind=rv_recieved_changes.dataind(RV(rv_recieved_changes.name(i),2)); |
| 449 | |
| 450 | final_rating_diff=-planned_rating+count_rating(planned_offset+(int)recieved_changes(ind(0)))-recieved_changes(ind(0)); |
| 451 | if (final_rating_diff>0) { |
| 452 | planned_offset+=(int)recieved_changes(ind(0)); |
| 453 | planned_rating+=final_rating_diff; |
| 454 | accepted_from=from; |
| 455 | } |
| 456 | } |
| 457 | //need_exps=true;s |
| 458 | new_stable_state=true; |
| 459 | } |
| 460 | /*else if (what=="reset_negot_offset") { |
| 461 | negot_offset=8; |
| 462 | }*/ |