c++代码运行两万行数据时间非常慢,vs会中断。图的存储

我之前没有用过c++,最近在写程序需要使用c++来编写,但是在写的时候遇到这些问题。运行小图时可以得出结果,但是两万多条边的时候,时间特别慢从而导致vs中断。

我用十字链表来存贮一个时序图,时序图有一个开始时间和结束时间,我在之前根据某些条件筛选了一些顶点存在mp集合中,现在我需要按照拓扑排序从下到上遍历这个图,为每一个mp集合中的顶点构建一个可达集合。即每次将下面顶点遍历完的结果 传递给上面的顶点。我用map来存结果,之前遍历map时间很慢,所以我将key放在vector里面遍历,然后再取寻找对应的value。但是效果没有发生改变。

请各位指正!不胜感谢!

map<int,map<int,vector<PAIR>>> result;//用嵌套map来存贮结果
map<int,vector<int>> start;//用一个map来记录图中每个顶点的开始时间
void Graph::MoutSet(Graph G, vector<int> findsort){
    Sidetable *p,*q;
    map<int,map<int,vector<PAIR>>>::iterator multitr;
    map<int,vector<PAIR>>::iterator intertr;
    vector<PAIR>::iterator m;
    for(int i=0;i<topo.size();i++){//按照从下到上的顺序遍历寻找mout
        vector<int>::iterator it;
        it = find(mp.begin(), mp.end(), findsort[i]);
        if(it!=mp.end()){//如果为mp点
            map<int,vector<PAIR>> temp1;//用来存储该顶点的开始时间:(到达顶点,结束时间)
            //map<int,vector<PAIR>> tem;
            vector<int> sta;//存储开始时间
            vector<PAIR> d;
            //d.reserve(1000);
            p=G._adj[findsort[i]].firstout;//用十字链表结构来存图
            while(p!=NULL){//遍历mp点的所有后继节点
                sta.emplace_back(p->weight);    //把所有开始时间存入vector
                it = find(mp.begin(), mp.end(), p->to);
                if(it == mp.end()){//后继节点不为mp
                    q=G._adj[p->to].firstout;
                    while(q!=NULL){//遍历后继节点的后继节点
                        for(int i:start[q->to]){//从start开始集合找到满足条件的开始时间,然后在将map中开始时间对应的集合给到当前顶点
                            if(i>=q->weight+1 && (result[q->to][i].size()!=0)){
                                d.insert(d.end(),result[q->to][i].begin(),result[q->to][i].end());
                            }
                        }
                        /*if((p->weight+1)<=q->weight){
                            d.emplace_back(make_pair(q->to,q->weight+1));
                            for(intertr=result[q->to].begin(); intertr!= result[q->to].end(); intertr++){
                                if(intertr->first>=q->weight+1){
                                    if(intertr->second.size()==0){
                                        continue;
                                    }
                                    d.insert(d.end(),intertr->second.begin(),intertr->second.end());
                                }
                            }
                        }*/
                        q=q->taillink;
                    }
                    if(d.size()!=0){
                        temp1.insert(make_pair(p->weight,d));
                    }    
                }
                else{//如果后继节点为mp
                    d.emplace_back(make_pair(p->to,p->weight+1));
                    for(int i:start[p->to]){
                        if(i>=p->weight+1 && (result[p->to][i].size()!=0)){
                            d.insert(d.end(),result[p->to][i].begin(),result[p->to][i].end());
                        }
                    }
                    //for(intertr=result[p->to].begin(); intertr!= result[p->to].end(); intertr++){
                    //    //for(int i=0;i<intertr->second.size();i++){
                    //        if(p->weight+1<=intertr->first){
                    //            if(intertr->second.size()==0){
                    //                continue;
                    //            }
                    //            d.insert(d.end(),intertr->second.begin(),intertr->second.end());
                    //        }
                    //    //}
                    //} 
                    if(d.size()!=0){
                        temp1.insert(make_pair(p->weight,d));
                    }
                }
            
                //temp1.emplace(pair<int,vector<PAIR>>(p->weight,d));
                
                p=p->taillink;
                d.clear();
                
            }
            start.emplace(pair<int,vector<int>>(findsort[i],sta));//存储顶点的所有开始时间格式为顶点:{开始时间1,开始时间2.。。。}
            result.emplace(pair<int,map<int,vector<PAIR>>>(findsort[i],temp1));
 //Mout形式为:
 //       顶点1:{开始时间1:[(到达顶点1,结束时间),(到达顶点2,结束时间)],
 //             开始时间2:[(到达顶点1,结束时间),(到达顶点2,结束时间)]}
 //          顶点2:。。。。
 //        顶点3:。。。                                                                                        
        }
    }
}

传递参数最好能用引用,而不是值,用值类型将发生复制。数据量大会引起性能大幅下降

c++里面的模版虽然很便捷,但是也会延长程序运行时间。

代码里你查找用的vector,容器换其他查找效率高的

无profiler不要谈效率!!尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代!

img

别听他们胡说,容器函数这些都要学习,当你使用QT以后,你才知道有多重要

DAG的可达性统计只需要把节点编好号用 bitset 就可以了吧,这样时间复杂度大概是 O((n+m)*n/64),点和边在两万以内的数据可以一秒轻松跑出来。
用 map 或者 vector 的时间复杂度至少是 O(n^2),用 vector 仅仅是常数优一些,两万跑起来都很呛。

建议好好学算法,复杂度级别的优化远比常数优化有效。