-
Notifications
You must be signed in to change notification settings - Fork 0
/
random.c
299 lines (237 loc) · 7.46 KB
/
random.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
#include <stdio.h>
#include <stdlib.h>
#define MAXNODES 100
#define MAXEDGES 100*(100-1)
/* RANDOM Random Graph coloring algorithm C.C. McGeoch 2011
Runs I iterations of greedy with random vertex orders, reports best
coloring found.
Usage: random filename I s
filename: input file containing G, in format below.
i: number of iterations
s: optional random number seed
Input format:
n // first line: number of vertices, named [1..n]
x y z 0 // neighbors of v1, list ending in 0
a b c d e 0 // neighbors of v2, list ending in 0
...
x y 0 // neighbors of vn, list ending in 0
Note: Both edges (v,w) and (w,v) must be present in input
Lines after end are ignored as comments
Outputs:
To report performance indicators: #define REPORTSTATS 1
To report the coloring and counts: #define REPORTCOLORS 1
To see some intermediate values #define DEBUG 1
*/
#define REPORTSTATS 1
#define REPORTCOLORS 1
#define DEBUG 1
int numnodes=0; /* number of nodes in the graph */
int numedges=0;
int iterations=1; /* default */
/* algorithm statistics*/
int checkcount=0; /* number of colors checked */
int colorcount=0; /* to compute average colors looked at */
int maxcolor=0; /* max color assigned */
/* The graph is represented as an adjacency list in two arrays */
int edgex[MAXNODES+1]; /* index to neighbor array */
int ecount[MAXNODES+1]; /* number of neighbors this node */
int neighbor[MAXEDGES+1]; /* adjacent nodes */
int colorof[MAXNODES+1]; /* node colors */
int colorcounts[MAXNODES+1]; /* color distributions */
int bestcoloring[MAXNODES+1]; /* save best coloring */
int colordist[MAXNODES+1]; /* save best color distribution */
FILE *fp, *fopen();
/*--------------------------------------------------------------*/
/* getgraph: Read input file and build graph */
/* Input Format:
First line is integer number of nodes.
Then:
neighbors of v1, list ending with 0
neighbors of v2, list ending with 0
...
neighbors of vn, list ending with 0
Lines after n+1 inputs are ignored as comments.
*/
void getgraph()
{
int i;
int edgeindex = 1;
int edgecount;
int nodeval;
fscanf(fp,"%d", &numnodes); /* number of nodes in graph */
if (numnodes >MAXNODES) {
printf("too many nodes: recompile and try again\n");
exit(1);
}
for (i=1; i <= numnodes; i++) {
edgex[i] = edgeindex; /* where it starts in edge array */
fscanf(fp, "%d", &nodeval);
edgecount=0;
while (nodeval != 0) {
numedges++; /* total for accounting */
edgecount++; /* total neighbors this node */
neighbor[edgeindex++] = nodeval;
fscanf(fp, "%d", &nodeval);
} /* for each adjacent node */
ecount[i] = edgecount;
} /* for each node in graph */
} /* end getgraph */
/*--------------------------------------------------------------*/
/* check if this color is valid 0 no, 1 yes */
int checkcolorok(int thenode, int thecolor)
{
int ex = edgex[thenode]; /* index to neighbor list */
int edges = ecount[thenode]; /* number of neighbors */
int e=1;
while (e++ <= edges){
checkcount++;
if (colorof [neighbor[ex++] ] == thecolor) return 0; /* false */
}
return 1;
}
/*--------------------------------------------------------------*/
void colorit (int thenode, int thecolor)
{
colorof[thenode] = thecolor;
colorcounts[thecolor]++;
}
/*--------------------------------------------------------------*/
int colorgraph()
{
int v ;
int k;
for (k = 1; k <= numnodes; k++) colorcounts[k] = 0; /* color distribuion*/
for (v = 1; v <= numnodes; v++) {
for (k = 1; k <= numnodes; k++ ) {
colorcount++; /* number of colors examined*/
if (checkcolorok(v, k)) {
colorit(v, k);
if (k > maxcolor) maxcolor=k; /* overall */
break;
}
}//for k
}//for v
}
/*-----------------------------------------------------------*/
void printcolors()
{
int v;
for (v =1; v<= numnodes; v++) {
printf("%d %d\t", v, bestcoloring[v]);
if (v % 10 == 0) printf("\n");
}
}
/*-----------------------------------------------------------*/
void printgraph()
{
int src;
int ex;
int i;
for (src = 1; src <= numnodes; src++) {
ex = edgex[src];
printf("\n v %d: ", src);
for (i=1; i <= ecount[src]; i++) {
printf("%d \t", neighbor[ex++]);
}
}
printf("\n");
}
/*-----------------------------------------------------------*/
void randomcolor() {
int it, i, k,v, r, x;
int bestcolor=numnodes+1;
int tmp;
int pv;
int perm[numnodes+1]; /*initialize node permutation*/
for (i = 1; i <= numnodes;i++) perm[i] = i;
for (it = 0; it < iterations; it++) {
/* random permutation */
for (i = numnodes; i >=2; i--) {
r = (int) (drand48() * i )+1;
//printf("\n swap %d %d \n", i, r);
tmp= perm[i];
perm[i] = perm[r];
perm[r]=tmp;
}
#ifdef DEBUG
printf("\npermutation: ");
for (x=1; x <= numnodes; x++) printf("%d\t", perm[x]);
printf("\n");
#endif
maxcolor=0;
for (i = 1; i <= numnodes; i++) colorof[i] = 0; /* reinit coloring */
for (k = 1; k <= numnodes; k++) colorcounts[k] = 0; /* color distribution*/
/* color with random permutation */
for (v = 1; v <= numnodes; v++) {
for (k = 1; k <= numnodes; k++ ) {
colorcount++; /* total number of colors examined*/
pv = perm[v];
if (checkcolorok(pv, k)) {
colorit(pv, k);
#ifdef DEBUG
printf("(%d %d)\t", pv, k);
#endif
if (k > maxcolor) maxcolor=k;
break;
}//if
}//for k
}//for v
#ifdef REPORTSTATS
printf("\n iteration %d maxcolor %d \n", it, maxcolor);
printf("vertex color pairs:\n");
for (x = 1; x <=numnodes; x++) printf("%d %d \t", x, colorof[x]);
#endif
if (bestcolor > maxcolor) {/* save best */
bestcolor=maxcolor;
for (i = 1; i <=numnodes; i++) bestcoloring[i] = colorof[i];
for (i = 1; i <=numnodes; i++) colordist[i] = colorcounts[i];
}
}// for it
}//randomcolor
/*-----------------------------------------------------------*/
main(argc, argv)
int argc;
char *argv[];
{
if ((argc != 3) && (argc != 4)) {
printf("usage: random filename i s (or)\n");
printf(" random filename i \n");
exit(1);
}
// if ((fp = fopen(*++argv, "r")) == NULL) {
if ((fp = fopen(argv[1], "r")) == NULL) {
printf("color: cant open file %s\n", argv[1]);
exit(1);
}
iterations = atoi(argv[2]);
if (argc != 4)
srand48( (long) time(0) );
else
srand48((long) atoi(argv[3]));
getgraph();
randomcolor();
#ifdef REPORTCOLORS
printf("\nvertex color pairs:\n");
printcolors();
#endif
#ifdef REPORTSTATS
printf("\ngraph:\n");
printgraph();
//double avecolor= ((double) colorcount) / (double)numnodes;
printf("n m it compares maxcolor colorcount \n");
printf("%d %d %d %d %d %d \n",
numnodes, numedges, iterations,
checkcount, maxcolor, colorcount);
int i;
printf("color counts:\n"); /* of best coloring only*/
for (i=1; i <= numnodes; i++) {
printf("%d %d \t", i, colordist[i]);
if (i % 10 == 0) printf("\n");
if (colordist[i]==0){
--i;
break;
}
}
printf("\n%d colors were assigned by random\n", i);
#endif
} /* end main */