I'm trying to solve a CodeWars problem called "Training on Binary Genetic Algorithms." There is a fitness function that is preloaded. When the program is run, a test function creates a random 35-bit string and it uses my run function which is supposed to return the same 35-bit string. This string is supposed to be found using a genetic algorithm.
Here is my code:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
typedef double fitness_t (const char *, ...);
extern fitness_t fitness;
void generate (size_t length, char * s)
{
for (size_t i = 0; i < length; i++)
s[i] = rand() % 2 + 48;
}
double sum(size_t n, double ar[n])
{
double sum = 0;
for (int i = 0; i < n; i++)
sum += ar[i];
return sum;
}
void select (int size, char* population[size], double fitnesses[size])
{
double probabilities[size]; // normalized to 1
double r; // random number
int s1, s2;
int i;
for (i = 0; i < size; i++)
probabilities[i] = fitnesses[i] / sum(size, fitnesses);
// select first chromosome
r = (double)(rand() % 1000000) / 1000000; // generates a random float between 0 and 1
for (i = 0; i < size && r > 0; i++)
r -= probabilities[i];
s1 = i;
// select second chromosome
s2 = s1;
while (s2 == s1) // ensures the two chromosomes aren't the same
{
r = (double)(rand() % 1000000) / 1000000; // generates a random float between 0 and 1
for (i = 0; i < size && r > 0; i++)
r -= probabilities[i];
s2 = i;
}
// places these two chromosomes on top
char * temp = population[0];
population[0] = population[s1];
population[s1] = temp;
temp = population[1];
population[1] = population[s2];
population[s2] = temp;
}
void crossover (size_t n, char* s1, char* s2)
{
int r = rand() % n; // select a random bit to cross over at
char temp;
for (size_t i = r; i < n; i++) // swap every bit from bit r to bit n
{
temp = s1[i];
s1[i] = s2[i];
s2[i] = temp;
}
}
void mutate (size_t n, char* s, double p)
{
double r;
for (size_t i = 0; i < n; i++) // for each bit
{
r = (double)(rand() % 1000000) / 1000000; // random float between 0 and 1
if (r <= p) // if random number is less than probability
{
if (s[i] == '1') s[i] = '0'; // swap 0s and 1s
else s[i] = '1';
}
}
}
void bubbleSortPop(int size, char * population[size], double fitnesses[size])
{
int i, j;
char * temp_chrome;
double temp_fitness;
for (i = 0; i < size - 1; i++)
// Last i elements are already in place
for (j = 0; j < size - i - 1; j++)
if (fitnesses[j] < fitnesses[j + 1])
{
temp_chrome = population[j];
population[j] = population[j+1];
population[j+1] = temp_chrome;
temp_fitness = fitnesses[j];
fitnesses[j] = fitnesses[j+1];
fitnesses[j+1] = temp_fitness;
}
}
// this function changes the population.
// select, crossover, mutate
void evolve(fitness_t f, size_t size, int length, char * population[size],
double fitnesses[size], double p_c, double p_m)
{
char * s1, * s2;
double f1, f2;
char * temp_pop[size+2];
double temp_fit[size+2];
int i;
double r;
// moves two selected parents to the top
select(size, population, fitnesses);
// begin reproduction process; duplicate the chromosomes
s1 = population[0];
s2 = population[1];
// crossover
r = (double)(rand() % 1000000) / 1000000; // random float between 0 and 1
if (r < p_c) // probability of crossing over
crossover(length, s1, s2); // commences with crossover
// mutate
mutate(length, s1, p_m);
mutate(length, s2, p_m);
// calculate fitnesses
f1 = f(s1);
f2 = f(s2);
// merge fitneses
// copy original fitnesses into temp_fit
for (i = 0; i < size; i++)
temp_fit[i] = fitnesses[i];
// add new fitnesses
temp_fit[size] = f1;
temp_fit[size+1] = f2;
// merge children into population
// copy original population into temp_pop
for (i = 0; i < size; i++)
temp_pop[i] = population[i];
// add two children to temp_pop
temp_pop[size] = s1;
temp_pop[size+1] = s2;
// sort fitnesses and population
bubbleSortPop(size+2, temp_pop, temp_fit);
// add first 100 elements of temp_pop and fit to population and fitnesses
for (i = 0; i < size; i++)
{
population[i] = temp_pop[i];
fitnesses[i] = temp_fit[i];
}
}
char* runN (fitness_t f, int length, double p_c, double p_m, size_t iterations) {
}
char* run (fitness_t f, int length, double p_c, double p_m)
{
size_t size = 100;
char * population[size];
double fitnesses[size];
size_t i;
int r;
srand(time(0));
// initialize population array
for (i = 0; i < size; i++)
population[i] = malloc((length+1) * sizeof(char));
// generate original population
for (i = 0; i < size; i++)
{
generate(length, population[i]);
fitnesses[i] = f(population[i]);
printf("[%2d] %s %lf\n", i, population[i], fitnesses[i]);
}
// evolve the population
for (i = 0; i < 10; i++)
evolve(f, size, length, population, fitnesses, p_c, p_m);
// print result
printf("\nAFTER EVOLUTION\n");
for (i = 0; i < size; i++) // generates original population
printf("[%2d] %s %lf\n", i, population[i], fitnesses[i]);
// store best chromosome and free memory
char ret[length+1];
strcpy(ret, population[0]);
for (i = 0; i < size; i++)
free(population[i]);
return ret;
}
The issue is when I run my code, it nearly always comes out with a segfault at some point while printing the contents of population and fitness.
At least these problems:
Attempting to print a non-string with "%s"
Code uses "%s" and passes population[i] as if it points to a string. population[i] does not point to a string as it does not certainly have a null character. Result undefined behavior (UB). Perhaps attempting to access beyond allocated memory.
// Undefined behavior: population[i] not a string
printf("[%2d] %s %lf\n", i, population[i], fitnesses[i]);
Set the null character.
generate(length, population[i]);
population[i][length] = '\0'; // Add this here or equivalent in `generate()`.
Many compiler warnings (20+)
Enable all compiler warnings and fix those.
I found the solution. It was all the places where I tried to copy a string by making a string pointer and assigning it the same address as the pointer I wanted to copy. For example, in 'select', when I tried to move the two strings to the top, I did
char * temp = population[0];
population[0] = population[s1];
population[s1] = temp;
temp = population[1];
population[1] = population[s2];
population[s2] = temp;
I changed this to using strcpy(). I made the same mistake in 'evolve' where I tried to duplicate the chromosomes by just copying their address into variables, rather than the strings themselves:
char * s1, * s2;
// begin reproduction process; duplicate the chromosomes
s1 = population[0];
s2 = population[1];
I changed it to this:
char s1[length+1], s2[length+1];
strcpy(s1, population[0]);
strcpy(s2, population[1]);
After I made this change the segfault went away. Thanks for all your answers.
I am trying to implement Simpson 1/3 rule in C and facing a problem with using malloc inside a for loop.
My current implementation is
int integrateSimpson(Integrate *intereg)
{
int i, j, iLoop, last;
double *tempOne = (double *) malloc(sizeof(double) * 1);
double *tempTwo = (double *) malloc(sizeof(double) * 1);
double dx, sumOdd, sumEven, area;
double lowerLimit = intereg->lowerLimit;
double upperLimit = intereg->upperLimit;
int *intervals = intereg->intervals;
int nIntervals = intereg->nIntervals;
int method = intereg->method;
for(j = 0; j < nIntervals; j++ )
{
printf("Number of Intervals: %d",nIntervals);
for(iLoop = 0; iLoop < nIntervals; iLoop++){
printf("\nIntervals: %d", intervals[iLoop]);
}
tempOne = (double *) realloc(tempOne, sizeof(double) * intervals[j]);
tempTwo = (double *) realloc(tempTwo, sizeof(double) * intervals[j]);
if(tempTwo == NULL || tempOne == NULL)
{
TRACE("Could not realloc memory to temporary arrays");
return EXIT_FAILURE;
}
if(intervals[j] % 2 != 0)
{
TRACE("Found odd interval, adding 1 to make it even");
intervals[j] = intervals[j] + 1;
}
dx = (upperLimit - lowerLimit) / intervals[j];
for(i = 0; i <= intervals[j]; i++)
{
tempOne[i] = lowerLimit + i * dx;
tempTwo[i] = intereg->func(tempOne[i]);
}
sumOdd = 0;
sumEven = 0;
for(i = 1; i < intervals[j]; i++)
{
if(i % 2 == 1)
{
sumOdd += tempTwo[i];
}
else
{
sumEven += tempTwo[i];
}
}
printf("\nPassed %d time", j );
last = intervals[j] - 1;
area = dx / 3 * (tempTwo[0] + tempTwo[last] + 4 * sumOdd + 2 * sumEven);
intereg->areaUnderCurve[j] = area;
intereg->resultMatrix[method - 1][j] = intereg->areaUnderCurve[j];
}
free(tempOne);
tempOne = NULL;
free(tempTwo);
tempTwo = NULL;
return EXIT_SUCCESS;
}
I tried to debug this and found that for intervals = {2,8,16,64} the loop works fine for the first time even the realloc part but with the second iteration for some reason, realloc doesn't work and I get a segmentation fault. I tried to reproduce this problem in the following way but the code below works fine
int i;
double *temp;
/* Initial memory allocation */
temp = (double *) malloc(sizeof(double)*1);
/* Reallocating memory */
for(i = 0;i<10;i++)
{
temp = (double *) realloc(temp, sizeof(double)* i);
}
free(temp);
temp = NULL;
I know that realloc basically assigns a new memory at the same time frees the memory pointed by the pointer passed to it. But what is wrong that I am doing here?
Also is it a good way to use malloc with loops?
Any lead is appreciated!
int main()
{
int abc[2][2];
int i,j,q,r,u,k;
char *A = malloc(sizeof(*A));
abc[0][0] = 1;
abc[1][0] = 0;
abc[0][1] = 7;
abc[1][1] = 480;
do
{
if( abc[1][1]>abc[0][1])
{
q = floor((abc[1][1] - 1)/abc[0][1]);
r = abc[1][1] - q*abc[0][1];
abc[1][0] = q*abc[0][0] + abc[1][0];
abc[1][1] = r;
}
if( abc[0][1]>abc[1][1])
{
q = floor((abc[0][1] - 1)/abc[1][1]);
r = abc[0][1] - q*abc[1][1];
abc[0][0] = q*abc[1][0] + abc[0][0];
abc[0][1] = r;
}
u = abc[0][0];
A[k] = abc[1][0];
} while (abc[0][1]>1);
return 0;
}
I want to store each the values for the index - abc[1][0] in array A[] so that I cant use that array further but I'm stuck at storing all the values
If you want to record the value of abc[1][0] in the end of each loop, you can do like this:
int* A = malloc(1000 * sizeof(*A)); // Note: Room for 1000 values
k = 0;
....
....
do
{
....
....
if (k < 1000)
{
A[k] = abc[1][0];
++k;
}
} while (abc[0][1]>1);
// Print the recorded values
printf("Recorded %d values\n", k);
int t;
for (t = 0; t < k; ++t) printf("Value[%d]=%d\n", t, A[t]);
This will record the first 1000 values.
If you want to be able to record "any" number of values, you shall take a look at realloc so that you can assign more memory when you reach 1000
I have this part of a code which is reading a 2D array of structs, doing some math on them that putting the results into a second 2D array:
#pragma omp parallel for private (n, i, j) schedule(dynamic)
for(n = 0; n < frames_read; n++){
for (i = 0; i < atoms_total; i++)
{
for(j = 0; j < atoms_total; j++)
{
if (timestep_array[i][n].atom_id == timestep_array[j][m].atom_id)
{
// calculates the vector magnitude and stores it in the created array MSD
double temp1_x = timestep_array[i][n].normalized_x_position + timestep_array[i][n].x_box;
double temp2_x = timestep_array[j][n+1].normalized_x_position + timestep_array[j][n+1].x_box;
double temp3_x = temp2_x - temp1_x;
double temp4_x = temp3_x * box_bound_x;
double temp5_x = pow(temp4_x, 2);
double temp1_y = timestep_array[i][n].normalized_y_position + timestep_array[i][n].y_box;
double temp2_y = timestep_array[j][n+1].normalized_y_position + timestep_array[j][n+1].y_box;
double temp3_y = temp2_y - temp1_y;
double temp4_y = temp3_y * box_bound_y;
double temp5_y = pow(temp4_y, 2);
double temp1_z = timestep_array[i][n].normalized_z_position + timestep_array[i][n].z_box;
double temp2_z = timestep_array[j][n+1].normalized_z_position + timestep_array[j][n+1].z_box;
double temp3_z = temp2_z - temp1_z;
double temp4_z = temp3_z * box_bound_z;
double temp5_z = pow(temp4_z, 2);
double temp = temp5_x + temp5_y + temp5_z;
double temp2 = sqrt(temp);
int atom_number = timestep_array[i][n].atom_id;
MSD[atom_number][n].msd = sqrt(temp2);
MSD[atom_number][n].atom_type = timestep_array[i][n].atom_type;
MSD[atom_number][n].time_in_picoseconds = timestep_array[i][n].timestep / picoseconds;
}
}
}
}
I have tried so many combinations of the #pragma statement (including making many more of the variables private.) Nothing has resulted in the a.out file running more than one thread. What am I doing wrong?
How do i find mean , median of a set of numbers without using arrays in C?
Question is rather not the way to find mean or median but how to store a set of numbers and perform some operations on them if use of arrays is not allowed ?
A fun problem.
The key to to find a place to store all the numbers. Code could use a file, a linked list, etc. The below uses a linked list and recursion.
Leave it to OP for refinements about multiple modes or median when count is even.
typedef struct num_S {
struct num_S *prev;
double x;
} num_T;
void GetNum(num_T *prev) {
num_T current;
current.prev = prev;
// If new number found ...
if (scanf("%lf", ¤t.x) == 1) {
num_T *p = ¤t;
// Sort new entry into list
while (p->prev != NULL && p->x < p->prev->x) {
double t = p->x;
p->x = p->prev->x;
p->prev->x = t;
p = p->prev;
}
GetNum(¤t);
// End of list -now process the list
} else {
unsigned ModeCount = 0;
double Mode = 0.0;
unsigned ModeCandidateCount = 0;
double ModeCandidate = 0.0 / 0.0;
unsigned Count = 0;
double SumX = 0.0;
double SumXX = 0.0;
num_T *p = current.prev;
while (p != NULL) {
Count++;
SumX += p->x;
SumXX += p->x * p->x;
if (p->x == ModeCandidate) {
ModeCandidateCount++;
} else {
ModeCandidateCount = 1;
ModeCandidate = p->x;
}
if (ModeCandidateCount > ModeCount) {
ModeCount = ModeCandidateCount;
Mode = p->x;
}
p = p->prev;
}
printf("Count = %u\n", Count);
if (Count > 0) {
printf("Mode = %lf Count %u\n", Mode, ModeCount);
printf("Mean = %lf\n", SumX / Count);
printf("STD = %lf\n", sqrt(Count * SumX - SumXX) / Count);
Count /= 2;
num_T *p = current.prev;
while (Count-- > 0) {
p = p->prev;
}
printf("Median = %lf\n", p->x);
}
fflush(stdout);
}
}
int main(void) {
GetNum(NULL);
return 0;
}
Input 4 3 4 2 4 1 EOF
Output:
Count = 6
Mode = 4.000000 Count 3
Mean = 3.000000
STD = 1.130388
Median = 3.000000
STD Ref: STD Rapid calculation methods