Add all required files

This commit is contained in:
Ashik K 2017-07-01 11:49:30 +02:00
parent fb5be62c6f
commit 3308c5d8be
7 changed files with 643 additions and 0 deletions

View File

@ -1,2 +1,7 @@
# oddcycle_shannon_capacity # oddcycle_shannon_capacity
Code for the shannon capacity of odd cycles paper http://dl.acm.org/citation.cfm?id=3100779 Code for the shannon capacity of odd cycles paper http://dl.acm.org/citation.cfm?id=3100779
paper is also available at https://arxiv.org/abs/1504.01472
The code is written by the authors of the paper and is uploaded to GitGub for archival
and for any refernce use by other researchers.

93
code/conj.cpp Normal file
View File

@ -0,0 +1,93 @@
#include "rep.h"
#include<cstring>
#define MAXC 22450
int is_conj(int e1[5], int e2[5]) {
for (int i1 = 0; i1<18; i1++) {
for(int i2 = 0; i2<18; i2++) {
for (int i3 = 0; i3<18; i3++) {
for(int i4 = 0; i4<18; i4++) {
for(int j1 = 0; j1<24; j1++) {
int g[5];
g[0] = i1, g[1] = i2, g[2] = i3, g[3] = i4, g[4] = j1;
int ge1[5];
perform_groupop(g, e1, ge1);
int ginv[5];
inverse(g, ginv);
int ge1ginv[5];
perform_groupop(ge1, ginv, ge1ginv);
if(is_same(ge1ginv, e2)) {
return 1;
}
}
}
}
}
}
return 0;
}
int main(int argc, char *argv[]) {
if(argc<2) {
printf("usage: %s <filename>\n", argv[0]);
exit(-1);
}
FILE *infile = fopen(argv[1], "r");
int inputs[MAXC][6];
int rqinputs[MAXC][5];
char line[128];
int linenum = 0;
init_rep();
while ( fgets ( line, sizeof line, infile ) != NULL ) /* read a line */
{
linenum++;
char delims[] = ", ";
char *pc = NULL;
pc = strtok(line, delims);
int incount = 0;
while(pc != NULL) {
int el = atoi(pc);
inputs[linenum-1][incount] = el;
incount++;
pc = strtok( NULL, delims );
}
if(incount!=6) {
printf("ERROR in input file, incount= %d\n",
incount);
exit(-1);
}
for(int ii = 0; ii<5; ii++) {
rqinputs[linenum-1][ii] = inputs[linenum-1][ii];
}
//inputs contain the generator of the cyclic group that we need
}
int alreadyconj[MAXC];
for(int i=0; i<MAXC; i++) {
alreadyconj[i] = 0;
}
for(int i=0; i<linenum; i++) {
printf("i=%d\n", i); fflush(stdout);
if(!alreadyconj[i]) {
for(int j=i+1; j<linenum; j++) {
printf("j = %d\n", j);
// int retvals[5];
if(!alreadyconj[j]) {
if(is_conj(rqinputs[i], rqinputs[j])) {
alreadyconj[i] = 1;
alreadyconj[j] = 1;
}
}
}
char ofname[128];
snprintf(ofname, sizeof(ofname), "%s-op.out", argv[1]);
FILE *of = fopen(ofname, "a+");
fprintf(of, "%d, %d, %d, %d, %d\n", rqinputs[i][0], rqinputs[i][1], rqinputs[i][2], rqinputs[i][3], rqinputs[i][4]);
fclose(of);
}
}
}

65
code/gencyc.cpp Normal file
View File

