Knapsack with GA

3

Good morning, I am working on this quite simple algorithm that tries to solve the problem of knapsack with a genetic algorithm. I have based on what I have learned from the internet and the algorithm compiles and works, but it always gives me 0 and I really do not understand why ... Could someone help me out? Thanks

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>
#include <time.h>

using namespace std;

vector<double> weight;
vector<string> population;
vector<double> fitness;
bool run = false;


vector<double> make_prob(int n) {

    weight.resize(n);
    for (int i = 0; i<n; i++) {
        weight[i] = rand() * 50;
    }

    return weight;
}


string makeGene(int n) {

    string g = "";


    for (int i = 0;i<n;i++) {
        g = g + to_string(rand() % 2);
    }
    return g;

}



vector<string> makepop(int p, int n) {
    population.resize(p);
    for (int i = 0; i<p; i++) {
        population[i] = makeGene(n);
    }

    return population;
}

double evaluation(string g, vector<double> w, double max, int n) {
    double tw = 0;

    for (int i = 0;i<n; i++) {
        if (g[i] == '1')
            tw = tw + w[i];

    }
    double e = 0;
    double d = max - tw;
    if (d >= 0)
        e = tw / max * 100;

    return e;


}

vector<double> evalPop(vector<string> pop, vector<double> w, double max, int p, int n) {

    vector<double> fit(n);

    for (int i = 0; i<p; i++) {
        fit[i] = evaluation(pop[i], w, max, n);
    }
    return fit;
}

int select(vector<double> fitness) {
    double totalFit = 0, r = 0, sum = 0;
    int i = 0;
    for (int j = 0; j<fitness.size();j++) {
        totalFit += fitness[j];
    }

    r = rand() * totalFit;

    do {
        sum += fitness[i];
        i++;
    } while (sum<r);

    return --i;
}

string cross(string n1, string n2, int n) {

    int c = rand() % n;
    return n1.substr(0, c) + n2.substr(c,(n2.size()-c)-1);

}

void breed(vector<string> population, vector<double> fitness, int p, int n) {

    vector<string> breedPop(p);

    for (int i = 0;i<p;i++) {
        int j = select(fitness);
        breedPop[i] = population[j];
    }

    for (int i = 0;i<p-1;i++) {
        population[i] = cross(breedPop[i], breedPop[i + 1], n);
    }

    population[p - 1] = cross(breedPop[0], breedPop[p - 1], n);

}

void printPopStats(int gen, vector<double> fitness) {

    double max = 0, totalFit = 0;

    for (int i = 0; i<fitness.size();i++) {
        if (max<fitness[i])max = fitness[i];
        totalFit += fitness[i];
    }
    cout << "Generation: " << gen << endl;
    cout << "Max fit: " << max << " Total Fitness: " << totalFit << endl;
}


int main() {

    srand(time(NULL));

    double max = 250.00 + rand()%50 * 500;
    int n = rand();
    weight = make_prob(n);
    int p = 20;
    population = makepop(p, n);
    int gen = 1;
    run = true;
    do {
        fitness = evalPop(population, weight, max, p, n);
        printPopStats(gen, fitness);
        gen++;
        breed(population, fitness, p, n);
        system("pause");

    } while (run);
    return 0;
}
    
asked by Lolo 01.03.2016 в 20:36
source

1 answer

2

I could not look at ideone.com because I did not compile, but in this function:

double evaluation(string g, vector<double> w, double max, int n) {
    double tw = 0;

    for (int i = 0;i<n; i++) {
        if (g[i] == '1')
            tw = tw + w[i];

    }
    double e = 0;
    double d = max - tw;
    if (d >= 0)
        e = tw / max * 100;

    return e;
}

if this is positive double d = max - tw; e = tw / max * 100; is applied where e tends to 0 .

if this is negative double d = max - tw; , e is 0 .

You can iterate over fitness[i] and see its contents, then if (max<fitness[i]) if max here is 0 applied to fitness [i] then, max is 0

If you change to double d = max + tw; it may not show you the 0 but I do not know if that is the behavior you expect.

P.D: You may have to check that the accesses to the addresses of an array are within the range, for example here vector<double> fit(n);

    
answered by 02.03.2016 / 02:00
source