Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8b256c1

Browse files
knizhnikkelvich
authored andcommitted
Implement Bron-Kerbosch algiruithm for clique detection
1 parent 3a62970 commit 8b256c1

File tree

3 files changed

+117
-0
lines changed

3 files changed

+117
-0
lines changed

bkb.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Bron–Kerbosch algorithm to find maximum clque in graph
3+
*/
4+
5+
typedef struct {
6+
int size;
7+
int nodes[MAX_NODES];
8+
} List;
9+
10+
static void list_append(List* list, int n)
11+
{
12+
nodes[list->size++] = n;
13+
}
14+
15+
static void list_copy(List* dst, List* src)
16+
{
17+
int i;
18+
int n = src->size;
19+
dst->size = n;
20+
for (i = 0; i < n; i++) {
21+
dst->nodes[i] = src->nodes[i];
22+
}
23+
}
24+
25+
26+
static void findMaximumIndependentSet(List* cur, List* result, nodemask_t* graph, int* oldSet, int ne, int ce)
27+
{
28+
int nod = 0;
29+
int minnod = ce;
30+
int fixp = -1;
31+
int s = -1;
32+
int i, j;
33+
int newSet[MAX_NODES];
34+
35+
for (i = 0; i < ce && minnod != 0; i++) {
36+
int p = oldSet[i];
37+
int cnt = 0;
38+
int pos = -1;
39+
40+
for (j = ne; j < ce; j++) {
41+
if (!BIT_CHECK(graph[p], oldSet[j])) {
42+
if (++cnt == minnod)
43+
break;
44+
pos = j;
45+
}
46+
}
47+
if (minnod > cnt) {
48+
minnod = cnt;
49+
fixp = p;
50+
if (i < ne) {
51+
s = pos;
52+
} else {
53+
s = i;
54+
nod = 1;
55+
}
56+
}
57+
}
58+
59+
60+
for (int k = minnod + nod; k >= 1; k--) {
61+
int sel = oldSet[s];
62+
oldSet[s] = oldSet[ne];
63+
oldSet[ne] = sel;
64+
65+
int newne = 0;
66+
for (int i = 0; i < ne; i++) {
67+
if (BIT_CHECK(graph[sel], oldSet[i])) {
68+
newSet[newne++] = oldSet[i];
69+
}
70+
}
71+
int newce = newne;
72+
for (int i = ne + 1; i < ce; i++) {
73+
if (BIT_CHECK(graph[sel], oldSet[i])) {
74+
newSet[newce++] = oldSet[i];
75+
}
76+
}
77+
list_append(cur, sel);
78+
if (newce == 0) {
79+
if (result->size < cur->size) {
80+
list_copy(result, cur);
81+
}
82+
} else if (newne < newce) {
83+
if (cur->size + newce - newne > result->size) {
84+
findMaximumIndependentSet(cur, result, graph, newSet, newne, newce);
85+
}
86+
}
87+
cur.size -= 1;
88+
if (k > 1) {
89+
for (s = ++ne; BIT_CHECK(graph[fixp], oldSet[s]); s++);
90+
}
91+
}
92+
}
93+
94+
nodemask_t MtmFindMaxClique(nodemask_t* graphs, in n_nodes);
95+
{
96+
List tmp;
97+
List result;
98+
nodemask_t mask = 0;
99+
int all[MAX_NODES];
100+
int i;
101+
tmp.size = 0;
102+
result.size = 0;
103+
for (i = 0; i < n_nodes; i++) {
104+
all[i]= i;
105+
}
106+
findMaximumIndependentSet(&tmp, &result, graph, all, 0, n_nodes);
107+
for (i = 0; i < result.size; i++) {
108+
mask |= (nodemask_t)1 << result.nodes[i];
109+
}
110+
return ~mask;
111+
}

multimaster.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,10 @@ _PG_init(void)
10231023
if (MtmNodes < 2) {
10241024
elog(ERROR, "Multimaster should have at least two nodes");
10251025
}
1026+
if (MtmNodes > MAX_NODES) {
1027+
elog(ERROR, "Multimaster with mor than %d nodes is not currently supported", MAX_NODES);
1028+
}
1029+
10261030
BgwPoolStart(MtmWorkers, MtmPoolConstructor);
10271031

10281032
MtmArbiterInitialize();

multimaster.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#define Anum_mtm_ddl_log_issued 1
2626
#define Anum_mtm_ddl_log_query 2
2727

28+
#define MAX_NODES 64
2829

2930
typedef uint64 csn_t; /* commit serial number */
3031
#define INVALID_CSN ((csn_t)-1)
@@ -146,5 +147,6 @@ extern MtmState* MtmGetState(void);
146147
extern timestamp_t MtmGetCurrentTime(void);
147148
extern void MtmSleep(timestamp_t interval);
148149
extern bool MtmIsRecoveredNode(int nodeId);
150+
extern nodemask_t MtmFindMaxClique(nodemask_t* matrix, in n_modes);
149151

150152
#endif

0 commit comments

Comments
 (0)