@ -0,0 +1,65 @@
#include "rep.h"
int main(void) {
init_rep();
//test the inverse function
for(int i1 = 0; i1<18; i1++) {
for(int i2 = 0; i2<18; i2++) {
for(int i3 = 0; i3<18; i3++) {
for(int i4 = 0; i4<18; i4++) {
for(int j1 = 0; j1<24; j1++) {
//find the cyclic subgroup generated by this element
int el[5];
int elpow[5];
el[0] = i1; el[1] = i2; el[2] = i3; el[3] = i4; el[4] = j1;
int invt[5];
inverse(el, invt);
int idt[5];
perform_groupop(el, invt, idt);
int realid[5] = {0, 0, 0, 0, 0};
if(!is_same(idt, realid)) {
printf("element is "); print_groupelem(el);
printf(" invt is "); print_groupelem(invt);
print_groupelem(idt);
printf("ERROR in inv %d, %d, %d, %d, %d\n", i1, i2, i3, i4, j1);
exit(-1);
}
}
}
}
}
}
exit(0);
for(int i1 = 0; i1<18; i1++) {
for(int i2 = 0; i2<18; i2++) {
for(int i3 = 0; i3<18; i3++) {
for(int i4 = 0; i4<18; i4++) {
for(int j1 = 0; j1<24; j1++) {
//find the cyclic subgroup generated by this element
int el[5];
int elpow[5];
el[0] = i1; el[1] = i2; el[2] = i3; el[3] = i4; el[4] = j1;
elpow[0] = i1; elpow[1] = i2; elpow[2] = i3; elpow[3] = i4; elpow[4] = j1;
int cycsz = 0;
do {
perform_groupop(el, elpow, elpow);
cycsz++;
}while(!is_same(el, elpow));
printf("i1 = %2d, i2 = %2d, i3 = %2d, i4 = %2d, j1 = %2d, cycsz = %4d\r", i1, i2, i3, i4, j1, cycsz);
char ofilename[32];
snprintf(ofilename, sizeof(ofilename), "out-%07d.dat", cycsz);
fflush(stdout);
FILE *of = fopen(ofilename, "a+");
fprintf(of, "%d, %d, %d, %d, %d, %d\n", i1, i2, i3, i4, j1, cycsz);
fclose(of);
}
}
}
}
}
exit(0);
}

148
code/rep.cpp Normal file
View File

@ -0,0 +1,148 @@
#include "rep.h"
//every groupelem is an array of 5 inetegers.
//first 4 elements stand for each axis positions,
//last element stands for axis rotations
int is_valid_groupelem(int candidate[5]) {
for (int i=0; i<4; i++) {
if(candidate[i]>18 || candidate[i]<0) {
return 0;
}
}
if(candidate[4] >24 || candidate[4]<0) {
return 0;
}
return 1;
}
void print_groupelem(int el[5]) {
for(int i=0; i<5; i++) {
printf("(%d)", el[i]);
}
printf("\n");
}
// the following fn maps n\in{0.. fact(n)-1} to a permutation of {0..n-1}
void itoperm(int p, int arr[4]) {
int pt = p;
int filled[4] = {0,0,0,0};
arr[0] = pt%4;
filled[arr[0]] = 1;
pt = floor(pt/4);
for(int i=1; i<4; i++) {
int pp1 = pt%(4-i);
pt = floor(pt/(4-i));
int j = 0, k = 0;
while(k<pp1 || filled[j]==1) {
if(filled[j]==0) {
k++;
}
j++;
}
arr[i] = j;
filled[arr[i]] = 1;
}
}
int PERMARRAY[4][4][4][4];
void init_PERMARRAY() {
for (int i1 = 0; i1<4; i1++) {
for(int i2=0; i2<4; i2++) {
for(int i3=0; i3<4; i3++) {
for(int i4=0; i4<4; i4++) {
PERMARRAY[i1][i2][i3][i4] = -1;
}
}
}
}
for(int i=0; i<24; i++) {
int pa[4];
itoperm(i, pa);
PERMARRAY[pa[0]][pa[1]][pa[2]][pa[3]] = i;
}
}
// combination of two permutation/ groupop in permutation group
int perm_prod(int p1, int p2) {
int pa1[4], pa2[4];
itoperm(p1, pa1);
itoperm(p2, pa2);
int ra[4];
for(int i=0; i<4; i++) {
ra[i] = pa2[pa1[i]];
}
return PERMARRAY[ra[0]][ra[1]][ra[2]][ra[3]];
}
int is_same(int el1[5], int el2[5]) {
for(int i=0; i<5; i++) {
if(el1[i]!=el2[i]) {
return 0;
}
}
return 1;
}
//define the group op in our torus group
void perform_groupop(int el1[5], int el2[5], int result[5]) {
if(!is_valid_groupelem(el1) || !is_valid_groupelem(el2)) {
printf("CRITICAL ERROR at %s:%d\n", __FILE__, __LINE__);
exit(-1);
}
//now define the group operation
for(int i=0; i<4; i++) {
int resor = 0;
if((el1[i]<9 && el2[i]<9) || (el1[i]>8 && el2[i]>8)) {
resor = 0;
}
else {
resor = 1;
}
//orientation of res[i] is now determined.
int val1 = el1[i]%9;
int val2 = el2[i]%9;
int resval = (val1+val2)%9;
result[i] = (9*resor)+resval;
}
result[4] = perm_prod(el1[4], el2[4]);
if(!is_valid_groupelem(result)) {
printf("CRITICAL ERROR at %S:%d\n", __FILE__, __LINE__);
exit(-1);
}
}
int PERMINV_TABLE[24];
//store inverses of permutation group elems in a table
void init_PERMINV_TABLE() {
for(int i=0; i<24; i++) {
for(int j=0; j<24; j++) {
if(perm_prod(i, j)==0) {
PERMINV_TABLE[i] = j;
// PERMINV_TABLE[j] = i;
}
}
}
}
//inverse of an element in the torus group
void inverse(int el[5], int res[5]) {
for(int i=0; i<4; i++) {
int elor = 0;
if(el[i]>8) {
elor = 1;
}
res[i] = (9*elor) + (9-(el[i])%9)%9;
}
res[4] = PERMINV_TABLE[el[4]];
}
int fact(int n) {
if(n==1) return 1;
else return n*fact(n-1);
}
void init_rep() {
init_PERMARRAY();
init_PERMINV_TABLE();
}

