#include #include #include #include #include const long MAX_TIME = 10000L; const long NO_STATIONS = 100L; const long FRAME_LENGTH = 100L; long medium_occupied_till = -1; long survival_timer = -1; long successful_packets = 0; long no_frames = MAX_TIME / FRAME_LENGTH; class Station { public: void Init() {}; void TriggerSend(long); }; // class Station void Station::TriggerSend(long current_time) { if(current_time < medium_occupied_till) { // Wir senden, obwohl das Medium noch eine Zeit lang von einem // anderen Paket belegt ist. Das ergibt eine Kollision und toetet // das aktuelle Paket. survival_timer = -1; } // 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 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 moechte 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. // Ausserdem 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); } // if // Ein survival_timer > -1 zeigt, dass noch keine Kollision stattgefunden hat. // Wir inkrementieren den Timer um 1 und wuenschen 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 // ueberlebt 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