Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implemented sct #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ class Graph {
vidType difference_set_edgeinduced(vidType v, vidType u, vlabel_t label, VertexSet& result);
vidType difference_set_edgeinduced(VertexSet& vs, vidType u, vlabel_t label, VertexSet& result);

// degeneracy ordering
vector<int> degeneracy_ordering();

// print graph information
void print_meta_data() const;
void print_graph() const;
Expand Down
3 changes: 3 additions & 0 deletions include/pattern.hh
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ public:
// colorful patterns
bool is_4color_square() const { return name_ == "4color-square"; }

// sct
bool is_sct() const { return name_ == "sct"; }

bool is_connected(vidType u, vidType v) const;
void read_adj_file(std::string inputfile);
std::string get_name() const { return name_; }
Expand Down
46 changes: 46 additions & 0 deletions src/common/graph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -728,3 +728,49 @@ void Graph::computeKCore() {
}
}

vector<int> Graph::degeneracy_ordering() {
int nv = size();
int md = get_max_degree();
std::vector<int> vertices(nv); // Vertices sorted by degree.
std::vector<int> position(nv); // The position of vertices in vertices array.
std::vector<int> degree_bin(md+1, 0); // Degree from 0 to max_degree.
std::vector<int> offset(md+1); // The offset in vertices array according to degree.
std::vector<int> d(nv);

for (int i = 0; i < nv; ++i) {
int degree = get_degree(i);
d[i] = degree;
degree_bin[degree] += 1;
}
int start = 0;
for (int i = 0; i < md+1; ++i) {
offset[i] = start;
start += degree_bin[i];
}
for (int i = 0; i < nv; ++i) {
int degree = get_degree(i);
position[i] = offset[degree];
vertices[position[i]] = i;
offset[degree] += 1;
}
for (int i = md; i > 0; --i) {
offset[i] = offset[i - 1];
}
offset[0] = 0;
for (int i = 0; i < nv; ++i) {
vidType v = vertices[i];
for (vidType u: N(v)) {
if (position[u] > position[v]) {
int pos_w = offset[d[u]];
vidType w = vertices[pos_w];
if (u != w) {
swap(vertices[position[u]], vertices[pos_w]);
swap(position[u], position[w]);
}
offset[d[u]--]++;
offset[d[v]--]++;
}
}
}
return position;
}
119 changes: 119 additions & 0 deletions src/count/cpu_kernels/sct.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// #pragma omp parallel for schedule(dynamic,1) reduction(+:counter)
enum CallType { PIVOT, HOLD };
vector<int> position = g.degeneracy_ordering();

vector<vector<uint64_t> > C = {{1}};
for (int i = 1; i <= 100; i++) {
vector<uint64_t> new_row = {1};
for (int j = 0; j < i - 1; j++) new_row.push_back(C.back()[j] + C.back()[j + 1]);
new_row.push_back(1);
C.push_back(new_row);
}

struct SCT {
VertexList vlabel;
pair<vidType, CallType> elabel;
vector<SCT*> children;
void count_cliques(vector<int>& p, vector<int>& h, vector<int>& cnt, vector<vector<uint64_t> >& C) {
if (elabel.second == PIVOT) p.push_back(elabel.first);
else h.push_back(elabel.first);
vidType p_sz = p.size();
vidType h_sz = h.size();
if (children.empty()) {
for (int i = 0; i < p_sz; i++) cnt[h_sz + i] += C[p_sz - 1][i];
}
else {
for (SCT* child: children) child->count_cliques(p, h, cnt, C);
}
if (elabel.second == PIVOT) p.pop_back();
else h.pop_back();
};
};

SCT* sct = new SCT();
sct->elabel = {-1, PIVOT};
for (vidType v = 0; v < g.size(); v++) sct->vlabel.push_back(v);

queue<SCT*> q;
for (vidType v = 0; v < g.size(); v++) {
SCT* child = new SCT();
for (vidType u: g.N(v)) {
if (position[u] > position[v]) child->vlabel.append(u);
}
// copy(g.out_colidx() + g.edge_begin(v), g.out_colidx() + g.edge_end(v), back_inserter(child->vlabel));
child->elabel = {v, HOLD};
sct->children.push_back(child);
q.push(child);
}

while (!q.empty()) {
SCT* node = q.front();
q.pop();
if (node->vlabel.size() == 0) continue;

// get all N(S, v)
map<vidType, VertexList> NS;
for (vidType v: node->vlabel) {
set_intersection(
g.out_colidx() + g.edge_begin(v), g.out_colidx() + g.edge_end(v),
begin(node->vlabel), end(node->vlabel),
back_inserter(NS[v])
);
// VertexList tmp;
// set_union(
// g.out_colidx() + g.out_rowptr()[v], g.out_colidx() + g.out_rowptr()[v + 1],
// g.in_colidx() + g.in_rowptr()[v], g.in_colidx() + g.in_rowptr()[v + 1],
// back_inserter(tmp)
// );
// set_intersection(
// begin(tmp), end(tmp),
// begin(node->vlabel), end(node->vlabel),
// back_inserter(NS[v])
// );
}
// find the pivot
vidType p = node->vlabel[0];
for (vidType v: node->vlabel) {
if (NS[v].size() > NS[p].size()) p = v;
}
SCT* child = new SCT();
child->vlabel = NS[p];
child->elabel = {p, PIVOT};
node->children.push_back(child);
q.push(child);

// find other children
VertexList others;
VertexList x, y = {p};
set_union(
begin(NS[p]), end(NS[p]),
begin(y), end(y),
back_inserter(x)
);
set_difference(
begin(node->vlabel), end(node->vlabel),
begin(x), end(x),
back_inserter(others)
);
while (!others.empty()) {
vidType v = others.back();
others.pop_back();
SCT* child = new SCT();
set_difference(
begin(NS[v]), end(NS[v]),
begin(others), end(others),
back_inserter(child->vlabel)
);
child->elabel = {v, HOLD};
node->children.push_back(child);
q.push(child);
}
}

vector<int> cnt(g.size() + 1);

vector<int> p, h;
sct->count_cliques(p, h, cnt, C);

int idx = 1;
while (idx < cnt.size() && cnt[idx]) cout << cnt[idx++] << " ";
2 changes: 2 additions & 0 deletions src/count/omp_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ void ScSolver(Graph &g, Pattern &p, uint64_t &total, int, int) {
// 6-motifs
} else if (p.is_6path()) {
#include "6path.h"
} else if (p.is_sct()) {
#include "sct.h"
} else {
std::cout << "Not implemented\n";
}
Expand Down