0

I am doing small coding on Genetic Algorithm and the below is my main function :

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mpi.h>
#include <limits.h>
#define N 8
#define POPULATION_SIZE 100
#define MUTATION_RATE 0.3
#define MAX_GENERATIONS 50
typedef struct {
 int board[N];
 int fitness;
} Individual;
int calculateFitness(int board[]) {
 int conflicts = 0;
 for (int i = 0; i < N; i++) {
 for (int j = i + 1; j < N; j++) {
 if (board[i] == board[j] || abs(board[i] - board[j]) == j - i) {
 conflicts++;
 }
 }
 }
 return conflicts;
}
void initializePopulation(Individual population[]) {
 for (int i = 0; i < POPULATION_SIZE; i++) {
 for (int j = 0; j < N; j++) {
 population[i].board[j] = rand() % N;
 }
 population[i].fitness = calculateFitness(population[i].board); // Calculate fitness for each individual
 }
}
void selection(Individual population[], Individual matingPool[]) {
 // Tournament selection
 for (int i = 0; i < POPULATION_SIZE; i++) {
 int idx1 = rand() % POPULATION_SIZE;
 int idx2 = rand() % POPULATION_SIZE;
 if (population[idx1].fitness < population[idx2].fitness) {
 matingPool[i] = population[idx1];
 } else {
 matingPool[i] = population[idx2];
 }
 } 
}
void crossover(Individual population[], Individual matingPool[]) {
// MPI_Barrier(MPI_COMM_WORLD);
 for (int i = 0; i < POPULATION_SIZE; i += 2) {
 int crossoverPoint = rand() % (N - 1) + 1; // Random crossover point
 for (int j = 0; j < crossoverPoint; j++) {
 population[i].board[j] = matingPool[i].board[j];
 population[i + 1].board[j] = matingPool[i + 1].board[j];
 }
 for (int j = crossoverPoint; j < N; j++) {
 population[i].board[j] = matingPool[i + 1].board[j];
 population[i + 1].board[j] = matingPool[i].board[j];
 }
 population[i].fitness = calculateFitness(population[i].board); // Recalculate fitness after crossover
 population[i + 1].fitness = calculateFitness(population[i + 1].board); 
 MPI_Barrier(MPI_COMM_WORLD);
 }
}
void mutate(Individual population[]) {
 for (int i = 0; i < POPULATION_SIZE; i++) {
 if ((double)rand() / RAND_MAX < MUTATION_RATE) {
 int mutationPoint = rand() % N; // Random mutation point
 int newGene = rand() % N; // New random gene
 population[i].board[mutationPoint] = newGene;
 population[i].fitness = calculateFitness(population[i].board); // Recalculate fitness after mutation
 }
 }
}
Individual population[POPULATION_SIZE];
int main(int argc, char *argv[]) {
 MPI_Init(&argc, &argv);
 int rank, size;
// MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// MPI_Comm_size(MPI_COMM_WORLD, &size);
// int totalPopulationSize = 100; // Replace with the actual total population size
 int numProcesses;
 int remainder;
 
 MPI_Comm_size(MPI_COMM_WORLD, &size);
 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
 
 int chunkSize = POPULATION_SIZE / size;
 remainder = POPULATION_SIZE % size;
 
 if (rank < remainder) {
 chunkSize += 1;
 }
 
 printf("Process %d: Chunk size = %d\n", rank, chunkSize);
 srand(time(NULL) + rank); // Adjust the random seed for each process
 printf("rank : %d\n", rank);
 // Divide the population among processes
// int chunkSize = POPULATION_SIZE / size;
 Individual population[POPULATION_SIZE]; // Declare the population array
 Individual localPopulation[chunkSize];
 Individual localMatingPool[chunkSize];
 MPI_Datatype individualType;
 int blocklengths[2] = {N, 1};
 MPI_Datatype types[2] = {MPI_INT, MPI_INT};
 MPI_Aint offsets[2];
 offsets[0] = offsetof(Individual, board);
 offsets[1] = offsetof(Individual, fitness);
 MPI_Type_create_struct(2, blocklengths, offsets, types, &individualType);
 MPI_Type_commit(&individualType);
 
 if (rank == 0) {
 initializePopulation(population);
 }
 MPI_Scatter(population, chunkSize, individualType, localPopulation, chunkSize, individualType, 0, MPI_COMM_WORLD);
 
 for (int generation = 1; generation <= MAX_GENERATIONS; generation++) {
 // Perform selection, crossover, and mutation in parallel
 selection(localPopulation, localMatingPool); 
 crossover(localPopulation, localMatingPool);
 mutate(localPopulation);
 
 // Synchronize results within each process
 MPI_Gather(localPopulation, chunkSize, individualType, population, chunkSize, individualType, 0, MPI_COMM_WORLD);
 // Exchange the best individuals among processes
 Individual bestLocalIndividual;
 int bestLocalFitness = INT_MAX;
 for (int i = 0; i < chunkSize; i++) {
 if (localPopulation[i].fitness < bestLocalFitness) {
 bestLocalFitness = localPopulation[i].fitness;
 bestLocalIndividual = localPopulation[i];
 }
 }
 // Reduce the best fitness and individual across all MPI processes
 Individual bestGlobalIndividual;
 int bestGlobalFitness;
 MPI_Reduce(&bestLocalFitness, &bestGlobalFitness, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
 MPI_Gather(&bestLocalIndividual, sizeof(Individual), MPI_BYTE, &bestGlobalIndividual, sizeof(Individual), MPI_BYTE, 0, MPI_COMM_WORLD);
 // Exchange the best individuals between processes
 if (rank == 0) {
 for (int i = 0; i < size; i++) {
 if (i != rank) {
 MPI_Send(&bestGlobalIndividual, 1, individualType, i, 0, MPI_COMM_WORLD);
 }
 }
 } else {
 MPI_Recv(&bestGlobalIndividual, 1, individualType, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
 }
 // Synchronize generation number
 MPI_Bcast(&generation, 1, MPI_INT, 0, MPI_COMM_WORLD);
 // Print the current generation and fitness of the best individual
 if (rank == 0) {
 printf("Generation %d, Best Fitness: %d, Solution: ", generation, bestGlobalFitness);
 for (int j = 0; j < N; j++) {
 printf("%d ", bestGlobalIndividual.board[j]);
 }
 printf("\n");
 if (bestGlobalFitness == 0) {
 printf("Solution found in generation %d\n", generation);
 break;
 } else if (generation == MAX_GENERATIONS) {
 printf("Solution exceeds %d generations\n", MAX_GENERATIONS);
 }
 }
 
 }
 MPI_Type_free(&individualType);
 MPI_Finalize();
 return 0;
}

===================================================================

when i run this code for np > 1;

error img

segmentation fault!!

==============================================================================

can anyone pls help me with this problem !!

14
  • if you gather N elements on rank 0, the receive buffer must be large enough to contain N * size elements. The way you handle bestGlobalIndividual is clearly wrong. Commented Dec 24, 2023 at 10:37
  • thank u for the suggestion sir ..... I made some changes to the code as u told but then also the same error is coming.. Commented Dec 24, 2023 at 11:24
  • please share your latest version of the code that can be compiled. Commented Dec 24, 2023 at 11:40
  • I have shared the latest code (entire code) sir in the above code block now sir Commented Dec 24, 2023 at 11:57
  • crossover() and selection() work on POPULATION_SIZE elements, but there are only chunkSize Commented Dec 24, 2023 at 12:29

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.