开发者

C++: problem with while loop for large number of iterations (code is attached)

First of all, thank you all for helping me with my questions before.

Input 1: (CSV file) listdata (input as list of vectors)

0,44,38,42,29,26,29,18,39,29,25,18,15,18,34,31,22,12,14,22,9,27
0,0,43,37,32,30,24,25,29,16,24,30,29,9,26,8,24,8,7,12,13,15
0,0,0,21,31,32,24,21,26,23,25,23,21,18,18,19,21,11,17,11,12,10
0,0,0,0,23,27,28,24,26,20,13,19,23,22,20,16,18,11,6,12,10,7
0,0,0,0,0,17,31,26,25,24,30,25,25,15,19,8,19,13,7,16,7,4
0,0,0,0,0,0,18,22,21,31,13,30,18,15,19,14,15,13,10,9,8,7
0,0,0,0,0,0,0,20,20,17,28,25,13,18,8,18,23,11,9,19,6,7
0,0,0,0,0,0,0,0,13,12,24,11,25,15,16,12,16,17,4,9,7,8
0,0,0,0,0,0,0,0,0,21,25,7,23,23,27,20,15,22,8,9,7,10
0,0,0,0,0,0,0,0,0,0,18,21,14,14,10,19,14,9,5,11,7,3
0,0,0,0,0,0,0,0,0,0,0,25,5,15,16,19,15,8,10,12,3,11
0,0,0,0,0,0,0,0,0,0,0,0,9,16,9,12,16,8,13,10,5,5
0,0,0,0,0,0,0,0,0,0,0,0,0,29,10,10,7,16,5,6,7,9
0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,13,6,10,2,6,13,11
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,13,9,7,11,7,9
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,15,12,20,8,13
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,4,11,5,10
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,11,9,3
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,8
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,10
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

input 2 : listmoves 14630x8 entries (CSV file).

{here is couple of lines from the file:
 1,2,3,4,-1,-3,-2,-4
 1,2,3,5,-1,-3,-2,-5
 1,2,3,6,-1,-3,-2,-6
 1,2,3,7,-1,-3,-2,-7
 1,2,3,8,-1,-3,-2,-8
 1,2,3,9,-1,-3,-2,-9
 1,2,3,10,-1,-3,-2,-10
 1,2,3,11,-1,-3,-2,-11 }

Here is the code:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>

using namespace std;

/*reading data files into vectors (22x22 matrix is in CSV format and 14630x8 vectors of moves in CSV format)*/
void readListData(vector< vector<short> > &vvec, const char *filename) {

    ifstream dataFile;

    dataFile.open(filename);
    if(!dataFile.good()) {
        cerr << "Could not open file '" << filename << "' for read\n";
        exit(EXIT_FAILURE);
    }
    string line;

    while (getline(dataFile, line)) {

        istringstream iss(line);
        vector<short> lvec;
        while (!iss.eof()) {
            short num;
            iss >> num;
            lvec.push_back(num);
            char ch;
            iss >> ch;
        }
        vvec.push_back(lvec);
    }
}

/* write modified list of vectors into file at the end */
void writeListData(vector< vector <short> > &vvec, std::string filename) {
    ofstream dataOutFile;

    dataOutFile.open(filename.c_str());
    if(!dataOutFile.good()) {
        cerr << "Could not open file 'listdata.out' for write\n";
        exit(EXIT_FAILURE);
    }
    for (vector<vector <short> >::size_type i = 0; i < vvec.size(); i++) {
        vector<short>::size_type j;
        for (j = 0; j < vvec[i].size() - 1; j++) {
            dataOutFile << vvec[i][j] << ",";
        }
        dataOutFile << vvec[i][j] << endl;
    }
    dataOutFile.flush();
}

/* creat a toy vector for the input */
void copyVectors(const vector<vector<short> >& source, vector<vector<short> >& dest){
    for(unsigned int i=0; i< source.size(); i++){
        vector<short> rowSrc = source[i];
        vector<short> rowDest;
        for(unsigned int j=0; j< rowSrc.size(); j++){
            rowDest.push_back(rowSrc[j]);
            }

        dest.push_back(rowDest);
        }   
} 



