首先,谢谢大家以前帮我解决过我的问题。
输入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)时,脚本就会无法响应。我不知道如何处理这个......
答案 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;