Snap算法学习01-01关于节点及边的操作

发布时间 2023-05-31 11:02:56作者: 海阔凭鱼跃越

 

 

 

  //alg.h
 
 1 // 对图中节点进行遍历,找出入度数与指定值相等的节点个数
 2 // Returns the number of nodes with in-degree NodeInDeg
 3 template <class PGraph>
 4 int CntInDegNodes(const PGraph& Graph, const int& NodeInDeg) {
 5   int Cnt = 0;
 6   for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
 7     if (NI.GetInDeg() == NodeInDeg) Cnt++;
 8   }
 9   return Cnt;
10 }

(1)掌握遍历全部节点的方法

(2)获取当前节点的入度    NI.GetInDeg()

(3)获取当前节点的出度    NI.GetOutDeg();  获取当前节点的度 NI.GetDeg();

 
 1 // 指定节点NId与节点集合NodeSet中各点之间的存在边的数量
 2 // Returns the number of nodes in NodeSet that have an edge to the node NId.
 3 template <class PGraph>
 4 int CntEdgesToSet(const PGraph& Graph, const int& NId, const TIntSet& NodeSet) {
 5   if (! Graph->IsNode(NId)) { return 0; }
 6   const bool IsDir = Graph->HasFlag(gfDirected);
 7   const typename PGraph::TObj::TNodeI NI = Graph->GetNI(NId);
 8   if (! IsDir) {
 9     int EdgesToSet = 0;
10     for (int e = 0; e < NI.GetOutDeg(); e++) {
11       if (NodeSet.IsKey(NI.GetOutNId(e))) { EdgesToSet++; } }
12     return EdgesToSet;
13   } else {
14     TIntSet Set(NI.GetDeg());
15     for (int e = 0; e < NI.GetOutDeg(); e++) {
16       if (NodeSet.IsKey(NI.GetOutNId(e))) { Set.AddKey(NI.GetOutNId(e)); } }
17     for (int e = 0; e < NI.GetInDeg(); e++) {
18       if (NodeSet.IsKey(NI.GetInNId(e))) { Set.AddKey(NI.GetInNId(e)); } }
19     return Set.Len();
20   }
21 }

(1)整形节点号NId构造为特定节点数据结构量NI:

const typename PGraph::TObj::TNodeI NI = Graph->GetNI(NId);
反过来,已知NI获取对应的整形量: NI.GetId();
 

(2)与节点NI有连线的节点共NI.GetDeg()个;依次列出对应节点对应节点号:

for (int e = 0; e < NI.GetOutDeg(); e++) {NI.GetOutNId(e)}

(3)节点集合:

声明 TIntSet Set(预留元素数量);//元素是字典key-value对

增加元素:Set.AddKey(节点号);

判断节点NId是否再集合中: Set.IsKey(NId);

节点集合的大小(包含元素的个数):Set.Len();

   
 1 // 找出拥有最大度数的若干节点,并从中随机选取一个节点作为返回值。
 2 // Returns a randomly chosen node from all the nodes with the maximum degree.
 3 template <class PGraph>
 4 int GetMxDegNId(const PGraph& Graph) {
 5   TIntV MxDegV;
 6   int MxDeg=-1;
 7   for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
 8     if (MxDeg < NI.GetDeg()) { MxDegV.Clr(); MxDeg = NI.GetDeg(); }
 9     if (MxDeg == NI.GetDeg()) { MxDegV.Add(NI.GetId()); }
10   }
11   EAssertR(! MxDegV.Empty(), "Input graph is empty!");
12   return MxDegV[TInt::Rnd.GetUniDevInt(MxDegV.Len())];
13 }

(1)声明整型向量并添加元素:

TIntV MxDegV;
MxDegV.Add(NI.GetId());

(2)从向量MxDegV中任选一个元素:

MxDegV[TInt::Rnd.GetUniDevInt(MxDegV.Len())];
   
1 // 获取每个节点及其度数
2 // Returns a vector of pairs :(node id, node in-degree)
3 template <class PGraph>
4 void GetNodeInDegV(const PGraph& Graph, TIntPrV& NIdInDegV) {
5   NIdInDegV.Reserve(Graph->GetNodes(), 0);
6   for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
7     NIdInDegV.Add(TIntPr(NI.GetId(), NI.GetInDeg()));
8   }
9 }
1 template <class PGraph>
2 void GetNodeOutDegV(const PGraph& Graph, TIntPrV& NIdOutDegV) {
3   NIdOutDegV.Reserve(Graph->GetNodes(), 0);
4   for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
5     NIdOutDegV.Add(TIntPr(NI.GetId(), NI.GetOutDeg()));
6   }
7 }

注意:

NIdOutDegV、NIdInDegV是TIntPrV类型的向量,且元素为TPair结构。元素对象Pair拥有两个数据成员Pair.Val1,Pair.Val2
从向量中获取TPair元素对应属性的操作:NIdOutDegV[i].Val1,NIdOutDegV[i].Val1