C ++:大量迭代的while循环问题(附加代码)

时间:2011-02-22 03:37:29

标签: c++

首先,谢谢大家以前帮我解决过我的问题。

输入1:(CSV文件)listdata(作为向量列表输入)

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

输入2:listmoves 14630x8条目(CSV文件)。

{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 }

以下是代码:

#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;
}

程序运行并产生理想的输出。但是,当我将while循环中的迭代次数更改为大约1000,然后在命令行中运行程序时,它似乎停留在循环中(不产生任何输出然后终端(在mac上) )变得反应迟钝)。我甚至害怕把它设置为30,000,这就是我的模拟所需要的。

我是C ++的新手,我不知道如何解决这个问题。

请帮忙!

更新:我更改了以下行:

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

好吧,我是prob,现在看来当prob小于10 ^( - 5)时,脚本就会无法响应。我不知道如何处理这个......

3 个答案:

答案 0 :(得分:2)

您可能会遇到probMove为零,非常接近零或甚至为负的情况,在这种情况下,j++将永远不会执行以增加循环。

答案 1 :(得分:2)

我会告诉你两件事:

  • probMove是一个整数,即使您将其保存在双变量中也是如此。当两个整数分开时,结果始终是整数。当至少有一个操作数是double时,结果是double。通过将num或den设为double来解决此问题。

  • rand()%RAND_MAX可能没有按你的意愿行事(你希望它看起来像是0到1之间的数字)。 rand()是一个介于0和32767之间的值,RAND_MAX是32767.所以你基本上会得到rand()的值(数字介于0和32766之间),除非rand()碰巧返回32767,在这种情况下你会得到一个0。

答案 2 :(得分:1)

此外,

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

没有做评论所说的。如果这是你想要的,你需要

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