//==================================================== file = genzipf.c ===== //= Program to generate Zipf (power law) distributed random variables = //=========================================================================== //= Notes: 1) Writes to a user specified output file = //= 2) Generates user specified number of values = //= 3) Run times is same as an empirical distribution generator = //= 4) Implements p(i) = C/i^alpha for i = 1 to N where C is the = //= normalization constant (i.e., sum of p(i) = 1). = //=-------------------------------------------------------------------------= //= Example user input: = //= = //= ---------------------------------------- genzipf.c ----- = //= - Program to generate Zipf random variables - = //= -------------------------------------------------------- = //= Output file name ===================================> output.dat = //= Random number seed =================================> 1 = //= Alpha vlaue ========================================> 1.0 = //= N value ============================================> 1000 = //= Number of values to generate =======================> 5 = //= -------------------------------------------------------- = //= - Generating samples to file - = //= -------------------------------------------------------- = //= -------------------------------------------------------- = //= - Done! = //= -------------------------------------------------------- = //=-------------------------------------------------------------------------= //= Example output file ("output.dat" for above): = //= = //= 1 = //= 1 = //= 161 = //= 17 = //= 30 = //=-------------------------------------------------------------------------= //= Build: bcc32 genzipf.c = //=-------------------------------------------------------------------------= //= Execute: genzipf = //=-------------------------------------------------------------------------= //= Author: Kenneth J. Christensen = //= University of South Florida = //= WWW: http://www.csee.usf.edu/~christen = //= Email: christen@csee.usf.edu = //=-------------------------------------------------------------------------= //= History: KJC (11/16/03) - Genesis (from genexp.c) = //=========================================================================== //----- Include files ------------------------------------------------------- #include // Needed for assert() macro #include // Needed for printf() #include // Needed for exit() and ato*() #include // Needed for pow() //----- Constants ----------------------------------------------------------- #define FALSE 0 // Boolean false #define TRUE 1 // Boolean true //----- Function prototypes ------------------------------------------------- int zipf(double alpha, int n); // Returns a Zipf random variable double rand_val(int seed); // Jain's RNG //===== Main program ======================================================== void main(void) { FILE *fp; // File pointer to output file char file_name[256]; // Output file name string char temp_string[256]; // Temporary string variable double alpha; // Alpha parameter double n; // N parameter int num_values; // Number of values int zipf_rv; // Zipf random variable int i; // Loop counter // Output banner printf("---------------------------------------- genzipf.c ----- \n"); printf("- Program to generate Zipf random variables - \n"); printf("-------------------------------------------------------- \n"); // Prompt for output filename and then create/open the file printf("Output file name ===================================> "); scanf("%s", file_name); fp = fopen(file_name, "w"); if (fp == NULL) { printf("ERROR in creating output file (%s) \n", file_name); exit(1); } // Prompt for random number seed and then use it printf("Random number seed (greater than 0) ================> "); scanf("%s", temp_string); rand_val((int) atoi(temp_string)); // Prompt for alpha value printf("Alpha value ========================================> "); scanf("%s", temp_string); alpha = atof(temp_string); // Prompt for N value printf("N value ============================================> "); scanf("%s", temp_string); n = atoi(temp_string); // Prompt for number of values to generate printf("Number of values to generate =======================> "); scanf("%s", temp_string); num_values = atoi(temp_string); // Output "generating" message printf("-------------------------------------------------------- \n"); printf("- Generating samples to file - \n"); printf("-------------------------------------------------------- \n"); // Generate and output zipf random variables for (i=0; i= z) { zipf_value = i; break; } } // Assert that zipf_value is between 1 and N assert((zipf_value >=1) && (zipf_value <= n)); return(zipf_value); } //========================================================================= //= Multiplicative LCG for generating uniform(0.0, 1.0) random numbers = //= - x_n = 7^5*x_(n-1)mod(2^31 - 1) = //= - With x seeded to 1 the 10000th x value should be 1043618065 = //= - From R. Jain, "The Art of Computer Systems Performance Analysis," = //= John Wiley & Sons, 1991. (Page 443, Figure 26.2) = //========================================================================= double rand_val(int seed) { const long a = 16807; // Multiplier const long m = 2147483647; // Modulus const long q = 127773; // m div a const long r = 2836; // m mod a static long x; // Random int value long x_div_q; // x divided by q long x_mod_q; // x modulo q long x_new; // New x value // Set the seed if argument is non-zero and then return zero if (seed > 0) { x = seed; return(0.0); } // RNG using integer arithmetic x_div_q = x / q; x_mod_q = x % q; x_new = (a * x_mod_q) - (r * x_div_q); if (x_new > 0) x = x_new; else x = x_new + m; // Return a random value between 0.0 and 1.0 return((double) x / m); }