/* Program to simulate Budgie Bedlam */ /* for CPSC 441 Assignment 4, January 2012. */ /* */ /* Written by Carey Williamson, Jan 12, 2011 */ /* Updated by Carey Williamson, Jan 11, 2012 */ /* */ /* Usage: cc -o budgie budgie.c -lm */ /* ./budgie */ #include #include /* Constants */ #define N 2 /* Number of budgies */ #define MEAN_QUIET_TIME 90.0 /* Mean quiet time in minutes */ #define MEAN_SONG_TIME 10.0 /* Mean song time in minutes */ /* Simulation parameters */ #define WARM_UP 10000.0 #define END_TIME 1000000.0 /* Budgie states */ #define QUIET 0 #define SINGING 1 /* Song duration model */ #define EXPONENTIAL 1 /* #define CONSTANT 1 */ /* Debugging flags */ /* #define DEBUG 1 */ /* #define DEBUG2 1 */ /* Parameters for random number generation. */ #define MAX_INT 2147483647 /* Maximum positive integer 2^31 - 1 */ double log(); /* Generate a random floating point number uniformly distributed in [0,1] */ double Uniform01() { double randnum; /* get a random positive integer from random() */ randnum = (double) 1.0 * random(); /* divide by max int to get something in the range 0.0 to 1.0 */ randnum = randnum / (1.0 * MAX_INT); return( randnum ); } /* Generate a random floating point number from an exponential */ /* distribution with mean mu. */ double Exponential(mu) double mu; { double randnum, ans; randnum = Uniform01(); ans = -(mu) * log(randnum); return( ans ); } main() { int i; int active, nexteventindex, status[N]; int songtries, perfectsongs; int mostrecentsongertostart; double mostrecentsongstarttime, mostrecentsongendtime; double now, lastcheck, nexteventtime, nextevent[N]; double randnum; double idletime, melodioustime, squawkytime, perfecttime; /* initialization */ now = 0.0; lastcheck = 0.0; srand(123457); idletime = 0.0; melodioustime = 0.0; squawkytime = 0.0; perfecttime = 0.0; songtries = 0; perfectsongs = 0; active = 0; for( i = 0; i < N; i++ ) { status[i] = QUIET; nextevent[i] = Exponential( MEAN_QUIET_TIME ); #ifdef DEBUG2 printf("Budgie %d will start singing at time %5.3f\n", i, nextevent[i]); #endif } /* main simulation loop */ while( now < END_TIME ) { /* find next event to happen */ nexteventtime = END_TIME; for( i = 0; i < N; i++ ) { if( nextevent[i] < nexteventtime ) { nexteventtime = nextevent[i]; nexteventindex = i; } } #ifdef DEBUG2 printf("Next event is for Budgie %d at time %5.3f\n", nexteventindex, nexteventtime); #endif if( nexteventtime < END_TIME ) { /* update statistics and determine state transition */ now = nexteventtime; if( status[nexteventindex] == QUIET ) { /* This Budgie is just starting to sing */ if( active == 0 ) idletime += now - lastcheck; else if( active == 1 ) melodioustime += now - lastcheck; else squawkytime += now - lastcheck; lastcheck = now; songtries++; mostrecentsongertostart = nexteventindex; mostrecentsongstarttime = now; #ifdef DEBUG for( i = 0; i < active; i++ ) printf(" "); printf("Budgie %d starting to sing at time %5.3f\n", nexteventindex, now); #endif status[nexteventindex] = SINGING; #ifdef EXPONENTIAL nextevent[nexteventindex] += Exponential( MEAN_SONG_TIME ); #endif #ifdef CONSTANT nextevent[nexteventindex] += MEAN_SONG_TIME; #endif active++; } else { /* This Budgie is done singing */ if( active == 0 ) printf("Error keeping track of singing Budgies!!!\n"); else if( active == 1 ) { melodioustime += now - lastcheck; if( (mostrecentsongertostart == nexteventindex) && (mostrecentsongendtime < mostrecentsongstarttime) ) perfectsongs++; perfecttime += now - lastcheck; } else squawkytime += now - lastcheck; lastcheck = now; mostrecentsongendtime = now; status[nexteventindex] = QUIET; active--; nextevent[nexteventindex] += Exponential( MEAN_QUIET_TIME ); #ifdef DEBUG for( i = 0; i < active; i++ ) printf(" "); printf("Budgie %d is done singing at time %5.3f\n", nexteventindex, now); #endif } } else { /* time to quit */ now = END_TIME; if( active == 0 ) idletime += now - lastcheck; else if( active == 1 ) melodioustime += now - lastcheck; else squawkytime += now - lastcheck; lastcheck = now; } } /* print out statistics */ printf("N = %d, MEAN_QUIET_TIME = %8.6f, MEAN_SONG_TIME = %8.6f\n", N, MEAN_QUIET_TIME, MEAN_SONG_TIME); printf("S = %8.6f\n", MEAN_SONG_TIME / (MEAN_QUIET_TIME + MEAN_SONG_TIME)); printf("Total time observing BLAN: %8.6f\n", now); printf(" Idle time on the BLAN: %8.6f %8.6f%%\n", idletime, 100.0 * idletime / now); printf(" Melodious time on BLAN: %8.6f %8.6f%%\n", melodioustime, 100.0 * melodioustime / now); printf(" Squawky time on the BLAN: %8.6f %8.6f%%\n", squawkytime, 100.0 * squawkytime / now); printf("\n Attempted songs: %d\n", songtries); printf(" Perfect songs: %d\n", perfectsongs); printf(" Perfect songs/Attempted songs: %8.6f (%4.2f%%)\n", 1.0*perfectsongs/songtries, 100.0*perfectsongs/songtries); printf(" Perfect song time on the BLAN: %8.6f %8.6f%%\n", perfecttime, 100.0 * perfecttime / now); printf("Quiet Melodious Squawky\n"); printf("%8.6f ", idletime/now); if( N > 0 ) printf("%8.6f ", melodioustime/now); else printf("0.000000 "); if( N > 1 ) printf("%8.6f ", squawkytime/now); else printf("0.000000 "); printf("\n"); }