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

C++ C++;:大量迭代的while循环问题(附加代码),c++,C++,首先,感谢大家在我提问之前帮助我 输入1:(CSV文件)列表数据(作为向量列表输入) 输入2:listmoves 14630x8项(CSV文件) 代码如下: #include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector> #include <cstdlib> #include <ctime>

首先,感谢大家在我提问之前帮助我

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

输入2:listmoves 14630x8项(CSV文件)

代码如下:

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

好吧,我可以
prob
,现在看来,当
prob
小于10^(-5)时,脚本将变得无响应。我不知道如何处理这个问题…

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

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

还有

double prob = rand() % RAND_MAX; //generate random numer [0,1]
没有按照评论所说的去做。如果这是你想要的,你需要

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

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

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

我要告诉你两件事:

  • probMove是一个整数,即使您将其保存在双变量中。当两个整数被除在一起时,结果总是一个整数。如果至少有一个操作数是双精度的,则结果是双精度的。通过将num或den设置为双精度来修复此问题

  • rand()%rand_MAX
    可能没有达到您的目的(您希望它看起来是一个介于0和1之间的数字)。rand()是介于0和32767之间的值,rand_MAX是32767。所以你基本上会得到rand()的值(介于0和32766之间的数字),除非rand()恰好返回32767,在这种情况下你会得到一个0


    • 我要告诉你两件事:

      • probMove是一个整数,即使您将其保存在双变量中。当两个整数被除在一起时,结果总是一个整数。如果至少有一个操作数是双精度的,则结果是双精度的。通过将num或den设置为双精度来修复此问题

      • rand()%rand_MAX
        可能没有达到您的目的(您希望它看起来是一个介于0和1之间的数字)。rand()是介于0和32767之间的值,rand_MAX是32767。所以你基本上会得到rand()的值(介于0和32766之间的数字),除非rand()恰好返回32767,在这种情况下你会得到一个0



      它在哪里进入无限循环?我假设在while循环中,但是你怎么知道?你做了什么来调试它?@falmari它肯定会进入
      中的无限循环,而
      循环。我试图在
      while
      循环中的不同位置放置不同的打印输出语句。此外,如果执行while循环,我将得到一个文件输出,如果迭代次数超过200,我就不会得到。1)奇怪的是,您使用的是
      a1
      b1
      的值,但您从未给它们赋值,它们以前是
      x1
      y1
      吗?2) 如果(probMove>=1 | | probMove>prob)
      很抱歉,我没有更正这些,但在我的程序中更正了……它在哪里进入无限循环?我假设在while循环中,但是你怎么知道?你做了什么来调试它?@falmari它肯定会进入
      中的无限循环,而
      循环。我试图在
      while
      循环中的不同位置放置不同的打印输出语句。此外,如果执行while循环,我将得到一个文件输出,如果迭代次数超过200,我就不会得到。1)奇怪的是,您使用的是
      a1
      b1
      的值,但您从未给它们赋值,它们以前是
      x1
      y1
      吗?2) 如果(probMove>=1 | | | probMove>prob)
      很抱歉,我没有更正这些,但在我的程序中更正了……这将在
      [0,1]中生成
      prob
      我将其更改为
      double prob=double(rand())/(rand_MAX+1)
      但它仍然会生成1或2个表,然后崩溃……如果
      mvec
      中充满了来自listmoves的数据,则
      e
      h
      的值为负值,但您使用它们作为索引,这可能不是您想要的。负值有特殊含义吗?例如“从列表末尾向后取”?我只取负数的绝对值,它们指向listdata中的值(向量索引和值索引)。概率是使用listdata中的值计算的,这些值是非负的。我发现我必须取
      srand((无符号int)time(NULL))
      ,但当prob太小时,脚本似乎会崩溃…我不知道如何解决这个问题…这将在
      [0,1]中生成
      prob
      我将其更改为
      double prob=double(rand())/(rand_MAX+1)
      但它仍然会生成1或2个表,然后崩溃……如果
      mvec
      中充满了来自listmoves的数据,则
      e
      h
      的值为负值,但您使用它们作为索引,这可能不是您想要的。负值有特殊含义吗?例如“从列表末尾向后取”?我只取负数的绝对值,它们指向listdata中的值(向量索引和值索引)。概率是使用listdata中的值计算的,这些值是非负的。我发现我必须取
      srand((无符号int)time(NULL))
      ,但当prob太小时,脚本似乎会崩溃…我不知道如何解决这个问题…但如果是这样,我认为我的程序只是返回到循环的开始…listmoves文件中有14630个选项。我同意,看起来他在s中使用了
      size\u type
      double prob = rand() % RAND_MAX; //generate random numer [0,1]
      
      double prob = double(rand()) / RAND_MAX;