/* urbcsp.c -- generates uniform random binary constraint satisfaction problems */ #include #include /* function declarations */ float ran2(long *idnum); void StartCSP(int N, int K, int instance, long seed); void EndCSP(); void AddConstraint(int var1, int var2); void AddNogood(int val1, int val2); /********************************************************************* This file has 5 parts: 0. This introduction. 1. A main() function, which can be used to demonstrate MakeURBCSP(). 2. MakeURBCSP(). 3. ran2(), a random number generator. 4. The four functions StartCSP(), AddConstraint(), AddNogood(), and EndCSP(), which are called by MakeURBCSP(). The versions of these functions given here print out each instance, listing the incompatible value pairs of each constraint. You will need to replace these functions with versions that mesh with your system and data structures. *********************************************************************/ /********************************************************************* 1. A simple main() function which reads in command line parameters and generates CSPs. *********************************************************************/ int main(int argc, char* argv[]) { int N, D, C, T, I, i; long S; if (argc != 7) { printf("usage: urbcsp #vars #vals #constraints #nogoods seed " "instances\n"); return 0; } N = atoi(argv[1]); D = atoi(argv[2]); C = atoi(argv[3]); T = atoi(argv[4]); S = atoi(argv[5]); I = atoi(argv[6]); /* Note that to generate I instances, MakeURBCSP is called once with the supplied seed, and then I-1 times with 0 instead of the seed. */ if (!MakeURBCSP(N, D, C, T, S)) return 0; for (i=1; i N * (N - 1) / 2) { printf("MakeURBCSP: ***Illegal value for C: %d\n", C); return 0; } if (T < 1 || T > ((D * D) - 1)) { printf("MakeURBCSP: ***Illegal value for T: %d\n", T); return 0; } if (S == 0) /* no seed specified */ { if (instance == 0) /* first instance, really should supply */ seed = default_seed; /* a seed, but just in case . . . */ else seed = next_seed; /* this is the typical case */ } else /* seed specified */ seed = (S < 0 ? S : -S); /* so use it, but it must be negative */ StartCSP(N, D, instance, seed); ++instance; /* The program has to choose randomly and uniformly m values from n possibilities. It uses the following logic for both constraints and nogoods: 1. Let t[] be an array of the n possibilities 2. for i = 0 to m-1 3. r = random(i, n-1) ; random() returns an int in [i,n-1] 4. swap t[i] and t[r] 5. end-for At the end of the for loop, the elements from t[0] to t[m-1] are the m randomly selected elements. */ /* Create an array for each possible binary constraint. */ PossibleCTs = N * (N - 1) / 2; CTarray = (unsigned long*) malloc(PossibleCTs * 4); /* Create an array for each possible value pair. */ PossibleNGs = D * D; NGarray = (unsigned long*) malloc(PossibleNGs * 4); /* Initialize the CTarray. Each entry has one var in the high two bytes, and the other in the low two bytes. */ i=0; for (var1=0; var1<(N-1); ++var1) for (var2=var1+1; var2> 16), (int)(CTarray[c] & 0x0000FFFF)); /* For each constraint, select D illegal value pairs. */ /* Initialize the NGarray. */ for (i=0; i<(D*D); ++i) NGarray[i] = i; /* Select T nogoods. */ for (t=0; t= 0; j--) { /* load the shuffle table */ k = (*idum) / IQ1; *idum = IA1 * (*idum - k*IQ1) - k*IR1; if (*idum < 0) *idum += IM1; if (j < NTAB) iv[j] = *idum; } iy = iv[0]; idum2 = iv[NTAB/2]; /* Added for urbcsp so that a negative */ } /* idum always starts the same sequence. */ k = (*idum) / IQ1; *idum = IA1 * (*idum - k*IQ1) - k*IR1; if (*idum < 0) *idum += IM1; k = idum2/IQ2; idum2 = IA2 * (idum2 - k*IQ2) - k*IR2; if (idum2 < 0) idum2 += IM2; j = iy / NDIV; iy = iv[j] - idum2; iv[j] = *idum; if (iy < 1) iy += IMM1; if ((temp = AM * iy) > RNMX) return RNMX; /* avoid endpoint */ else return temp; } /********************************************************************* 4. An implementation of StartCSP, AddConstraint, AddNogood, and EndCSP which prints out the CSP, just listing incompatible value pairs. Each constraint starts one a new line, and the id-numbers of the variables appear before the colon. For instance, the output of urbcsp 10 5 5 3 1514849 10 begins Instance 0 uses seed -1514849 4 8: (4 4) (2 2) (0 3) (3 2) (4 1) 3 4: (3 4) (1 3) (3 0) (1 2) (0 2) 7 9: (2 4) (4 1) (0 2) (4 3) (3 1) *********************************************************************/ void StartCSP(int N, int D, int instance, long seed) { printf("\nInstance %d uses seed %d", instance, seed); } void AddConstraint(int var1, int var2) { printf("\n%3d %3d: ", var1, var2); } void AddNogood(int val1, int val2) { printf("(%d %d) ", val1, val2); } void EndCSP() { printf("\n"); }