#include "traffic_agent.cpp" const string testMessage = "test_message"; const double measurement_cycle_time = 90; // s const double saturated_stream = 0.5; // car/s const int sample_cycles = 5; class SignalGroup { public: string name; Array lanes; double green_time_ratio; int average_queue_length; string queue_name; int cycle_counter; SignalGroup () { average_queue_length = 0; } void adapt() { if ( (cycle_counter +1)% sample_cycles == 0 ) average_queue_length = 0; } int getSumCarsWaitingTime ( double time_cycle ) { int q = average_queue_length/sample_cycles; // pomocna delka fronty - UPRAVIT - pocitat s vetsi nez prumernou? int cars_per_green = time_cycle * green_time_ratio * lanes.length() * saturated_stream; // pocet aut ktere projedou na zelenou int sum_cars_waiting_time = 0; // suma aut * cekacich casu int i = 0; // iterator while ( q > cars_per_green ) { q -= cars_per_green; sum_cars_waiting_time += q*time_cycle; i ++; } // + zbytek fronty + prvni nezapocitana vlna if ( i > 0 ) { sum_cars_waiting_time += q*time_cycle + cars_per_green*(1.0-green_time_ratio)*time_cycle*0,5; //cout << "delsi fronta " << q << " "; } // pocet aut * stredni hodnota cekaci doby pri volne krizovatces else { sum_cars_waiting_time += (0.5*(1.0-green_time_ratio))*(time_cycle*q); //cout << "kratsi fronta " << q << " "; } //cout << "signal group " << name << " tc " << time_cycle << " cekani " << sum_cars_waiting_time << " fronta " << average_queue_length << endl; return sum_cars_waiting_time; } void addQueue( int q ) { if ( q > 0 ) average_queue_length += q; } }; class TrafficAgentCycleTime : public BaseTrafficAgent { public: int Tc; int minTc; int maxTc; int stepTc; int idealTc; static const int d_Tc = 3; // pocet navrhovanych delek cyklu int cycle_counter; int max_profit; unsigned int n_of_broadcast; Array lane_sum; Array signal_groups; Array received_Tcs; Array received_profit_sum; // POMOCNE FUNKCE void printVector ( RV rv_vector, vec vector, string description ) { cout << endl << description << " " << name << endl; int k = 0; for ( int i = 0; i < rv_vector.length(); i ++ ) { cout << rv_vector.name(i) << " : "; for ( int j = 0; j < rv_vector.size(i); j ++ ) { cout << vector(k) << " "; k ++; } cout << endl; } cout << endl; } void echo ( string message ) { cout << name << " hlasi: " << message << endl; } unsigned int find_index ( RV rv_vector, string index_string ) { for ( unsigned int i = 0; i < (int) rv_vector.length(); i ++) { if ( rv_vector.name(i) == index_string ) return i; } return rv_vector.length(); } unsigned int find_index ( Array arr, string index_string ) { for ( unsigned int i = 0; i < (int) arr.length(); i ++) { if ( arr(i) == index_string ) return i; } return arr.length(); } // VYPOCETNI FUNKCE int getSumCarsWaitingTime ( double time_cycle ) { int sum = 0; SignalGroup * sg; for ( int i = 0; i < signal_groups.length(); i ++ ) { sg = signal_groups(i); sum += sg->getSumCarsWaitingTime( time_cycle ); } return sum; } int getQueue () { int queue = 0; SignalGroup *sg; for ( int i = 0; i < signal_groups.length(); i ++ ) { sg = signal_groups(i); queue += sg->average_queue_length; } return queue; } // NEPOUZIVAT? //int getIdealTc() { // int min_waiting_time = getSumCarsWaitingTime(Tc); // int waiting_time; // int idealTc = Tc; // cout << name << " Tc wt" << endl; // for ( int t_c = Tc - 2*stepTc; t_c <= Tc + 2*stepTc; t_c += stepTc ) { // waiting_time = getSumCarsWaitingTime(t_c); // cout << t_c << " " << waiting_time << endl; // if ( waiting_time < min_waiting_time ) { // min_waiting_time = waiting_time; // idealTc = t_c; // } // } // cout << "IDEAL " << idealTc << endl; // return idealTc; //} int getIdealTc() { } void send2neighbour( Setting &set, int i, string messageName, double messageValue ) { if ( i < neighbours.length() ) { Setting &msg =set.add(Setting::TypeGroup); UI::save( neighbours(i), msg, "to" ); UI::save (name,msg,"from"); UI::save( messageName, msg, "what" ); UI::save( messageValue, msg, "value" ); } else { //throw new Exception("soused "+((string)i)+" neexistuje"); //cout << endl << endl << "soused " << i << mimo std::stringstream out; out << "soused " << i << " neexistuje"; //throw out.str(); cout << out.str(); } } void send2allNeighbours ( Setting &set, string messageName, double messageValue ) { for ( int i = 0; i < neighbours.length(); i++ ) { send2neighbour( set, i, messageName, messageValue ); } } int getProfit( int time_cycle ) { if ( Tc != time_cycle ) return getSumCarsWaitingTime( Tc ) - getSumCarsWaitingTime ( time_cycle ); else return 0; } // FUNKCE VOLANE V main_loop NA ZACATKU void from_setting( Setting &set ) { BaseTrafficAgent::from_setting(set); //TrafficAgentCycleTime::Tc = 80; } void validate (){ rv_action = RV("Tc",1); rv_action.add( RV( stage_names, ones_i(stage_names.length()) ) ); Tc = 80; minTc = 60; maxTc = 120; stepTc = 5; max_profit = 0; received_profit_sum.set_length( 2*d_Tc +1 ); received_Tcs.set_length( 2*d_Tc +1 ); cycle_counter = 0; BaseTrafficAgent::validate(); // inicializace signalnich skupin for ( int i = 0; i < lanes.length(); i ++ ) { Lane * l = & lanes(i); int sg_index = -1; for ( int j = 0; j < signal_groups.length(); j ++ ) { SignalGroup * sg; sg = signal_groups(j); if ( sg->name == l->sg ) sg_index = j; } SignalGroup * sg; if ( sg_index >= 0 ) { sg = signal_groups(sg_index); } else { sg = new SignalGroup(); sg->name = l->sg; sg->average_queue_length = 0; signal_groups.set_size( signal_groups.length()+1, true ); signal_groups(signal_groups.length()-1) = sg; } sg->lanes.set_size(sg->lanes.length()+1, true); sg->lanes(sg->lanes.length()-1) = l; } } // FUNKCE VOLANE V main_loop V KAZDEM CYKLU void adapt (const vec &glob_dt) { // inicializes vars of cycle of broadcast n_of_broadcast = 0; max_profit = 0; idealTc = Tc; for ( int i = 0; i < signal_groups.length(); i ++ ) { signal_groups(i)->adapt(); } for ( int i = 0; i < received_profit_sum.length(); i++ ) { received_profit_sum(i) = 0; } // nacteni dat do signalnich skupin cout << endl << cycle_counter << " SG " << (cycle_counter%sample_cycles +1) << endl; for ( int i = 0; i < rv_queues.length(); i ++ ) { SignalGroup * sg; sg = signal_groups(i); sg->queue_name = rv_queues.name(i); sg->addQueue(queues(i)); sg->green_time_ratio = green_times(i); sg->cycle_counter = cycle_counter; //cout << sg->name << " " << sg->getSumCarsWaitingTime(Tc) << " " << sg->average_queue_length << " " << sg->green_time_ratio*Tc << " " << sg->getTime2zeroQue() << endl; cout << sg->name << " " << queues(i) << " " << sg->average_queue_length << " " << sg->average_queue_length / (cycle_counter%sample_cycles +1) << endl; } //suggestedTc = idealTc = getIdealTc(); //cout << endl << "CELKOVA FRONTA " << name << " " << getQueue() << endl; BaseTrafficAgent::adapt(glob_dt); } void broadcast(Setting &set){ // 1. cycle of communication // sends all tcs in range +- d_tc and expected profits according to tc // format: tc_index, profit_index if ( n_of_broadcast == 0 && ( cycle_counter % sample_cycles == 0 ) ) { for ( int i = -d_Tc; i <= d_Tc; i++ ) { int time_cycle = Tc + i*stepTc; int profit = getProfit(time_cycle); // send tc stringstream time_cycle_stream; time_cycle_stream << "tc_" << (i+d_Tc); send2allNeighbours( set, time_cycle_stream.str(), time_cycle); // send profit stringstream profit_stream; profit_stream << "profit_" << (i+d_Tc); send2allNeighbours( set, profit_stream.str(), profit ); //cout << name << " tc " << time_cycle << " profit " << profit << " cekani " << getSumCarsWaitingTime(time_cycle) << endl; } //cout << endl; } n_of_broadcast ++; } void receive(const Setting& msg){ string what; string from; double val; UI::get(what, msg, "what", UI::compulsory); UI::get(from, msg, "from", UI::compulsory); UI::get(val, msg, "value"); //cout << name << " receiving from " << from << " " << what << " : " << val<> index; received_Tcs( index ) = val; //cout << "tc " << val << endl; } if ( what.substr(0,6) == "profit" ) { istringstream profiti( what.substr(7, what.length()-7) ); int index; profiti >> index; received_profit_sum( index ) = received_profit_sum( index ) + val; //cout << "profit " << val << endl; } } if ( what == "new_stable_state" ) { //echo("new_stable_state"); BaseTrafficAgent::receive(msg); } } void act (vec &glob_ut){ if ( cycle_counter % sample_cycles == 0 ) { // choose tc with max profit for ( int i = 0; i < received_profit_sum.length(); i ++ ) { int time_cycle = received_Tcs(i); int profit = received_profit_sum(i) + getProfit(time_cycle); if ( profit > max_profit ) { max_profit = profit; idealTc = time_cycle; //cout << name << " idealni Tc " << time_cycle << " s celkovym ziskem " << profit << endl; } } //cout << endl << name << " nastevuje TC na " << idealTc << endl; Tc = idealTc; // nastaveni delky cyklu na Tc vec action; action.set_size(rv_action._dsize()); int st; int stage_time_sum = 0; // soucet delky fazi action(find_index(rv_action, "Tc")) = Tc; for ( int i =0; i < stage_names.length(); i ++) { if ( (i+1) < stage_names.length() ) { st = (stage_times(i)/80)*Tc; stage_time_sum += st; action(find_index(rv_action, stage_names(i))) = st; } else // dopocitani posledni faze - oprava zaokrouhlovaci chyby action(find_index(rv_action, stage_names(i))) = Tc - stage_time_sum; } action2ds.filldown(action,glob_ut); } cycle_counter ++; } }; UIREGISTER(TrafficAgentCycleTime);