int main() {

    vector<vector <short> > mvec; //moves vectors
    vector<vector <short> > vvecOrig; // original data vectors

    readListData(vvecOrig, "listdata");
    readListData(mvec, "listmoves");
    const int NITERATIONS = 25; //set number of iterations
    int numTables=25; //set number of outputs 

    vector<vector <short> > vvec;
    copyVectors(vvecOrig, vvec);

    for (int i=0; i<numTables; i++) {

        srand((int) time(NULL)); 

       int j = 0;
       while (j < NITERATIONS) {

        int movesIndex = rand() % mvec.size(); //generate random # from 0 to 14630 


        short a = mvec[movesIndex][0]; 
        short b = mvec[movesIndex][1];
        short c = mvec[movesIndex][2];
        short d = mvec[movesIndex][3];
        short e = abs(mvec[movesIndex][4]);
        short f = abs(mvec[movesIndex][5]);
        short g = abs(mvec[movesIndex][6]);
        short h = abs(mvec[movesIndex][7]);



        int x=vvec[e - 1][f - 1]-1;
        int y=vvec[g - 1][h - 1]-1;
        int z=vvec[a - 1][b - 1]+1;
        int w=vvec[c - 1][d - 1]+1;
        int x1=vvec[e - 1][f - 1];
        int y1=vvec[g - 1][h - 1];
        int z1=vvec[a - 1][b - 1];
        int w1=vvec[c - 1][d - 1];

            /*check for probability of the move */
           /*if move does not create negative number in the list of vectors*/
        if ((x>=0 && y>=0)) {


            if  (x==0 ){
                 x=1;
            }
            if(y==0){
                y=1;
            }
            if (z==0){
                z=1;
            }
            if (w==0){
                w=1;
            }
            if (x1==0){
                x1=1;
            }
            if (y1==0){
                y1=1;
            }
            if (z1==0){
                z1=1;
            }
            if (w1==0){
                w1=1;
            }
        int numerator=x*y;  
        int denominator=z1*w1;


        double probMove=numerator/denominator; //conditional probability
        double prob = rand() % RAND_MAX; //generate random numer [0,1]  

        if ( probMove >=1 || probMove>prob) {
        /*make a move if conditions are satisfied */

                vvec[a - 1][b - 1]++;
                vvec[c - 1][d - 1]++;
                vvec[e - 1][f - 1]--;
                vvec[g - 1][h - 1]--;
            j++;

            }
        }
        }
    /*write output file after iterations*/
    std::stringstream filenamestr;
    filenamestr<<"listdata."<<i<<".out"; 
    writeListData(vvec, filenamestr.str());

     }
    return 0;
}

The programs runs and produces desirable output. However, when I change number of iteration in while loop to about 1000, and then run the program in the command line, it seems to be stuck in the loop ( doesn't produce any output and then terminal (on mac) becomes unresponsive). I am even scared to set it to 30,000 which is what my simulation required.

I am very new to C++ and I am not sure how to troubleshoot this.

Please help!

UPDATE: I changed the following lines:

srand((unsigned int) time(NULL));
...
double probMove=double(numerator)/denominator; 
double prob = double(rand() )/ (RAND_MAX); 

well, I cout prob, and it seems now that when prob is less than 10^(-5) the script becomes unresponsive. I have no idea how to approach开发者_运维百科 this...


I'll tell you 2 things:

  • probMove is an integer, even though you are saving it in a double variable. When two integers are divided together, the result is always an integer. When at least one of the operands is a double then the result is a double. Fix this by making either num or den a double.

  • rand()%RAND_MAX is probably not doing what you intend (you want it to be a number between 0 and 1 it seems). rand() is a value between 0 and 32767, and RAND_MAX is 32767. So you're basically going to get the value of rand() back (number between 0 and 32766) unless rand() happened to return 32767, in which case you'll get a 0.


You are probably hitting a case where probMove is either zero, very close to zero, or even negative, in which case j++ will never execute to increment your loop.


Also,

double prob = rand() % RAND_MAX; //generate random numer [0,1]

doesn't do what the comment says. If that's what you want, you need

double prob = double(rand()) / RAND_MAX;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