7   for (
int i = 0; i < GraphSigV.
Len(); i++) {
 
   14   for (
int i = 0; i < GraphSigV.
Len(); i++) {
 
   21   for (
int i = 0; i < GraphSigV.
Len(); i++) {
 
   27   EdgeV(GraphKey.EdgeV), SigV(GraphKey.SigV), VariantId(GraphKey.VariantId) {
 
   38   if (
this != &GraphKey) {
 
   50   for (
int e = 0; e < 
GetEdges(); e++) {
 
   61     NodeIdH.
AddKey(NI.GetId()); }
 
   65     const int NewNId = NodeIdH.
GetKeyId(NI.GetId());
 
   66     for (
int i = 0; i < NI.GetOutDeg(); i++) {
 
   79     NodeIdH.
AddKey(NI.GetId());
 
   85     const int NewNId = NodeIdH.
GetKeyId(NI.GetId());
 
   86     for (
int i = 0; i < NI.GetOutDeg(); i++) {
 
  102     DegV.
Add(
TIntPr(NodeI.GetInDeg(), NodeI.GetOutDeg()));
 
  108   for (
int i = 0; i < DegV.
Len(); i++) {
 
  115   if (
Nodes >= MnSvdGraph && 
Nodes < MxSvdGraph) {
 
  123       NodeIdH.
AddKey(NodeI.GetId());
 
  126       const int NodeId = NodeIdH.
GetKeyId(NodeI.GetId()) + 1;
 
  127       for (
int e = 0; e < NodeI.GetOutDeg(); e++) {
 
  128         const int DstNId = NodeIdH.
GetKeyId(NodeI.GetOutNId(e)) + 1;  
 
  129         if (NodeId != DstNId) AdjMtx.
At(NodeId, DstNId) = 1;
 
  133       TSvd::Svd(AdjMtx, LSingV, SngValV, RSingV);
 
  135       printf(
"\n***No SVD convergence: G(%d, %d): SngValV.Len():%d\n", 
Nodes(), Graph->
GetEdges(), SngValV.
Len());
 
  139     for (
int i = 0; i < SngValV.
Len(); i++) {
 
  149   for (
int i = 0; i < 
EdgeV.
Len(); i++) {
 
  150     fprintf(F,
"  %d\t%d\n", 
EdgeV[i].Val1(), 
EdgeV[i].Val2());
 
  155   FILE *F = fopen(OutFNm.
CStr(), 
"wt");
 
  156   fprintf(F, 
"/*****\n");
 
  159   fprintf(F, 
"*****/\n\n");
 
  160   fprintf(F, 
"digraph G {\n");
 
  161   if (Size != -1) fprintf(F, 
"  size=\"%d,%d\";\n", Size, Size);
 
  162   fprintf(F, 
"  graph [splines=true overlap=false]\n"); 
 
  163   if (NodeAttrs.
Empty()) fprintf(F, 
"  node  [shape=ellipse, width=0.3, height=0.3]\n");
 
  164   else fprintf(F, 
"  node  [shape=ellipse, %s]\n", NodeAttrs.
CStr());
 
  166     for (
int e = 0; e < 
EdgeV.
Len(); e++) {
 
  167       fprintf(F, 
"  %d -> %d;\n", 
EdgeV[e].Val1(), 
EdgeV[e].Val2()); }
 
  169     for (
int n = 0; n < 
Nodes; n++) { fprintf(F, 
"  %d;\n", n); }
 
  171   if (! Desc.
Empty()) {
 
  172     fprintf(F, 
"  label = \"\\n%s\\n\";", Desc.
CStr());
 
  173     fprintf(F, 
"  fontsize=24;\n");
 
  182   SaveGViz(DotFNm, Desc, NodeAttrs, Size);
 
  189   if (Key1.
Nodes != Key2.
Nodes || EdgeV1.
Len() != EdgeV2.
Len()) { 
return false; }
 
  190   for (
int e1 = 0; e1 < EdgeV1.
Len(); e1++) {
 
  191     const TIntPr Edge2(NodeIdMap[EdgeV1[e1].Val1], NodeIdMap[EdgeV1[e1].Val2]);
 
  192     if (EdgeV2.
SearchBin(Edge2) == -1) 
return false;
 
  199   return IsIsomorph(Key1, Key2, NodeIdMapV, IsoPermId);
 
  208   const int Nodes = NodeIdMapV[0].
Len();
 
  210   TIntV AdjMtx2(Nodes*Nodes);
 
  211   for (
int i = 0; i < EdgeV2.
Len(); i++) {
 
  212     AdjMtx2[EdgeV2[i].Val1*Nodes + EdgeV2[i].Val2] = 1;
 
  214   for (
int perm = 0; perm < NodeIdMapV.
Len(); perm++) {
 
  215     const TIntV& NodeIdMap = NodeIdMapV[perm];
 
  217     for (
int e1 = 0; e1 < EdgeV1.
Len(); e1++) {
 
  218       const int NId1 = NodeIdMap[EdgeV1[e1].Val1];
 
  219       const int NId2 = NodeIdMap[EdgeV1[e1].Val2];
 
  220       if (AdjMtx2[NId1*Nodes + NId2] != 1) {
 
  221         IsIso = 
false;  
break; }
 
  238   const int MxEdges = Edges1+1;
 
  243   while (g1 < Edges1 && g2 < Edges2) {
 
  244     if (e == MxEdges) 
return false;
 
  245     if (abs(g1 - g2) > 1) 
return false;
 
  246     if (EdgeV1[g1] == EdgeV2[g2]) { e++;  g1++;  g2++; }
 
  247     else if (EdgeV1[g1] < EdgeV2[g2]) { e++;  g1++; }
 
  252   while (g1 < Edges1 && g2 < Edges2) {
 
  253     if (EdgeV1[g1] == EdgeV2[g2]) {
 
  254       EdgeV[e] = EdgeV1[g1];  e++;  g1++;  g2++; }
 
  255     else if (EdgeV1[g1] < EdgeV2[g2]) {
 
  256       EdgeV[e] = EdgeV1[g1];  e++;  g1++; }
 
  258       EdgeV[e] = EdgeV2[g2];  e++;  g2++; }
 
  260   if (g1 == Edges1 && g2 == Edges2 && e == MxEdges) 
return true;
 
  261   if (e+1 == MxEdges) {
 
  262     if (g1+1 == Edges1 && g2 == Edges2) {
 
  266     if (g1 == Edges1 && g2+1 == Edges2) {
 
  276   else printf(
"Edges: %d\n", 
EdgeV.
Len());
 
  277   for (
int i = 0; i < 
EdgeV.
Len(); i++) {
 
  278     printf(
"\t%d\t%d\n", 
EdgeV[i].Val1(), 
EdgeV[i].Val2());
 
  289     for (
int e = 0; e < NI.GetOutDeg(); e++) {
 
  290       EdgeV[0] = 
TIntPr(NI.GetId(), NI.GetOutNId(e));
 
  297   for (
int g1 = 0; g1 < 
SgV.
Len()-1; g1++) {
 
  298     const TIntPr& E1 = 
SgV[g1].GetEdgeV()[0];
 
  299     for (
int g2 = g1+1; g2 < 
SgV.
Len(); g2++) {
 
  300       const TIntPr& E2 = 
SgV[g2].GetEdgeV()[0];
 
  321   for (
int edges = 3; edges <= MaxEdges; edges++) {
 
  323     printf(
"  %2d edge graphs:", edges);
 
  324     for (
int g1 = 0; g1 < 
SgV.
Len()-1; g1++) {
 
  325       for (
int g2 = g1+1; g2 < 
SgV.
Len(); g2++) {
 
  350     RecurBfs(NI.GetId(), MxDepth, SimpleG);
 
  354   printf(
"\ncandidates: %d\n", 
SgV.
Len());
 
  357   for (
int i = 1; i < 
SgV.
Len(); i++) {
 
  358     if (
SgV[i-1] != 
SgV[i]) Cnt++;
 
  360   printf(
"distinct:   %d\t[%s]\n", Cnt, ExeTm.
GetTmStr());
 
  367     for (
int i = 1; i < EdgeV.
Len(); i++) {
 
  368       if (EdgeV[i-1] == EdgeV[i]) { 
return; }
 
  374   for (
int e = 0; e < NI.
GetOutDeg(); e++) {
 
  379   for (
int e = 0; e < NI.
GetInDeg(); e++) {
 
  395   printf(
"candidates: %d\n", 
SgV.
Len());
 
  398   for (
int i = 1; i < 
SgV.
Len(); i++) {
 
  404   printf(
"distinct:   %d\t[%s]\n", Cnt, ExeTm.
GetTmStr());
 
  410     EdgeH.GetKeyV(EdgeV);
 
  416   for (
int e = 0; e < NI.
GetOutDeg(); e++) {
 
  418     if (! 
EdgeH.IsKey(Edge)) {
 
  424   for (
int e = 0; e < NI.
GetInDeg(); e++) {
 
  426     if (! 
EdgeH.IsKey(Edge)) {
 
int GetEdges() const 
Returns the number of edges in the graph. 
 
void TakeSig(const PNGraph &Graph, const int &MnSvdGraph, const int &MxSvdGraph)
Creates a signature for a given directed graph. 
 
static const T & Mn(const T &LVal, const T &RVal)
 
TPair< TInt, TInt > TIntPr
 
TNodeI BegNI() const 
Returns an iterator referring to the first node in the graph. 
 
Simple directed/undirected graph defined by its edges. 
 
static const T & Mx(const T &LVal, const T &RVal)
 
static PNGraph New()
Static constructor that returns a pointer to the graph. Call: PNGraph Graph = TNGraph::New(). 
 
TNodeI GetNI(const int &NId) const 
Returns an iterator referring to the node of ID NId in the graph. 
 
void Save(TSOut &SOut) const 
 
int GetKeyId(const TKey &Key) const 
 
int GetEdges() const 
Returns the number of edges in the graph. 
 
TSizeTy Len() const 
Returns the number of elements in the vector. 
 
int GetNodes() const 
Returns the number of nodes in the graph. 
 
int AddNode(int NId=-1)
Adds a node of ID NId to the graph. 
 
bool Join(const TSimpleGraph &G1, const TSimpleGraph &G2)
 
static bool IsIsomorph(const TGraphKey &Key1, const TGraphKey &Key2, const TIntV &NodeIdMap)
Checks whether directed graph Key1 is isomorphic to the directed graph Key2 under node Id permutation...
 
void EnumSubGraphs(const int &MaxEdges)
 
void Save(TSOut &SOut) const 
 
bool Empty() const 
Tests whether the vector is empty. 
 
void AddEdge(const int &SrcNId, const int &DstNId)
 
const char * GetTmStr() const 
 
THash< TIntPr, TIntH > EdgeH
 
void GVizDoLayout(const TStr &GraphInFNm, TStr OutFNm, const TGVizLayout &Layout)
Runs GraphViz layout engine over a graph saved in the file GraphInFNm with output saved to OutFNm...
 
TGraphKey & operator=(const TGraphKey &GraphKey)
 
static void Svd(const TFltVV &InMtx, TFltVV &LSingV, TFltV &SingValV, TFltVV &RSingV)
 
void Clr(const bool &DoDel=true, const TSizeTy &NoDelLim=-1)
Clears the contents of the vector. 
 
void Sort(const bool &Asc=true)
Sorts the elements of the vector. 
 
int AddEdge(const int &SrcNId, const int &DstNId)
Adds an edge from node IDs SrcNId to node DstNId to the graph. 
 
void RecurBfs(const int &MxDepth)
 
static double Round(const double &Val)
 
int AddKey(const TKey &Key)
 
const TVal & Last() const 
Returns a reference to the last element of the vector. 
 
void Dump(const TStr &Desc=TStr()) const 
 
void Save(TSOut &SOut) const 
 
void TakeGraph(const PNGraph &Graph)
Creates a key from a given directed graph. 
 
TSizeTy SearchBin(const TVal &Val) const 
Returns the position of an element with value Val. 
 
void Defrag(const bool &OnlyNodeLinks=false)
Defragments the graph. 
 
int GetNodes() const 
Returns the number of nodes in the graph. 
 
int GetKeyId(const TKey &Key) const 
 
PNGraph GetNGraph() const 
Returns the directed graph stored in the GraphKey object. 
 
void SaveGViz(const TStr &OutFNm, const TStr &Desc=TStr(), const TStr &NodeAttrs="", const int &Size=-1) const 
Saves the graph to the .DOT file format used by GraphViz. 
 
int AddKey(const TKey &Key)
 
TNodeI EndNI() const 
Returns an iterator referring to the past-the-end node in the graph. 
 
int GetId() const 
Returns ID of the current node. 
 
int GetOutDeg() const 
Returns out-degree of the current node. 
 
void Pack()
The vector reduces its capacity (frees memory) to match its size. 
 
void RecurBfs1(const int &MxDepth)
 
Node iterator. Only forward iteration (operator++) is supported. 
 
void DrawGViz(const TStr &OutFNm, const TStr &Desc=TStr(), const TStr &NodeAttrs="", const int &Size=-1) const 
Saves the graph to the .DOT file format and calls GraphViz to draw it. 
 
void Gen(const TSizeTy &_Vals)
Constructs a vector (an array) of _Vals elements. 
 
void MoveFrom(TVec< TVal, TSizeTy > &Vec)
Takes over the data and the capacity from Vec. 
 
void SaveTxt(FILE *F) const 
Saves the graph as a list of edges. 
 
int GetInDeg() const 
Returns in-degree of the current node. 
 
int GetInNId(const int &NodeN) const 
Returns ID of NodeN-th in-node (the node pointing to the current node). 
 
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element. 
 
const TVal & At(const int &X, const int &Y) const 
 
int GetOutNId(const int &NodeN) const 
Returns ID of NodeN-th out-node (the node the current node points to). 
 
Vector is a sequence TVal objects representing an array that can change in size.