什么是C ++中的RND /种子?

时间:2012-05-21 23:35:04

标签: c++

我正在尝试使用一些代码..保持编译错误RND not declared in scope我找到了一部分代码,如果它在linux上运行并且在Windows上定义它而忽略了Mac用户(没什么大不了的,我也会忽略它们!)。我删除了那部分代码,并使用linux设置定义它(因为我认为我的Mac比Linux更接近Linux),但后来我得到了相同的错误,但是对于种子。奇怪的是那些种子错误在RND错误处于同一位置。所以我的问题是什么是RND /种子?我的搜索发现它们特定于VB但不确定它是否有用,因为我使用的是C ++。

这是一个令人反感的攻击性代码(建议观众自行决定):

mi = (int)(round(RND*(dimc-1)));

任何提示/建议都会很棒。我刚刚开始学习c ++,所以我可能会错过很简单的东西。

这是整个代码(从这里偷走http://cg.iit.bme.hu/~zsolnai/gfx/genetic/):

// a fast genetic algorithm for the 0-1 knapsack problem
// by karoly zsolnai - keeroy@cs.bme.hu
// test case: 1000 items, 50 knapsack size
//
// compilation by: g++ genetic.cpp -O3 -ffast-math -fopenmp
#include <math.h>
#include <time.h>
#include <algorithm>
#include <vector>
#include <fstream>
#include <limits.h>


#define RND ((double)rand_r(&seed)/RAND_MAX) // reentrant uniform rnd



using namespace std;

struct chromo {
    chromo(int dimc) { items = new bool[dimc]; }
    ~chromo() { items = NULL; }
    void mutate(const int dimc, const int count) {
        int mi;
        for(int i=0;i<count;i++) {
            mi = (int)(round(RND*(dimc-1)));
            items[mi] = !items[mi];
        }
    }
    bool* items;
    int f;
};

int fitness(bool*& x, const int dimc, const vector<int>& v, const vector<int>& w, const int limit) {
    int fit = 0, wsum = 0;
    for(int i=0;i<dimc;i++) {
        wsum += x[i]*w[i];
        fit += x[i]*v[i];
    }
    if(wsum>limit) fit -= 7*(wsum-limit); // penalty for invalid solutions
    return fit;
}

void crossover1p(const chromo& c1, const chromo& c2, const chromo& c3, const int dimc, const int cp) {
    for(int i=0;i<dimc;i++) {
        if(i<cp) { c3.items[i] = c1.items[i]; }
        else { c3.items[i] = c2.items[i]; }
    }
}

void crossover1p_b(const chromo &c1, const chromo &c2, const chromo &c3, int dimc, int cp) {
    for(int i=0;i<dimc;i++) {
        if(i>=cp) { c3.items[i] = c1.items[i]; }
        else { c3.items[i] = c2.items[i]; }
    }
}

void crossoverrand(const chromo &c1, const chromo &c2, const chromo &c3, const int dimc) {
    for(int i=0;i<dimc;i++) {
        if(round(RND)) { c3.items[i] = c1.items[i]; }
        else { c3.items[i] = c2.items[i]; }
    }
}

void crossoverarit(const chromo &c1, const chromo &c2, const chromo &c3, int dimc) {
    for(int i=0;i<dimc;i++) {
        c3.items[i] = (c1.items[i]^c2.items[i]);
    }
}

bool cfit(const chromo &c1,const chromo &c2) { return c1.f > c2.f; }
bool cmpfun(const std::pair<int,double> &r1, const std::pair<int,double> &r2) { return r1.second > r2.second; }

int coin(const double crp) { // a cointoss
    if(RND<crp) return 1; // crossover
    else return 0; // mutation
}

// initializes the chromosomes with the results of a greedy algorithm
void initpopg(bool**& c, const std::vector<int> &w, const std::vector<int> &v, const int dimw, const int limit, const int pop) {
    std::vector<std::pair<int,double> > rvals(dimw);
    std::vector<int> index(dimw,0);
    for(int i=0;i<dimw;i++) {
        rvals.push_back(std::pair<int,double>(std::make_pair(i,(double)v[i]/(double)w[i])));
    }
    std::sort(rvals.begin(),rvals.end(),cmpfun);
    int currentw = 0, k;
    for(int i=0;i<dimw;i++) {
        k = rvals[i].first;
        if(currentw + w[k] <= limit) { // greedy fill
            currentw += w[k];
            index[k] = 1;
        }
    }
    for(int i=0;i<pop;i++) {
        for(int j=0;j<dimw;j++) {
            c[i][j] = index[j];
        }
    }
}

int main() {
    printf("\n");
    srand(time(NULL));
    vector<int> w, v; // items weights and values
    int info=0;
    FILE *f = fopen("1000_weights.txt","r");
    FILE *f2 = fopen("1000_values.txt","r");
    while(!feof(f) || !feof(f2) ) {
        fscanf(f," %d ",&info);
        w.push_back(info);
        info=0;
        fscanf(f2," %d ",&info);
        v.push_back(info);
    } // omitted fclose(f1) and fclose(f2) on purpose
    const int limit = 50; // knapsack weight limit
    const int pop = 250; // chromosome population size
    const int gens = INT_MAX; // maximum number of generations
    const int disc = (int)(ceil(pop*0.8)); // chromosomes discarded via elitism
    const int dimw = w.size();
    int best = 0, ind = 0, ind2 = 0; // a few helpers for the main()
    int parc = 0; // parent index for crossover
    double avg = 0, crp = 0.35; // crossover probability
    vector<chromo> ch(pop,chromo(dimw));
    bool **c = new bool*[pop];
    for(int i=0;i<pop;i++) c[i] = new bool[dimw];
    clock_t start = clock();
    printf("Initializing population with a greedy algorithm...");
    initpopg(c,w,v,dimw,limit,pop);
    printf("done!");
    for(int i=0;i<pop;i++) {
        ch[i].items = c[i];
        ch[i].f = fitness(ch[i].items, dimw ,v, w, limit);
    }
    printf("\n\n");

    for(int p=0;p<gens;p++) {
        std::sort(ch.begin(), ch.end(), cfit);
        #pragma omp parallel for shared(ch)
        for(int i=0;i<pop;i++) {
            if(i>pop-disc) { // elitism - only processes the discarded chromosomes
                if(coin(crp)==1) { // crossover section
                    ind = parc+round(10*RND); // choosing parents for crossover
                    ind2 = parc+1+round(10*RND);
                    // choose a crossover strategy here
                    crossover1p(ch[ind%pop],ch[ind2%pop],ch[i],dimw,round(RND*(dimw-1)));
//                  crossoverrand(ch[ind],ch[ind2],ch[i],dimw);
//                  crossoverarit(ch[0],ch[1],ch[i],dimw);
                    ch[i].f = fitness(ch[i].items, dimw ,v, w, limit);
                    parc += 1;
                }
                else { // mutation section
                    ch[i].mutate(dimw,1);
                    ch[i].f = fitness(ch[i].items, dimw ,v, w, limit);
                }
            }
            avg += ch[i].f;
            if(ch[i].f>best) best=ch[i].f;
        }
        parc = 0;
        if(p%5==0) {
            printf("\n#%d\t",p);
            printf("best fitness: %d \t",best);
            printf("avg fitness: %f",avg/pop);
            if(best == 675) goto end; // psst...don't tell anyone
        }
        best = avg = 0;
    }

end:
    printf("\n\n");
    clock_t end = clock();
    double t = (double)(end-start)/CLOCKS_PER_SEC;
    printf("\nCompletion time: %fs.\n",t);
    return 0;
}

1 个答案:

答案 0 :(得分:3)

问题是你已经不熟练地分割了你所拥有的代码:

#if defined(__linux) || defined(__linux__)
        unsigned int seed = time(NULL);
        #define RND ((double)rand_r(&seed)/RAND_MAX) // reentrant uniform rnd
#endif

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
        #define RND ((double)rand()/RAND_MAX) // uniform rnd
#endif

根据Linux系统的当前时间定义 seed变量;也许Windows系统不需要种子?

无论如何,如果您在if defined (__linux) ...分支中包含两行行,而不是只有一行,那么它应该可以在您的OS X系统上正常运行。