1 /* ranlabg.c  version 1.2; B D McKay, Jun 20, 2015. */
2 
3 #define USAGE "ranlabg [-q] [-f#] [-m#] [-S#] [infile [outfile]]"
4 
5 #define HELPTEXT \
6 " Randomly relabel graphs.\n\
7 \n\
8     The output file has a header if and only if the input file does.\n\
9     Each graph is written in the same format as it is read.\n\
10 \n\
11     -f# Don't relabel the first # vertices.\n\
12     -m# Output # randomly labelled copies of each input (default 1).\n\
13     -S# Set random number seed (taken from clock otherwise).\n\
14 \n\
15     -q  Suppress auxiliary information.\n"
16 
17 /*************************************************************************/
18 
19 #include "gtools.h"
20 
21 /**************************************************************************/
22 
23 static void
ranrelabel(graph * g,int fixed,int m,int n,graph * h)24 ranrelabel(graph *g, int fixed, int m, int n, graph *h)
25 /* h := random labelling of g, fixing some initial vertices */
26 {
27     int i,j,w,imin;
28 #if MAXN
29     int perm[MAXN];
30 #else
31     DYNALLSTAT(int,perm,perm_sz);
32     DYNALLOC1(int,perm,perm_sz,n,"ranlabg");
33 #endif
34 
35     for (i = 0 ; i < n; ++i) perm[i] = i;
36 
37     if (fixed >= 0 && fixed < n) imin = fixed;
38     else                         imin = 0;
39 
40     for (i = imin; i < n-1; ++i)
41     {
42         j = i + KRAN(n-i);
43         w = perm[i];
44         perm[i] = perm[j];
45         perm[j] = w;
46     }
47 
48     updatecan(g,h,perm,0,m,n);
49 }
50 
51 /**************************************************************************/
52 
53 int
main(int argc,char * argv[])54 main(int argc, char *argv[])
55 {
56     char *infilename,*outfilename;
57     FILE *infile,*outfile;
58     boolean badargs,quiet,Sswitch,fswitch,mswitch;
59     int j,m,n,argnum,fixed;
60     int codetype,outcode;
61     graph *g;
62     nauty_counter nin;
63     int mult;
64     boolean digraph;
65     char *arg,sw;
66     double t;
67     long seed;
68 #if MAXN
69     graph h[MAXN*MAXM];
70 #else
71     DYNALLSTAT(graph,h,h_sz);
72 #endif
73 
74     HELP; PUTVERSION;
75 
76     infilename = outfilename = NULL;
77     mswitch = quiet = fswitch = Sswitch = FALSE;
78 
79     argnum = 0;
80     badargs = FALSE;
81 
82     for (j = 1; !badargs && j < argc; ++j)
83     {
84         arg = argv[j];
85         if (arg[0] == '-' && arg[1] != '\0')
86         {
87             ++arg;
88             while (*arg != '\0')
89             {
90                 sw = *arg++;
91                      SWBOOLEAN('q',quiet)
92                 else SWINT('f',fswitch,fixed,"ranlabg -f")
93                 else SWINT('m',mswitch,mult,"ranlabg -m")
94                 else SWLONG('S',Sswitch,seed,"ranlabg -S")
95                 else badargs = TRUE;
96             }
97         }
98         else
99         {
100             ++argnum;
101             if      (argnum == 1) infilename = arg;
102             else if (argnum == 2) outfilename = arg;
103             else                  badargs = TRUE;
104         }
105     }
106 
107     if (badargs)
108     {
109         fprintf(stderr,">E Usage: %s\n",USAGE);
110         GETHELP;
111         exit(1);
112     }
113 
114     if (!Sswitch) INITSEED;
115     if (!mswitch) mult = 1;
116     if (!fswitch) fixed = 0;
117 
118     if (!quiet)
119     {
120         fprintf(stderr,">A ranlabg");
121         fprintf(stderr," -S%ld",seed);
122         if (fswitch) fprintf(stderr,"f%d",fixed);
123         if (mswitch) fprintf(stderr,"m%d",mult);
124         if (argnum > 0) fprintf(stderr," %s",infilename);
125         if (argnum > 1) fprintf(stderr," %s",outfilename);
126         fprintf(stderr,"\n");
127         fflush(stderr);
128     }
129 
130     ran_init(seed);
131 
132     if (infilename && infilename[0] == '-') infilename = NULL;
133     infile = opengraphfile(infilename,&codetype,FALSE,1);
134     if (!infile) exit(1);
135     if (!infilename) infilename = "stdin";
136 
137     if (!outfilename || outfilename[0] == '-')
138     {
139         outfilename = "stdout";
140         outfile = stdout;
141     }
142     else if ((outfile = fopen(outfilename,"w")) == NULL)
143     {
144         fprintf(stderr,"Can't open output file %s\n",outfilename);
145         gt_abort(NULL);
146     }
147 
148     if (codetype&SPARSE6)       outcode = SPARSE6;
149     else if (codetype&DIGRAPH6) outcode = DIGRAPH6;
150     else                        outcode = GRAPH6;
151 
152     if (codetype&HAS_HEADER)
153     {
154         if (outcode == SPARSE6)       writeline(outfile,SPARSE6_HEADER);
155         else if (outcode == DIGRAPH6) writeline(outfile,DIGRAPH6_HEADER);
156         else                          writeline(outfile,GRAPH6_HEADER);
157     }
158 
159     nautil_check(WORDSIZE,1,1,NAUTYVERSIONID);
160 
161     nin = 0;
162     t = CPUTIME;
163     while (TRUE)
164     {
165         if ((g = readgg(infile,NULL,0,&m,&n,&digraph)) == NULL) break;
166         ++nin;
167 
168 #if !MAXN
169         DYNALLOC2(graph,h,h_sz,n,m,"ranlabg");
170 #endif
171         for (j = 0; j < mult; ++j)
172         {
173             ranrelabel(g,fixed,m,n,h);
174             if (readg_code == SPARSE6 || readg_code == INCSPARSE6)
175                 writes6(outfile,h,m,n);
176             else if (readg_code == GRAPH6)
177                 writeg6(outfile,h,m,n);
178             else
179                 writed6(outfile,h,m,n);
180         }
181         FREES(g);
182     }
183     t = CPUTIME - t;
184 
185     if (!quiet)
186         fprintf(stderr,
187             ">Z  " COUNTER_FMT
188                  " graphs relabeled from %s to %s; %3.2f sec.\n",
189                 nin,infilename,outfilename,t);
190 
191     exit(0);
192 }
193