【发布时间】:2011-06-18 09:07:18
【问题描述】:
我有一个代码,我需要创建一个键值为 double 的映射(两个集群之间的 f 检验的值。我需要为此计算残差平方和)和 cluspair 的映射值这是我创建的类 Cluster 的对。 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函数的实现:
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) );
}
}
提前非常感谢。我现在真的不知道该怎么办。
下面是我用来创建地图的代码,其中的键是两个聚类平均值之间的简单欧几里得距离。正如我上面所说,它非常相似并且使用最少的内存。它仅在 fvalue 的计算上有所不同。不是递归计算,而是计算两个簇的均值的简单距离。希望它有助于识别问题
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;
}
编辑:
顺便说一句,我已经尝试过这种替代实现,但仍然无法控制内存使用情况
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);
}
}
【问题讨论】:
-
用编程语言标记它
-
这个while循环合法吗?另外,考虑不返回地图的副本,而是接受它作为参考参数
-
Cluster::rss() 如何“减少”每次迭代的工作量?请发布先编译的内容...
-
每次迭代都减少工作量是什么意思?原始代码相当广泛,有很多步骤。我引用的函数是我用来创建
的映射的部分,正如我所提到的。 -
顺便说一句,我正在添加一个类似的函数来创建一个带有简单距离键的地图,而不是 f 检验计算。它非常相似,但在我所说的部分不同,它使用的内存非常少。希望它有助于识别问题