void mutate(gsl_matrix *chromosome, gsl_matrix *bounds, pcg32_random_t *rng) { uint32_t rows = chromosome->size1, cols = chromosome->size2, row, col; double r, min, max; // Select a random row and column row = (uint32_t)pcg32_boundedrand_r(rng, rows); col = (uint32_t)pcg32_boundedrand_r(rng, cols); // Set to a random value within the bounds min = gsl_matrix_get(bounds, col, 0); max = gsl_matrix_get(bounds, col, 1); r = (ldexp(pcg32_random_r(rng), -32) * (max - min)) + min; gsl_matrix_set(chromosome, row, col, r); if (DEBUG == DEBUG_MUTATE) { printf(YELLOW "MUTATED CHROMSOME\n" RESET); printf(YELLOW "ROW: %d, COL: %d, VAL: %10.6f\n" RESET, row, col, r); for (uint32_t i = 0; i < rows; ++i) { for (uint32_t j = 0; j < cols; ++j) { printf(YELLOW "%10.6f " RESET, gsl_matrix_get(chromosome, i, j)); } printf("\n"); } } }
void choice_floyd(pcg32_random_t *rng, int *values, int M, int N) { /* Floyd's algorithm for returning a list of M random numbers in the range 0,...,N-1. Preferable to Knuth's method when M << N (though Knuth is still viable). Uses Melissa O'Neil's PCG generator. */ int in; int im = 0; unsigned char *is_used = malloc(N*sizeof(unsigned char)); for (int i = 0; i < N; i++) { is_used[i] = 0; } for(in = N - M; in < N && im < M; ++in) { int r = pcg32_boundedrand_r(rng,N-1); if (is_used[r]) { r = in; } values[im++] = r; is_used[r] = 1; } free(is_used); }
/* * Generates uniformly random keys [0, MAX_KEY_VAL] on each rank using the time and rank * number as a seed */ static KEY_TYPE * make_input(void) { timer_start(&timers[TIMER_INPUT]); KEY_TYPE * restrict const my_keys = malloc(NUM_KEYS_PER_PE * sizeof(KEY_TYPE)); pcg32_random_t rng = seed_my_rank(); for(uint64_t i = 0; i < NUM_KEYS_PER_PE; ++i) { my_keys[i] = pcg32_boundedrand_r(&rng, MAX_KEY_VAL); } timer_stop(&timers[TIMER_INPUT]); #ifdef DEBUG wait_my_turn(); char msg[1024]; const int my_rank = shmem_my_pe(); sprintf(msg,"Rank %d: Initial Keys: ", my_rank); for(uint64_t i = 0; i < NUM_KEYS_PER_PE; ++i){ if(i < PRINT_MAX) sprintf(msg + strlen(msg),"%d ", my_keys[i]); } sprintf(msg + strlen(msg),"\n"); printf("%s",msg); fflush(stdout); my_turn_complete(); #endif return my_keys; }
void dostep(world *w){ int nextbind = pcg32_boundedrand_r(&rng, w->nbonds); //ran_int(0, w->nbonds); int nextbond = w->bonds[nextbind]; double test = ldexp(pcg32_random_r(&rng), -32); int ind0, ind1; bond2inds(w->N, nextbond, &ind0, &ind1); int ind = 0; int tx, ty; if (w->grid[ind0] == w->grid[ind1]){ remove_bond(w, nextbond); return; } if (test < 1.0/(1+w->alpha)){ ind = ind0 * (w->grid[ind0] == SS) + ind1 * (w->grid[ind1] == SS); ind2xy(w->N, ind, &tx, &ty); add_zombie(w, tx, ty); } else { ind = ind0 * (w->grid[ind0] == SZ) + ind1 * (w->grid[ind1] == SZ); ind2xy(w->N, ind, &tx, &ty); kill_site(w, tx, ty); } }
/* * Generates uniformly random keys [0, MAX_KEY_VAL] on each rank using the time and rank * number as a seed */ static KEY_TYPE * make_input(void) { timer_start(&timers[TIMER_INPUT]); KEY_TYPE * const my_keys = malloc(NUM_KEYS_PER_PE * sizeof(KEY_TYPE)); assert(my_keys); pcg32_random_t rng = seed_my_rank(); #ifdef ISX_PROFILING unsigned long long start = current_time_ns(); #endif for(uint64_t i = 0; i < NUM_KEYS_PER_PE; ++i) { my_keys[i] = pcg32_boundedrand_r(&rng, MAX_KEY_VAL); } #ifdef ISX_PROFILING unsigned long long end = current_time_ns(); if (shmem_my_pe() == 0) printf("Making input took %llu ns\n", end - start); #endif timer_stop(&timers[TIMER_INPUT]); #ifdef DEBUG wait_my_turn(); char msg[1024]; const int my_rank = shmem_my_pe(); sprintf(msg,"Rank %d: Initial Keys: ", my_rank); for(uint64_t i = 0; i < NUM_KEYS_PER_PE; ++i){ if(i < PRINT_MAX) sprintf(msg + strlen(msg),"%d ", my_keys[i]); } sprintf(msg + strlen(msg),"\n"); printf("%s",msg); fflush(stdout); my_turn_complete(); #endif return my_keys; }
/* Delete a single file @return Zero on successful wipe */ int deleteFile(char fileName[], int passes) { pcg32_random_t rng; // chmod if requested (-a) if (forceFiles) { removeAttribute(fileName); } if (access(fileName,W_OK) == 0) { printf("\nWiping %s...",fileName); FILE *fp = fopen(fileName,"rb+"); // Move to end of file to get a correct result from ftell fseek(fp, 0, SEEK_END); int fileSize = ftell(fp); // Wipe file int wipeCounter; for (wipeCounter = 0; wipeCounter < passes; wipeCounter++) { int offsetCounter; // Reset position fseek(fp,0,SEEK_SET); for (offsetCounter = 0; offsetCounter < fileSize; offsetCounter++) { int rand = pcg32_boundedrand_r(&rng,256); fprintf(fp,"%c",rand); } } fclose(fp); if (!keepFiles) { printf("\nScrambling and deleting %s...",fileName); scrambleName(fileName,25); } } else { printf("\nERROR: Cannot get write access to %s (try running with -a arg)",fileName); return -1; } return 0; }
uint32_t pcg32_boundedrand(uint32_t bound) { return pcg32_boundedrand_r(&pcg32_global, bound); }
void crossover(gsl_matrix *parent1, gsl_matrix *parent2, pcg32_random_t *rng) { uint32_t rows = parent1->size1, cols = parent1->size2; uint32_t cut = (uint32_t)pcg32_boundedrand_r(rng, rows-1) + 1; bool left = (bool)pcg32_boundedrand_r(rng, 2); gsl_matrix *temp = gsl_matrix_alloc(1, cols); if (DEBUG == DEBUG_CROSSOVER) { printf(YELLOW "CROSSOVER CENTROIDS BEFORE\n" RESET); printf(YELLOW "CHROMSOME CUT POINT: %d\n", cut); printf(YELLOW "CROSSOVER SIDE: %s\n", left ? "left" : "right"); printf(YELLOW "PARENT[1]:\n" RESET); for (uint32_t i = 0; i < rows; ++i) { for (uint32_t j = 0; j < cols; ++j) { printf(YELLOW "%10.6f " RESET, gsl_matrix_get(parent1, i, j)); } printf("\n"); } printf(YELLOW "PARENT[2]:\n" RESET); for (uint32_t i = 0; i < rows; ++i) { for (uint32_t j = 0; j < cols; ++j) { printf(YELLOW "%10.6f " RESET, gsl_matrix_get(parent2, i, j)); } printf("\n"); } } if (left) { // Swap left half of chromosome for (uint32_t i = 0; i < cut; ++i) { gsl_vector_view parent1_row = gsl_matrix_row(parent1, i); gsl_vector_view parent2_row = gsl_matrix_row(parent2, i); gsl_vector_view temp_row = gsl_matrix_row(temp, 0); gsl_vector_memcpy(&temp_row.vector, &parent2_row.vector); gsl_vector_memcpy(&parent2_row.vector, &parent1_row.vector); gsl_vector_memcpy(&parent1_row.vector, &temp_row.vector); } } else { // Swap the right half of chromosome for (uint32_t i = cut; i < rows; ++i) { gsl_vector_view parent1_row = gsl_matrix_row(parent1, i); gsl_vector_view parent2_row = gsl_matrix_row(parent2, i); gsl_vector_view temp_row = gsl_matrix_row(temp, 0); gsl_vector_memcpy(&temp_row.vector, &parent2_row.vector); gsl_vector_memcpy(&parent2_row.vector, &parent1_row.vector); gsl_vector_memcpy(&parent1_row.vector, &temp_row.vector); } } if (DEBUG == DEBUG_CROSSOVER) { printf(YELLOW "CROSSOVER CENTROIDS AFTER\n" RESET); printf(YELLOW "CHROMSOME CUT POINT: %d\n", cut); printf(YELLOW "CROSSOVER SIDE: %s\n", left ? "left" : "right"); printf(YELLOW "PARENT[1]:\n" RESET); for (uint32_t i = 0; i < rows; ++i) { for (uint32_t j = 0; j < cols; ++j) { printf(YELLOW "%10.6f " RESET, gsl_matrix_get(parent1, i, j)); } printf("\n"); } printf(YELLOW "PARENT[2]:\n" RESET); for (uint32_t i = 0; i < rows; ++i) { for (uint32_t j = 0; j < cols; ++j) { printf(YELLOW "%10.6f " RESET, gsl_matrix_get(parent2, i, j)); } printf("\n"); } } gsl_matrix_free(temp); }
int main(int argc, char** argv) { // Read command-line options int rounds = 5; bool nondeterministic_seed = false; int round, i; ++argv; --argc; if (argc > 0 && strcmp(argv[0], "-r") == 0) { nondeterministic_seed = true; ++argv; --argc; } if (argc > 0) { rounds = atoi(argv[0]); } // In this version of the code, we'll use a local rng, rather than the // global one. pcg32_random_t rng; // You should *always* seed the RNG. The usual time to do it is the // point in time when you create RNG (typically at the beginning of the // program). // // pcg32_srandom_r takes two 64-bit constants (the initial state, and the // rng sequence selector; rngs with different sequence selectors will // *never* have random sequences that coincide, at all) - the code below // shows three possible ways to do so. if (nondeterministic_seed) { // Seed with external entropy -- the time and some program addresses // (which will actually be somewhat random on most modern systems). // A better solution, entropy_getbytes, using /dev/random, is provided // in the full library. pcg32_srandom_r(&rng, time(NULL) ^ (intptr_t)&printf, (intptr_t)&rounds); } else { // Seed with a fixed constant pcg32_srandom_r(&rng, 42u, 54u); } printf("pcg32_random_r:\n" " - result: 32-bit unsigned int (uint32_t)\n" " - period: 2^64 (* 2^63 streams)\n" " - state type: pcg32_random_t (%zu bytes)\n" " - output func: XSH-RR\n" "\n", sizeof(pcg32_random_t)); for (round = 1; round <= rounds; ++round) { printf("Round %d:\n", round); /* Make some 32-bit numbers */ printf(" 32bit:"); for (i = 0; i < 6; ++i) printf(" 0x%08x", pcg32_random_r(&rng)); printf("\n"); /* Toss some coins */ printf(" Coins: "); for (i = 0; i < 65; ++i) printf("%c", pcg32_boundedrand_r(&rng, 2) ? 'H' : 'T'); printf("\n"); /* Roll some dice */ printf(" Rolls:"); for (i = 0; i < 33; ++i) { printf(" %d", (int)pcg32_boundedrand_r(&rng, 6) + 1); } printf("\n"); /* Deal some cards */ enum { SUITS = 4, NUMBERS = 13, CARDS = 52 }; char cards[CARDS]; for (i = 0; i < CARDS; ++i) cards[i] = i; for (i = CARDS; i > 1; --i) { int chosen = pcg32_boundedrand_r(&rng, i); char card = cards[chosen]; cards[chosen] = cards[i - 1]; cards[i - 1] = card; } printf(" Cards:"); static const char number[] = {'A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K'}; static const char suit[] = {'h', 'c', 'd', 's'}; for (i = 0; i < CARDS; ++i) { printf(" %c%c", number[cards[i] / SUITS], suit[cards[i] % SUITS]); if ((i + 1) % 22 == 0) printf("\n\t"); } printf("\n"); printf("\n"); } return 0; }