-
Notifications
You must be signed in to change notification settings - Fork 1
/
NautyLink.cpp
132 lines (104 loc) · 3.91 KB
/
NautyLink.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: NautyLink.cpp
* Author: Wooyoung
*
* Created on October 27, 2017, 11:36 AM
*/
#include "NautyLink.h"
NautyLink::NautyLink(int subgraphsize, unordered_map<edge, edgetype> edgeset):NautyLink(subgraphsize, edgeset, false) {
}
NautyLink::NautyLink(int subgraphsize, unordered_map<edge, edgetype> edgeset, bool dir) {
G_N=subgraphsize;
directed=dir;
nautyinit();
edges = edgeset;
}
NautyLink::~NautyLink() {
}
int NautyLink::get_G_N(){
return G_N;
}
graph64 NautyLink::getLabel(graph* canon, set* gv, const int G_N, const int G_M)
{
//Fanmod code to retrieve canon data
graph64 res_gr = 0ULL;
for (int a = 0; a < G_N; ++a)
{
gv = GRAPHROW(canon, a, G_M);
for (int b = 0; b < G_N; ++b)
{
res_gr <<= 1;
if (ISELEMENT(gv, b))
{
res_gr |= 1;
}
}
}
return res_gr;
}
void NautyLink::nautyinit(){
G_M = (G_N + WORDSIZE - 1) / WORDSIZE; //#define WORDSIZE 64
options.writeautoms = FALSE;
options.getcanon = TRUE;
if (directed) {
options.digraph = TRUE;
options.invarproc = adjacencies;
options.mininvarlevel = 1;
options.maxinvarlevel = 10;
}
// Initialize nautyGraph
for (int i = 0; i != G_N; ++i) {
EMPTYSET(GRAPHROW(nautyGraph, i, G_M), G_M);
}
nauty_check(WORDSIZE, G_M, G_N, NAUTYVERSIONID);
}
/* For each subgraph, return its cannonical label */
graph64 NautyLink::nautylabel(Subgraph& subgraph){
// get the node(index) list from subgraph
int subsize = subgraph.getSize();
// get the adjacenylists of the node(index) list from subgraph
// key = node id. value = the adjacencylist of the node (key)
//go through each pair from nodes and connect if there is an edge
for (int i = 0; i < subsize ; i++) {
for (int j = 0; j < subsize ; j++) {
if (i != j) {
vertex uc = subgraph.get(i);
vertex vc = subgraph.get(j);
edge e_check = edge_code(uc, vc);
//if there is an edge between nodes[i] and nodes[j], connect i and j
if (edges.count(e_check) > 0) {
edgetype ec = edges[e_check];
if (((uc < vc) && (ec == DIR_U_T_V)) || ((uc > vc) && (ec == DIR_V_T_U))) {
// cout<<"1. connect "<<uc<<" and "<<vc<<endl;
DELELEMENT(GRAPHROW(nautyGraph, i, G_M), j);
gv = GRAPHROW(nautyGraph, i, G_M);
ADDELEMENT(gv, j);
} /*else if (((uc < vc) && (ec == DIR_V_T_U)) || ((uc > vc) && (ec == DIR_U_T_V))) {
cout<<"2. connect "<<vc<<" and "<<uc<<endl;
DELELEMENT(GRAPHROW(nautyGraph, j, G_M), i);
gv = GRAPHROW(nautyGraph, j, G_M);
ADDELEMENT(gv, i);
}*/ else if (ec == UNDIR_U_V) {
// cout<<"3. connect "<<uc<<" and "<<vc<<endl;
DELELEMENT(GRAPHROW(nautyGraph, i, G_M), j);
gv = GRAPHROW(nautyGraph, i, G_M);
ADDELEMENT(gv, j);
}
}
}
}
}
nauty(nautyGraph, lab, ptn, NILSET, orbits, &options, &stats, workspace, 160 * MAXM, G_M, G_N, canon);
// get the cannonical label
graph64 res_gr = getLabel(canon, gv,G_N, G_M);
// then initialize the graph
for (int i = 0; i != G_N; ++i) {
EMPTYSET(GRAPHROW(nautyGraph, i, G_M), G_M);
}
return res_gr;
}