17
code/rep.h Normal file
View File

@ -0,0 +1,17 @@
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
int is_valid_groupelem(int candidate[5]);
void print_groupelem(int el[5]);
void init_PERMARRAY();
int perm_prod(int p1, int p2) ;
int is_same(int el1[5], int el2[5]);
void perform_groupop(int el1[5], int el2[5], int result[5]);
void init_PERMINV_TABLE();
void inverse(int el[5], int res[5]);
int fact(int n);
void init_rep();

315
code/tabu4.c Normal file
View File

@ -0,0 +1,315 @@
/* tabu3.c tabu search program for clique finding
by Patric Ostergard, 15.05.2014 */
/* make -f makefile3 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "cliquer.h"
char infilename[128], outfilename[128];
#define MAXN 7000 /* order of graph */
int debug_level = 0;
extern long int lrand48();
int gr[MAXN][MAXN]; /* distance matrix */
int wt[MAXN]; /* orbit size */
int a60=0;
int d(int a,int b)
{
int c,e,i;
c = a^b;
e = 0;
for(i=0;i<16;i++)
if(((c>>i)&1)==1)
e++;
return e;
}
int err_message(int i)
{
printf("Usage: tabu d1 d2 threshold sim rounds seed (error %d)\n",i);
exit(1);
}
int main(argc,argv)
int argc;
char *argv[];
/* arguments: d1 d2 lambda sim rd tabu seed */
{
int n,k,m,total;
int ii[MAXN],jj[MAXN],nr,posit,sim,rd,rct=0;
int tabu[MAXN],pp,npos;
int absval,count,count2,p,size,temp,temp2;
int timeout;
int i,j,k2,tabo,seed;
int weight,weight2,ok,ant,ant2,mx,gsize;
int gtab[MAXN],htab[MAXN],value[MAXN],v2[MAXN];
int d1,d2,d3;
int high,threshold;
int max=0;
graph_t *g;
set_t st;
/* no timer */
clique_default_options->time_function = NULL;
if(argc<8)
err_message(10);
if((d1 = atoi(argv[1]))==0)
err_message(1);
if((d2 = atoi(argv[2]))==0)
err_message(2);
if((threshold = atoi(argv[3]))==0)
err_message(3);
if((sim = atoi(argv[4]))==0)
err_message(4);
if((rd = atoi(argv[5]))==0)
err_message(5);
seed = atoi(argv[6]);
strncpy(infilename, argv[7], sizeof(infilename));
if(argc>8) debug_level = atoi(argv[8]);
/* INIT graph (now: testing)*/
int pidx;
for(pidx = 0; pidx<8; pidx++) {
printf("%s ", argv[pidx]);
}
printf("\n");
#if 0
n = 2048;
for(i=0;i<n;i++) {
wt[i] = 1;
for(j=0;j<n;j++) {
gr[i][j] = d(i,j);
}
}
#endif
FILE *infile = fopen(infilename, "r");
if(fscanf(infile, "%d",&n)==EOF)
err_message(6); /* second integer not used (EOF instead) */
if(n==0) {
printf("0 rows in matrix. exiting\n"); exit(0);
}
for(i=0;i<n;i++) {
if(fscanf(infile, "%d",&wt[i])==EOF)
err_message(7);
for(j=0;j<n;j++)
if(fscanf(infile, "%d",&gr[i][j])==EOF)
err_message(8);
}
/* INITIALIZE */
again: /* start of outer loop */
weight = 0;
srand48(time(0)%100000 + seed++);
/* random vertices until n guesses does not go right */
ant = 0;
for(i=0;;i++) {
temp = 0;
anyo: if(temp>n) break;
value[i] = lrand48()%n;
for(j=0;j<i;j++)
if(gr[value[i]][value[j]]<d1) {
temp++;
goto anyo;
}
weight += wt[value[i]];
ant++;
}
i = 0;
/* complete clique in a greedy manner */
do {
ok = -1;
for(j=0;j<ant;j++)
if(gr[value[j]][i]<d1) {
ok = 0;
break;
}
if(ok) {
value[ant++] = i;
weight += wt[i];
}
i++;
} while(i<n);
if(debug_level > 0) {
printf("Initial weight/size: %d/%d\n",weight,ant);
}
int ct = 0;
timeout = 1;
for(;;) {
/* if(timeout%5==0)
printf("T: %d\n",timeout); */
if(timeout>1000) { /* now we are stuck, RESTART */
count2 = 0;
if(weight>max)
max = weight;
goto again;
}
high = -1;
nr = 0;
if(ct<100) { /* different nbrhood in the beginning, ct rounds */
d3 = d1;
ct++;
}
else
d3 = d2;
for(;;) {
i = (lrand48()%ant); /* remove vertex */
/* if(tabu[i]) continue; */
/* find vertices (indices) that are close to the removed one */
for(j=0;j<ant;j++)
htab[j] = 0;
ant2 = 0;
weight2 = 0;
for(j=0;j<ant;j++) {
if(gr[value[i]][value[j]]>d3) continue; /* order matters! */
htab[j] = -1;
ant2++;
weight2 += wt[value[j]];
}
/* printf("%d %d\n",ant2,weight2); for testing */
/* run clique search */
gsize = 0;
for(j=0;j<n;j++) {
/* if(j==value[i]) continue; */ /* don't include the specified vertex */
ok = -1;
for(k=0;k<ant;k++) {
if(htab[k]) continue;
if(gr[j][value[k]]<d1) {
ok = 0;
break;
}
}
if(ok) {
gtab[gsize++] = j;
}
}
if(gsize==0) continue;
g = graph_new(gsize);
for(j=0;j<gsize;j++) {
g->weights[j] = wt[gtab[j]];
for(k=j+1;k<gsize;k++)
if(gr[gtab[j]][gtab[k]]>=d1)
GRAPH_ADD_EDGE(g,j,k);
}
mx = clique_max_weight(g,clique_default_options);
graph_free(g);
total = mx-weight2;
if(total > high) {
nr = 1;
ii[0] = i;
jj[0] = mx;
high = total;
}
else if(total==high) {
ii[nr] = i;
jj[nr++] = mx;
}
break;
}
posit = (lrand48()%nr);
/* MAKE CHANGE */
for(j=0;j<ant;j++)
htab[j] = 0;
ant2 = 0;
weight2 = 0;
temp = 0;
for(j=0;j<ant;j++) {
if(gr[value[ii[posit]]][value[j]]>d3) { /* order matters */
v2[temp++] = value[j]; /* save */
continue;
}
htab[j] = -1;
ant2++;
weight2 += wt[value[j]];
}
/* run clique search */
gsize = 0;
for(j=0;j<n;j++) {
if(high==0&&j==value[ii[posit]]) continue; /* don't include specified vertex */
ok = -1;
for(k=0;k<ant;k++) {
if(htab[k]) continue;
if(gr[j][value[k]]<d1) {
ok = 0;
break;
}
}
if(ok) {
gtab[gsize++] = j;
}
}
if(gsize==0) {
timeout++;
continue;
}
g = graph_new(gsize);
for(j=0;j<gsize;j++) {
g->weights[j] = wt[gtab[j]];
for(k=j+1;k<gsize;k++)
if(gr[gtab[j]][gtab[k]]>=d1)
GRAPH_ADD_EDGE(g,j,k);
}
st = clique_find_single(g,jj[posit],jj[posit],FALSE,clique_default_options);
graph_free(g);
if(st==NULL) {
timeout++;
continue;
}
i = -1;
while ((i=set_return_next(st,i)) >= 0) {
v2[temp++] = gtab[i];
}
ant = temp;
weight += high;
for(i=0;i<ant;i++)
value[i] = v2[i];
/* for(i=0;i<ant;i++)
printf("%d ",value[i]);
printf("\n"); */
/* restart timout counter */
timeout = 1;
if(weight>=threshold) {
/* YES! */
printf("Yess!!! %d %d\n",ant,weight);
for(i=0;i<ant;i++)
printf("%d ",value[i]);
printf("\n");
snprintf(outfilename, sizeof(outfilename), "%s.yes", infilename);
FILE *ofile = fopen(outfilename, "w+");
fclose(ofile);
exit(0);
}
if(++count%10 == 0) {
if(debug_level >0) {
printf("%d/%d %d %d (max %d) %d/%d\n",count2,sim,ant,weight,max,a60,rct);
}
if(count2++==sim) {
count2 = 0;
if(weight>max)
max = weight;
if(weight>=threshold-1) a60++;
if(++rct < rd)
goto again;
exit(0);
}
}
}
}

BIN
shannon_oddcycles.pdf Normal file

Binary file not shown.