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

Your Answer

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.