我有一個代碼,我需要創建一個關鍵值爲double的映射(兩個集羣之間的f-測試值,我需要計算這個殘差平方和)以及作爲我創建的類Cluster的對的cluspair的映射值。 Map旨在存儲所有簇之間的F檢驗值,這樣我就不需要在每一步中一次又一次地進行計算。 BTW羣集是一個樹形結構,每個羣集包含兩個子羣集,存儲的值爲70維向量。在內存使用方面的巨大增加
問題是,爲了計算RSS,我需要實現一個遞歸代碼,我需要找到簇的每個元素與簇的平均值的距離,這似乎正在消耗大量的記憶。當我創建相同的映射關鍵值是兩個簇之間的簡單距離時,程序使用最小內存,所以我認爲內存使用的增加是由遞歸函數RSS的調用引起的。我應該如何管理下面代碼中的內存使用?在當前的實現中,系統內存不足,windows關閉應用程序,說系統耗盡了虛擬內存。
的主要代碼:
map<double,cluspair> createRSSMap(list<Cluster*> cluslist)
{
list<Cluster*>::iterator it1;
list<Cluster*>::iterator it2;
map<double,cluspair> rtrnmap;
for(it1=cluslist.begin(); it1!= --cluslist.end() ;it1++)
{
it2=it1;
++it2;
cout << ".";
list<Cluster*>::iterator itc;
double cFvalue=10000000000000000000;
double rIt1 = (*it1)->rss();
for(int kk=0 ; it2!=cluslist.end(); it2++)
{
Cluster tclustr ((*it1) , (*it2));
double r1 = tclustr.rss();
double r2= rIt1 + (*it2)->rss();
int df2 = tclustr.getNumOfVecs() - 2;
double fvalue = (r1 - r2)/(r2/df2);
if(fvalue<cFvalue)
{
cFvalue=fvalue;
itc=it2;
}
}
cluspair clp;
clp.c1 = *it1;
clp.c2 = *itc;
bool doesexists = (rtrnmap.find(cFvalue) != rtrnmap.end());
while(rtrnmap)
{
cFvalue+= 0.000000001;
rtrnmap= (rtrnmap.find(cFvalue) != rtrnmap.end());
}
rtrnmap[cFvalue] = clp;
}
return rtrnmap;
}
和功能RSS的imlementation:
double Cluster::rss()
{
return rss(cnode->mean);
}
double Cluster::rss(vector<double> &cmean)
{
if(cnode->numOfVecs==1)
{
return vectorDist(cmean,cnode->mean);
}
else
{
return (ec1->rss(cmean) + ec2->rss(cmean));
}
}
提前很多感謝。我現在真的不知道該怎麼做。下面
是與我用於創建具有鍵爲兩個羣集裝置之間簡單歐幾里得距離的映射的代碼。正如我上面所說的那樣,它非常相似並且使用最少的內存。它僅在f值的計算中有所不同。除了遞歸計算之外,還有計算兩個聚類平均值的簡單距離。希望它可以幫助找出問題
map<double,cluspair> createDistMap(list<Cluster*> cluslist)
{
list<Cluster*>::iterator it1;
list<Cluster*>::iterator it2;
map<double,cluspair> rtrnmap;
for(it1=cluslist.begin(); it1!= --cluslist.end() ;it1++)
{
it2=it1;
++it2;
cout << ".";
list<Cluster*>::iterator itc;
double cDist=1000000000000000;
for(int kk=0 ; it2!=cluslist.end(); it2++)
{
double nDist = vectorDist((*it1)->getMean(),(*it2)->getMean());
if (nDist<cDist)
{
cDist = nDist;
itc=it2;
}
}
cluspair clp;
clp.c1 = *it1;
clp.c2 = *itc;
bool doesexists = (rtrnmap.find(cDist) != rtrnmap.end());
while(doesexists)
{
cDist+= 0.000000001;
doesexists = (rtrnmap.find(cDist) != rtrnmap.end());
}
rtrnmap[cDist] = clp;
}
return rtrnmap;
}
實施vectorDist()的
double vectorDist(vector<double> vec1, vector<double> vec2)
{
double sqrsum=0;
double tempd=0;
int vs = vec1.size();
for (int i=0;i<vs;i++)
{
tempd = vec1[i] - vec2[i];
sqrsum += tempd*tempd;
}
return sqrsum;
}
編輯:
BTW我已經試過這種替代的實施仍無法得到控制內存使用情況
double Cluster::rss()
{
list<double> fvals;
rss(cnode->mean , fvals);
double sum=0;
list<double>::iterator tpit;
for(tpit=fvals.begin() ; tpit != fvals.end() ; ++tpit)
{
sum += *tpit;
}
return sum;
}
void Cluster::rss(vector<double> &cmean , list<double> &fvals)
{
if(cnode->numOfVecs==1)
{
fvals.push_back(vectorDist(cmean,cnode->mean));
}
else
{
ec1->rss(cmean , fvals);
ec2->rss(cmean , fvals);
}
}
用編程語言標記 – emaillenin
那是while循環合法嗎?此外,請考慮不返回地圖<>的副本,而是將其作爲參考參數 – Andrei
並且Cluster :: rss()如何在每次迭代時減少它的工作負荷?請發佈首先編譯的內容... – Andrei