#include #include #include #include #include const long MAX_TIME = 10000L; const long NO_STATIONS = 100L; const long FRAME_LENGTH = 100L; const long PROBABILITY = 1000000L; long medium_occupied_till = -1; long survival_timer = -1; long successful_packets = 0; long no_frames = MAX_TIME / FRAME_LENGTH; class Station { public: bool intend_to_send; public: void Init() {intend_to_send = false;}; void TriggerSend(long); void IntendToSend(long); }; // class Station void Station::TriggerSend(long current_time) { if(current_time < medium_occupied_till) { // Wir senden nicht, da das Medium belegt ist. Jedoch // wird der Sendewunsch vermerkt. intend_to_send = true; return; } // if // Das Medium war frei. Ein neues Paket ist gerade 0 Zeiteinheiten // alt geworden. else survival_timer = 0; // Unser neues Paket wird bis zu diesem Zeitpunkt auf dem Kanal sein: medium_occupied_till = current_time + FRAME_LENGTH; } // Station::TriggerSend void Station::IntendToSend(long current_time) { if(intend_to_send) { if(current_time < medium_occupied_till) { survival_timer = -1; } // if else survival_timer = 0; medium_occupied_till = current_time + FRAME_LENGTH; } // if intend_to_send = false; } // Station::IntendToSend main() { Station* station = new Station[NO_STATIONS]; for(long i = 0; i < NO_STATIONS; i++) station[i].Init(); // Ankunftsraten zwischen 0 und 4 Paketen pro Rahmenzeit simulieren for(long arrival_rate = 0; arrival_rate < 400; arrival_rate += 1) { // Prozentanzeige fuer gelangweilten Benutzer cerr << arrival_rate*100/400 << " % " << (char)(13) << flush; medium_occupied_till = -1; survival_timer = -1; successful_packets = 0; // Abklappern von MAX_TIME Simulationssekunden. Ein Rahmen hat 100 davon. for(long time = 0; time < MAX_TIME; time++) { // Jede Station fragen, ob sie senden möchte for(long station_index = 0; station_index < NO_STATIONS; station_index++) { // Die Station darf nur senden, wenn die Zufallszahl kleiner als arrival_rate ist, // aber vorsicht, sonst fragen wir viel zu oft! Es sollte eigentlich nur 1x pro // Rahmenzeit gefragt werden, wir fragen aber 100x pro Rahmenzeit. Das Ereignis muss // daher 100x (=FRAME_LENGTH) unwahrscheinlicher sein, daher arrival_rate*FRAME_LENGTH. // Außerdem fragen wir jede Station einzeln, wollten aber nur eine gesamt Ankunftsrate // vorgeben, daher arrival_rate*FRAME_LENGTH*NO_STATIONS. if((abs(rand()) % (100*NO_STATIONS*FRAME_LENGTH)) < arrival_rate) station[station_index].TriggerSend(time); // Steht am Anfang einer neuen Rahmenzeit ein alter Sendewunsch aus? if((time % FRAME_LENGTH) == 0) if((abs(rand()) % PROBABILITY) < 1) station[station_index].IntendToSend(time); } // if // Ein survival_timer > -1 zeigt, dass noch keine Kollision stattgefunden hat. // Wir inkrementieren den Timer um 1 und wünschen dem Paket weiter alles Gute. if(survival_timer != -1) survival_timer++; if(survival_timer == FRAME_LENGTH) { // Der seltene Fall ist eingetreten, dass das Paket eine volle Rahmenzeit // überlegt hat. successful_packets++; survival_timer = -1; } // if } // for double overall_arrival_rate = ((double)arrival_rate)/100.0; cout << overall_arrival_rate << " " << (double)successful_packets/(double)no_frames << endl; } // for delete[] station; } // main