所以在这里我试图创建一个Graph数据结构,其中我必须根据它们的id来跟踪边缘。所以我在字符串数据结构中创建边缘ID为eid:sourceid_destinationid
using namespace std;
class Edge{
public:
bool operator==(const Edge* &obj) const
{
return eid==obj->eid;
}
std::string eid;
set<int> rrids;
int sourceid;
int destid;
int strength;
public:
Edge(std::string eid,int from,int to);
std::string getId();
void addRRid(int rrid);
void removeRRid(int rrid);
void setRRid(set<int> rrids);
void setId(std::string eid);
};
这是我用来添加和删除边缘的另一个类。 HPP-文件
使用namespace std;
class RRassociatedGraph{
public:
unordered_map<int,vertex*> vertexMap;
std::unordered_map<std::string,Edge*> EdgeMap;
int noOfEdges;
public:
RRassociatedGraph();
unordered_set<vertex> getVertices();
int getNumberOfVertices();
void addVertex(vertex v);
vertex* find(int id);
Edge* findedge(std::string id);
void addEdge(int from, int to, int label);
void removeEdge(int from, int to,int rrSetID);
};
当我调试代码时,我发现在函数中添加边缘这里我正在做的地方EdgeMap.insert执行不会转到下一行。它保留在哈希表中,用于某些桶条目的循环。我无法经常调试此代码,因为我必须等待3个小时才能解决此问题。代码与小图完美配合。但对于较大的图形,edgeMap必须存储800k边缘。它进入这个哈希表无限循环。我没有得到这个哈希表代码。但是我创建Edgemap的数据结构有问题吗?
#include "RRassociatedGraph.hpp"
RRassociatedGraph::RRassociatedGraph() {
noOfEdges=0;
}
void RRassociatedGraph::addVertex(vertex v) {
vertexMap.insert(pair<int,vertex*>(v.getId(), &v));
}
vertex* RRassociatedGraph::find(int id) {
unordered_map<int,vertex*>::const_iterator got=vertexMap.find(id);
if(got != vertexMap.end() )
return got->second;
return nullptr;
}
Edge* RRassociatedGraph::findedge(std::string id){
unordered_map<std::string,Edge*>::const_iterator got=EdgeMap.find(id);
if(got != EdgeMap.end() )
return got->second;
return nullptr;
}
void RRassociatedGraph::addEdge(int from, int to, int label) {
vertex* fromVertex = find(from);
if (fromVertex == nullptr) {
fromVertex = new vertex(from);
vertexMap.insert(pair<int,vertex*>(fromVertex->getId(), fromVertex));
}
vertex* toVertex = find(to);
if (toVertex == nullptr) {
toVertex = new vertex(to);
vertexMap.insert(pair<int,vertex*>(toVertex->getId(), toVertex));
}
if(fromVertex==toVertex){
// fromVertex->outDegree++;
//cout<<fromVertex->getId()<<" "<<toVertex->getId()<<"\n";
return;
}
std::string eid=std::to_string(from);
eid+="_"+std::to_string(to);
Edge* edge=findedge(eid);
if(edge==nullptr){
edge=new Edge(eid,from,to);
edge->addRRid(label);
fromVertex->addOutGoingEdges(edge);
EdgeMap.insert(pair<std::string,Edge*>(edge->getId(), edge));
noOfEdges++;
}
else{
edge->addRRid(label);
fromVertex->outDegree++;
}
}
void RRassociatedGraph::removeEdge(int from, int to,int rrSetID) {
vertex* fromVertex = find(from);
std::string eid=std::to_string(from);
eid+="_"+std::to_string(to);
if(EdgeMap.count(eid)==1){
Edge* e=EdgeMap.find(eid)->second;
if(fromVertex->removeOutgoingEdge(e,rrSetID)){
EdgeMap.erase(eid);
delete e;
}
}
}
这是继续进入for循环的地方。地图的插入时间应该非常少,但这会在我的代码中造成瓶颈。
template <class _Tp, class _Hash, class _Equal, class _Alloc>
void
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __nbc)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__invalidate_all(this);
#endif // _LIBCPP_DEBUG_LEVEL >= 2
__pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc();
__bucket_list_.reset(__nbc > 0 ?
__pointer_alloc_traits::allocate(__npa, __nbc) : nullptr);
__bucket_list_.get_deleter().size() = __nbc;
if (__nbc > 0)
{
for (size_type __i = 0; __i < __nbc; ++__i)
__bucket_list_[__i] = nullptr;
__next_pointer __pp = __p1_.first().__ptr();
__next_pointer __cp = __pp->__next_;
if (__cp != nullptr)
{
size_type __chash = __constrain_hash(__cp->__hash(), __nbc);
__bucket_list_[__chash] = __pp;
size_type __phash = __chash;
for (__pp = __cp, __cp = __cp->__next_; __cp != nullptr;
__cp = __pp->__next_)
{
__chash = __constrain_hash(__cp->__hash(), __nbc);
if (__chash == __phash)
__pp = __cp;
else
{
if (__bucket_list_[__chash] == nullptr)
{
__bucket_list_[__chash] = __pp;
__pp = __cp;
__phash = __chash;
}
else
{
__next_pointer __np = __cp;
for (; __np->__next_ != nullptr &&
key_eq()(__cp->__upcast()->__value_,
__np->__next_->__upcast()->__value_);
__np = __np->__next_)
;
__pp->__next_ = __np->__next_;
__np->__next_ = __bucket_list_[__chash]->__next_;
__bucket_list_[__chash]->__next_ = __cp;
}
}
}
}
}
}
我有很多文件,所以我不能把整个代码。我在c ++方面不是那么好。如果我必须以其他方式实施,请告诉我。我必须使用hashMap,因为我还需要更快的搜索。
答案 0 :(得分:0)
您可能在插入时遇到重新哈希。 Unordered_map有多个桶。填充最差时,插入时间为O(size())。 http://en.cppreference.com/w/cpp/container/unordered_map/insert 仅当新元素数大于max_load_factor()* bucket_count()时才会发生重新散列。
您可以使用当前设置执行的操作是: 1.程序初始化的增长映射,因为通常桶的数量不会缩小。 2.从std :: unordered_map更改为Boost :: intrusive_map,您可以在其中手动管理多个存储桶。