内存在递归树算法中的使用

时间:2011-06-19 13:25:49

标签: c++ memory recursion tree

我有一个代码,我需要创建一个键值为double的映射(两个簇之间的f-test值。我需要计算剩余的平方和)以及cluspair的映射值这是我创建的一类Cluster。 Map旨在将F测试值存储在所有集群之间,这样我就不需要在每个步骤中反复进行计算。 BTW集群是一种树结构,其中每个集群包含两个子集群,存储的值是70维向量。

问题是,为了计算RSS,我需要实现一个递归代码,我需要找到集群中每个元素与集群平均值的距离,这似乎消耗了大量的内存。当我创建相同的映射,其中键值是两个集群均值之间的简单距离时,程序使用最少的内存,所以我认为内存使用的增加是由递归函数RSS的调用引起的。我该怎么做才能管理下面代码中的内存使用?在其当前实现中,系统内存不足,窗口关闭应用程序,说系统耗尽了虚拟内存。

主要代码:

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

群集构建器

Cluster::Cluster (Cluster *C1, Cluster *C2)
{
    ec1=C1;
    ec2=C2;
    node* cn = new node;
    cn->numOfVecs = C1->cnode->numOfVecs + C2->cnode->numOfVecs;

    double nov = cn->numOfVecs;
    double div = (1 / nov);

    cn->mean = scalarMultVect(div,vectAdd(scalarMultVect(C1->cnode->numOfVecs,C1->cnode->mean),scalarMultVect(C2->cnode->numOfVecs,C2->cnode->mean)));

    mvect tmv;
    tmv.stock="";
    cn->v1 = tmv;

    cnode = cn;
}

1 个答案:

答案 0 :(得分:1)

之前你问过完全相同的问题:  Enormous Increase In the Use Of Memory

  1. rtrnmap =(rtrnmap.find(cFvalue)!= rtrnmap.end());没有意义。
  2. 您被告知通过参考传递数据
  3. 您被告知要添加日志记录信息并查看执行的迭代次数。
  4. 一些评论:

    • 使用map作为关键字double是一个坏主意,因为double的细微差别可能导致您无法检索元素。
    • 只在集合中添加一些元素,并手动浏览调试器中的所有函数。您将“看到”执行的内容并立即查看实际执行流程是否符合您的期望

    请不要双重发布您的问题(即使您使用不同的用户)。

    编辑:

    我们都假设了一个合适的析构函数。确保根据需要使用newnew[]取消分配您使用deletedelete[]明确分配的内存。