gpt4 book ai didi

c++ - 不可重复的二维 vector 问题

转载 作者:行者123 更新时间:2023-11-28 08:28:21 24 4
gpt4 key购买 nike

我正在编写一个小程序来计算物理问题,但我在从二维数组中删除元素时遇到问题。我正在使用 XCode(所以是 GDB)进行编译。

问题总是出现在 walker.erase(walker.begin()+loacationInArray) 部分(在 void diffuseWalkers 函数中),并且总是在不同次数的函数调用之后。所以有时候,“热化”循环可能会运行 50 次,而其他时候它会一直运行。我通常会遇到 EXC_BAD_ACCESS 错误,偶尔会遇到 malloc 错误。

任何帮助将不胜感激,因为我已经尝试了所有方法并且真的看不出我做错了什么。我已经在下面发布了代码。名为“heliumHeader.h”的头文件包含一些对我的问题不是很重要的数学函数。

    #include "heliumHeader.h"


void copyVectorInformation(vector<double>& walker, vector<double>& walkerTemp);
void diffuseWalker(double beta, double a, double alpha, int locationInArray, vector<double>& walker, double dt,
double& trialEnergy, int& numberOfWalkers, int targetNumberOfWalkers);
using namespace std;

int main(){


srand(time(NULL));

double s=0.; //inter-molecular distance
double beta = 0.15;
double alpha = 2.;
double dt=0.1;
int numberOfWalkers = 1; //number of particles
int targetNumberOfWalkers = numberOfWalkers;

//2D-vectors to hold information
vector<vector<double> > walker(numberOfWalkers,6);

//solve for a
double a = 1.;
for(int i=0; i<20;i++)
a = 1./(1.+exp(-s/a));

//set up sums
double localEnergy, trialEnergy, localEnergy2, trialEnergy2;
localEnergy = trialEnergy = localEnergy2 = trialEnergy2 = 0.;

//put the walkers randomly in space & get the energy of that configuration
for(int i=0; i<walker.size(); i++){
for(int j=0; j<6; j++)
walker[i][j]=randomPositiveNegative();
localEnergy += calculateEnergy(beta, alpha, a, walker[i]);
}

localEnergy /= numberOfWalkers;

double beforeEnergy = localEnergy;
cout << "local energy of random " << localEnergy << endl;
trialEnergy = -2.903;

//move the walkers
for(int thermalisationCounter = 1; thermalisationCounter<1000; thermalisationCounter++){
for(int i=0; i<walker.size(); i++)
diffuseWalker(beta, a, alpha, i, walker[i], dt, trialEnergy, numberOfWalkers, targetNumberOfWalkers);
cout << thermalisationCounter << endl;
}

//recalculate the local energy
for(int i=0; i<walker.size(); i++){
for(int j=0; j<6; j++)
localEnergy += calculateEnergy(beta, alpha, a, walker[i]);
}

localEnergy /= numberOfWalkers;

for(int numberOfSteps = 1; numberOfSteps<1000; numberOfSteps++){
for(int i=0; i<walker.size(); i++)
diffuseWalker(beta, a, alpha, i, walker[i], dt, trialEnergy, numberOfWalkers, targetNumberOfWalkers);
cout << numberOfSteps << endl;
}

//get initial energy of random positiions
for(int i=0; i<walker.size(); i++)
localEnergy += calculateEnergy(beta, alpha, a, walker[i]);

localEnergy /= numberOfWalkers;

cout << "before energy " << beforeEnergy << " local energy " << localEnergy <<
" trial energy " << trialEnergy << " number " << numberOfWalkers << endl;

return 0;
}


void copyVectorInformation(vector<double>& walker, vector<double>& walkerTemp){
for(int i=0; i<6; i++)
walkerTemp[i] = walker[i];
}//end of copyVectorInformation

void diffuseWalker(double beta, double a, double alpha, int locationInArray, vector<double>& walker, double dt,
double& trialEnergy, int& numberOfWalkers, int targetNumberOfWalkers){

vector<double> driftFunction(6);
vector<double> walkerTemp(6); //temporary store of information

//copy the walker information over
copyVectorInformation(walker, walkerTemp);

//get the drift functions
calculateDriftFunctions(beta, alpha, a, walker, driftFunction);

//get the old local energy
double preMoveLocalEnergy = calculateEnergy(beta, alpha, a, walker);

//move the walker
for(int j=0; j<6;j++)
walker[j] += 0.5*dt*driftFunction[j] + randomGauss()*sqrt(dt);

//caclulate the local energy of the new position
double postMoveLocalEnergy = calculateEnergy(beta, alpha, a, walker);

//calculate the weight, q and branching ration s
double q = exp(-dt*(0.5*(postMoveLocalEnergy + preMoveLocalEnergy) - trialEnergy));
double s = q+randomPositive();

if(int(s)<1){
//kill the walker
walker.erase(walker.begin()+locationInArray);
numberOfWalkers--;
}
else{
//reproduce walker int(s) number of times
for(int k=0; k<int(s); k++){
walker.push_back(walker[locationInArray]);
numberOfWalkers++;
}
}

//update the trial energy
trialEnergy += 0.2*log((double)targetNumberOfWalkers/(double)numberOfWalkers);

}//end of diffuse walkers

最佳答案

你有:

 if(int(s)<1){
//kill the walker
walker.erase(walker.begin()+locationInArray);
numberOfWalkers--;
}

假设

(int(s) < 1)

总是为真(总是删除)

 //move the walkers
for(int thermalisationCounter = 1; thermalisationCounter<1000; thermalisationCounter++){
for(int i=0; i<walker.size(); i++)
diffuseWalker(beta, a, alpha, i, walker[i], dt, trialEnergy, numberOfWalkers, targetNumberOfWalkers);
cout << thermalisationCounter << endl;
}

将删除所有对角线元素。是你故意的吗?也许您混合了行索引和列索引(或 1D 和 2D)?

无论如何,问题在于 locationInArray 太大,您正在删除 vector 中不再存在的项目。

关于c++ - 不可重复的二维 vector 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3174916/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com