Compare commits
5 Commits
19119a5adf
...
dev
Author | SHA1 | Date | |
---|---|---|---|
d35206c2b9 | |||
1922396b71 | |||
e953d8aa1f | |||
06690e4982 | |||
a8b52a581f |
@@ -36,14 +36,17 @@ Usage: ./SOCgen -n <order> [-r <num>] [--graphviz] [FILTER ...]
|
|||||||
-n <order> Generate SOCs with `order' connected nodes
|
-n <order> Generate SOCs with `order' connected nodes
|
||||||
-r <num> Pick directed graphs at random, and exit after having found `num' SOCs
|
-r <num> Pick directed graphs at random, and exit after having found `num' SOCs
|
||||||
--graphviz Output SOCs in Graphviz format, arcs of common parents are highlighted
|
--graphviz Output SOCs in Graphviz format, arcs of common parents are highlighted
|
||||||
|
--vector Output SOCs adjacency vectors in the order (0<-1, 0<-2, ..., 1<-0, 1<-2, ...)
|
||||||
|
--all Allow for disconnected SOCs and disable the degree-order filter (see below)
|
||||||
|
|
||||||
[FILTER] Consider only simple directed graphs ...
|
[FILTER] Consider only simple directed graphs ...
|
||||||
-c ... that are cyclic (i.e., not DAGs)
|
-c ... that are cyclic (i.e., not DAGs)
|
||||||
--no-sink ... without sink nodes (this logically implies -c)
|
--no-sink ... without sink nodes (this logically implies -c)
|
||||||
--no-source ... without source nodes (also this logically implies -c)
|
--no-source ... without source nodes (also this logically implies -c)
|
||||||
|
--chordless ... without cycles that have chords (this is incompatible with --no-source, see paper)
|
||||||
|
|
||||||
This program prints the found SOCs as adjacency matrices to stdout, unless --graphviz has been specified.
|
This program prints the found SOCs as adjacency matrices to stdout, unless --graphviz has been specified.
|
||||||
To exclude (some) of the isomorphic SOCs, it uses a degree-order filter.
|
To exclude (some) of the isomorphic SOCs, it uses a degree-order filter, unless --all is specified.
|
||||||
```
|
```
|
||||||
|
|
||||||
### SOCadmissible
|
### SOCadmissible
|
||||||
|
98
src/SOCgen.c
98
src/SOCgen.c
@@ -32,6 +32,30 @@ void dumpgraph(int n, const int *children, const int *childrenlen) {
|
|||||||
printf("}\n");
|
printf("}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Print the graph's adjacency vector.
|
||||||
|
* The entries are (0<-1, 0<-2, ...1, 1<-0, 1<-2, ...)
|
||||||
|
***/
|
||||||
|
void dumpgraphvector(int n, const int *parents, const int *parentslen) {
|
||||||
|
int edge = 0;
|
||||||
|
for (int a = 0; a < n; a++) {
|
||||||
|
for (int b = 0; b < n; b++) {
|
||||||
|
if (a==b) continue;
|
||||||
|
edge = 0;
|
||||||
|
for (int i = 0; i < parentslen[a] && !edge; i++) {
|
||||||
|
const int v = parents[a*n+i];
|
||||||
|
if (b==v) {
|
||||||
|
printf("1");
|
||||||
|
edge = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!edge)
|
||||||
|
printf("0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Print the graph as graphviz command
|
* Print the graph as graphviz command
|
||||||
***/
|
***/
|
||||||
@@ -300,6 +324,65 @@ int find_cycles(int *cycles, int *cyclescnt, int n, const int *children, \
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* gischordless tests wheter the graph provided has chordless cycles only
|
||||||
|
* Parameter `n': Number of nodes
|
||||||
|
* Parameter `parents': Pointer to list of parents per node
|
||||||
|
* Parameter `parentslen': Pointer to list of number of parents per node
|
||||||
|
* Parameter `children': Pointer to list of children per node
|
||||||
|
* Parameter `childrenlen': Pointer to list of number of children per node
|
||||||
|
* Parameter `cycles': Pointer to list of cycles in the graph
|
||||||
|
* Parameter `cyclescnt': Pointer to list of cycles count
|
||||||
|
* Parameter `num_cycles' Total number of cycles
|
||||||
|
*
|
||||||
|
* This function retruns 0 if the graph has a directed cycle with a chord, and
|
||||||
|
* 1 otherwise.
|
||||||
|
*
|
||||||
|
* If there is no cycle, then the graph trivially satisfy this condition.
|
||||||
|
* Cycles of length two are trivially chordless.
|
||||||
|
* If there is a k-cycle, then a chord implies the existance of an l-cycle
|
||||||
|
* with l < k.
|
||||||
|
***/
|
||||||
|
int gischordless(int n, const int *parents, const int *parentslen, \
|
||||||
|
const int *children, const int *childrenlen, const int *cycles, \
|
||||||
|
const int *cyclescnt, int num_cycles) {
|
||||||
|
if (!num_cycles) return 1;
|
||||||
|
for (int clen=n; clen>2; clen--) {
|
||||||
|
if (!cyclescnt[clen]) continue;
|
||||||
|
// A chord can only exist if there is a cycle of length < clen
|
||||||
|
int shortercycleexists = 0;
|
||||||
|
for (int sclen = 2; sclen < clen; sclen++) {
|
||||||
|
if (cyclescnt[sclen]) {
|
||||||
|
shortercycleexists = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!shortercycleexists) return 1;
|
||||||
|
for (int i=0; i<cyclescnt[clen]; i++) {
|
||||||
|
const int bs = blocksize(n);
|
||||||
|
const int startidx = clen*bs + i*clen; // Cycle starts here
|
||||||
|
int v = cycles[startidx+clen-1];
|
||||||
|
for (int pos=0; pos<clen; pos++) {
|
||||||
|
const int u = v;
|
||||||
|
v = cycles[startidx+pos];
|
||||||
|
// Cycle has arc u -> v
|
||||||
|
// Is there a chord, i.e., A) reverse arc u <- v or B) u -> v' for v'
|
||||||
|
// on the cycle? We test only B), but for all vertices on the cycle.
|
||||||
|
for (int cidx=0; cidx<childrenlen[u]; cidx++) {
|
||||||
|
const int child = children[n*u+cidx];
|
||||||
|
if (child == v) continue;
|
||||||
|
// Is `child` on the cycle?
|
||||||
|
for (int j=0; j<clen; j++) {
|
||||||
|
const int w = cycles[startidx+j];
|
||||||
|
if (child == w) return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* gissoc tests wheter the graph provided is a SOC or not.
|
* gissoc tests wheter the graph provided is a SOC or not.
|
||||||
* Parameter `n': Number of nodes
|
* Parameter `n': Number of nodes
|
||||||
@@ -460,6 +543,8 @@ int main(int argc, char *argv[]) {
|
|||||||
int NOSOURCE = 0;
|
int NOSOURCE = 0;
|
||||||
int RANDOM = 0;
|
int RANDOM = 0;
|
||||||
int GRAPHVIZ = 0;
|
int GRAPHVIZ = 0;
|
||||||
|
int VECTOR = 0;
|
||||||
|
int CHORDLESS = 0;
|
||||||
int UNKOPTION = 0;
|
int UNKOPTION = 0;
|
||||||
int ALL = 0;
|
int ALL = 0;
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
@@ -479,6 +564,10 @@ int main(int argc, char *argv[]) {
|
|||||||
GRAPHVIZ = 1;
|
GRAPHVIZ = 1;
|
||||||
} else if (strcmp(argv[i], "--all") == 0) {
|
} else if (strcmp(argv[i], "--all") == 0) {
|
||||||
ALL = 1;
|
ALL = 1;
|
||||||
|
} else if (strcmp(argv[i], "--vector") == 0) {
|
||||||
|
VECTOR = 1;
|
||||||
|
} else if (strcmp(argv[i], "--chordless") == 0) {
|
||||||
|
CHORDLESS = 1;
|
||||||
} else {
|
} else {
|
||||||
UNKOPTION = 1;
|
UNKOPTION = 1;
|
||||||
break;
|
break;
|
||||||
@@ -489,12 +578,14 @@ int main(int argc, char *argv[]) {
|
|||||||
fprintf(stderr, " -n <order> Generate SOCs with `order' connected nodes\n");
|
fprintf(stderr, " -n <order> Generate SOCs with `order' connected nodes\n");
|
||||||
fprintf(stderr, " -r <num> Pick directed graphs at random, and exit after having found `num' SOCs\n");
|
fprintf(stderr, " -r <num> Pick directed graphs at random, and exit after having found `num' SOCs\n");
|
||||||
fprintf(stderr, " --graphviz Output SOCs in Graphviz format, arcs of common parents are highlighted\n");
|
fprintf(stderr, " --graphviz Output SOCs in Graphviz format, arcs of common parents are highlighted\n");
|
||||||
|
fprintf(stderr, " --vector Output SOCs adjacency vectors in the order (0<-1, 0<-2, ..., 1<-0, 1<-2, ...)\n");
|
||||||
fprintf(stderr, " --all Allow for disconnected SOCs and disable the degree-order filter (see below)\n");
|
fprintf(stderr, " --all Allow for disconnected SOCs and disable the degree-order filter (see below)\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "[FILTER] Consider only simple directed graphs ...\n");
|
fprintf(stderr, "[FILTER] Consider only simple directed graphs ...\n");
|
||||||
fprintf(stderr, " -c ... that are cyclic (i.e., not DAGs)\n");
|
fprintf(stderr, " -c ... that are cyclic (i.e., not DAGs)\n");
|
||||||
fprintf(stderr, " --no-sink ... without sink nodes (this logically implies -c)\n");
|
fprintf(stderr, " --no-sink ... without sink nodes (this logically implies -c)\n");
|
||||||
fprintf(stderr, " --no-source ... without source nodes (also this logically implies -c)\n");
|
fprintf(stderr, " --no-source ... without source nodes (also this logically implies -c)\n");
|
||||||
|
fprintf(stderr, " --chordless ... without cycles that have chords (this is incompatible with --no-source, see paper)\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "This program prints the found SOCs as adjacency matrices to stdout, unless --graphviz has been specified.\n");
|
fprintf(stderr, "This program prints the found SOCs as adjacency matrices to stdout, unless --graphviz has been specified.\n");
|
||||||
fprintf(stderr, "To exclude (some) of the isomorphic SOCs, it uses a degree-order filter, unless --all is specified.\n");
|
fprintf(stderr, "To exclude (some) of the isomorphic SOCs, it uses a degree-order filter, unless --all is specified.\n");
|
||||||
@@ -538,6 +629,8 @@ int main(int argc, char *argv[]) {
|
|||||||
fprintf(stderr, " Filter: Omitting graphs with sink nodes\n");
|
fprintf(stderr, " Filter: Omitting graphs with sink nodes\n");
|
||||||
if (NOSOURCE)
|
if (NOSOURCE)
|
||||||
fprintf(stderr, " Filter: Omitting graphs with source nodes\n");
|
fprintf(stderr, " Filter: Omitting graphs with source nodes\n");
|
||||||
|
if (CHORDLESS)
|
||||||
|
fprintf(stderr, " Filter: Omitting graphs with chords in directed cycles\n");
|
||||||
// We will always omit the graph with `graphnumber' 0;
|
// We will always omit the graph with `graphnumber' 0;
|
||||||
// it is unintersting anyway
|
// it is unintersting anyway
|
||||||
unsigned long long graphnumber = 0;
|
unsigned long long graphnumber = 0;
|
||||||
@@ -602,9 +695,14 @@ int main(int argc, char *argv[]) {
|
|||||||
if (num_cycles > 0 && !gissoc(n, parents, parentslen, children, \
|
if (num_cycles > 0 && !gissoc(n, parents, parentslen, children, \
|
||||||
childrenlen, cycles, cyclescnt)) continue;
|
childrenlen, cycles, cyclescnt)) continue;
|
||||||
// We have found a SOC
|
// We have found a SOC
|
||||||
|
// If enabled, test chordless property
|
||||||
|
if (CHORDLESS && !gischordless(n, parents, parentslen, children, \
|
||||||
|
childrenlen, cycles, cyclescnt, num_cycles)) continue;
|
||||||
len++;
|
len++;
|
||||||
if (GRAPHVIZ)
|
if (GRAPHVIZ)
|
||||||
dumpgv(n, graphnumber, children, childrenlen);
|
dumpgv(n, graphnumber, children, childrenlen);
|
||||||
|
else if (VECTOR)
|
||||||
|
dumpgraphvector(n, parents, parentslen);
|
||||||
else
|
else
|
||||||
dumpgraph(n, children, childrenlen);
|
dumpgraph(n, children, childrenlen);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user