Skip to content

Commit 0f74000

Browse files
committed
Implement Bron-Kerbosch algiruithm for clique detection
1 parent 0cd651e commit 0f74000

File tree

3 files changed

+117
-0
lines changed

3 files changed

+117
-0
lines changed

contrib/mmts/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+
}

contrib/mmts/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();

contrib/mmts/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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy