/* makeQAPrl.cc (C) Joshua Knowles 27/3/2002 Compile: gcc makeQAPrl.cc -o makeQAPrl -lm Usage: ./makeQAPrl -h ****and the command line parameters will be explained**** INTRODUCTION This program generates symmetric multi-objective Quadratic Assignment Problems with one distance matrix and multiple flow matrices. Details of the generator can be found in: @TechReport{Knowles2002EMO, author = {Joshua Knowles and David Corne}, title = {Instance Generators and Test Suites for the Multiobjective Quadratic Assignment Problem}, institution = {IRIDIA}, number = {TR/IRIDIA/2002-25}, year = {2002}, note = {(Submitted to the {\em 2003 Evolutionary Multi-criterion Optimization Conference (EMO-2003))} } and we have done some simple landscape analysis in: @InProceedings{Knowles2002HIS, author = {Joshua Knowles and David Corne}, title = {Towards {L}andscape {A}nalyses to {I}nform the {D}esign of {H}ybrid {L}ocal {S}earch for the {M}ultiobjective {Q}uadratic {A}ssignment {P}roblem}, booktitle = {Proceedings of the Second International Conference on Hybrid Intelligent Systems (HIS 2002)}, year = {2002}, publisher = {IOS Press}, note = {(To appear, but available from http://iridia.ulb.ac.be/~jknowles/publications.html )} } STRUCTURED INSTANCES The distance and flow matrices generated have structured, "real-world-like" entries and correlations can be set between corresponding entries in the two or more flow matrices. The amount of "overlap" between the flow matrices can also be controlled. The generator follows procedures for making non-uniform QAP problems outlined in: E. D. Taillard. Comparison of iterative searches for the quadratic assignment problem. Location Science, 3:87--105, 1995. DISTANCE MATRIX The distance matrix entries are the Euclidean distances between points in the plane. The points are randomly distributed in small circular regions, with these regions distributed in a larger circle. The size and number of the small and larger circles can be controlled by the command line parameters R_max, r_max, and N_max. The points are generated using the procedure: Choose Theta randomly, uniformly between 0 and 2 * PI Choose R randomly, uniformly between 0 and R_max Choose N randomly, uniformly between 1 and N_max Repeat N times: Choose theta randomly, uniformly between 0 and 2 * PI Choose r randomly, uniformly between 0 and r_max. The Euclidean coordinates of the next generated point are: (R cos Theta + r cos theta, R sin Theta + r sin theta) FIRST FLOW MATRIX The flow entries are non-uniform random values, controlled by two parameters, A and B, with A < B, and B > 0. Let X be a random variable uniformly distributed between 0 and 1. Then a flow entry is given by (int)(10^((B-A)*X + A)) -- Equation 1. With negative vaues of A the flow matrix is sparse, ie it contains a number of zero entries. The non-zero entries are non-uniformly distributed. OTHER FLOW MATRICES The number of flow matrices is controlled by the command line parameter, k. With k >= 2, a multiobjective QAP problem is generated with k flow matrices. The entries in the nth matrix (k>=n>=2) are generated using the same equation as above but the random variable X is correlated with the value of X used in the corresponding entry in the first flow matrix. Correlations between -1 and 1 can be set between the first and each of the additional flow matrices using the command line parameters. A degree of overlap between the matrices can also be specified. The overlap parameter is set between 0 and 1. It controls the fraction of entries in the nth flow matrix that are correlated with the corresponding entries in the 1st flow matrix. With the overlap parameter set to zero, a random un-correlated value, calculated using Equation 1, will be placed in each entry of the nth flow matrix that corresponds to a zero entry in the first flow matrix. Similarly, a zero will be placed in each entry of the nth flow matrix that corresponds to a non-zero value in the first flow matrix. Thus there is no overlap between the flows of the first and nth matrix. With the overlap parameter set to 1 all the flows are correlated. With the overlap set to intermediate values some of the flows will overlap and others will not. Here is a typical command line for the generator: ./makeQAPrl -n 30 -k 3 -M 1000 -m 10 -K 4 -A -3 -B 4 -c1 0.5 -c2 -0.8 -ov 0.7 -- ** Please contact me - Joshua Knowles - if you have any comments, suggestions or questions regarding this program or multicriteria QAP problems. My email address is jknowles@ulb.ac.be This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. The GNU General Public License is available at: http://www.gnu.org/copyleft/gpl.html or by writing to: The Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #define MAX_N 500 // max facilities - change as required #define MAX_K 5 // max number of objectives i.e. flow matrices - change as required #define VERBOSE 1 #define PI 3.141592654 #define RN ran0(&seed) /* Random number generator */ /* Copyright Numerical Recipes in C */ #define IA 16807 #define IM 2147483647 #define AM (1.0/IM) #define IQ 127773 #define IR 2836 #define MASK 123459876 double ran0(long *idum); /* End copyright Numerical Recipes in C */ void print_output(); void point_in_plane(const int M, const int K, const int m, const int max_points); void print_dominance(); double correl_val(double v, double c); long seed; long init_seed; int n_fac = 30; // number of facilities/locations in the QAP int n_k = 2; // number of objectives double corr[MAX_K]; // correlations between 1st and each other objective int max_flow; int max_dist; int M=0; int K=1; int m=100; int A=-5; int B=5; double overlap=1.0; int d_matrix[MAX_N][MAX_N]; int f_matrix[MAX_K][MAX_N][MAX_N]; int XYpos[MAX_N][2]; int main(int argc, char *argv[]) { int i,j,k; double r1,r2,val; int f1,fk; int d1; seed = 23453464; if(argc==2) { if(strcmp("-h", argv[1])==0) { printf("You have requested help with the -h argument. \nOther optional parameters are: -n positive integer : number of facilities/locations -k positive integer : number of objectives -c1 real in the interval [-1,1]: correlation between objectives 1 and 2 -c2 real in the interval [-1,1]: correlation between objectives 1 and 3 -c3 real in the interval [-1,1]: correlation between objectives 1 and 4 -c4 real in the interval [-1,1]: correlation between objectives 1 and 5 -ov real in the interval [0:1]: sets the fraction of flows that are correlated -A integer : flow control parameter (must be set less than B; negative values cause a sparse matrix) -B positive integer : flow control parameter -K positive integer : maximum number of points in a small cluster -M non-negative integer : radius of large clusters -m non-negative integer : radius of small clusters -s positive long : random seed Default values are: n = 30, k = 2, c1 = 0, c2 = 0, c3 = 0, c4 = 0, A = -5, B = 5, m = 100, M = 0, K = 1, ov = 0.7, s = 23453464\n"); exit(1); } } if((argc>2)&&(argc%2==1)) { // printf("argc = %d\n", argc); for(i=1;iMAX_N) { printf("Number of facilities too high. Maximum is currently set at %d\n", MAX_N); exit(1); } for(k=1;k1.0)||(corr[k]<-1.0)) { fprintf(stderr, "Correlations must be in the interval [-1,1]\n"); exit(1); } } if(n_k>MAX_K) { fprintf(stderr,"number of objectives too high. Maximum is currently set at %d\n", MAX_K); exit(1); } if(B<0) { fprintf(stderr,"B must be a positive integer.\n"); exit(1); } if(A>=B) { fprintf(stderr,"A must be less than B.\n"); exit(1); } if(K<0) { fprintf(stderr,"K must be a positive integer.\n"); exit(1); } if(M<0) { fprintf(stderr,"M must be a non-negative integer\n"); exit(1); } if(m<0) { fprintf(stderr,"m must be a non-negative integer\n"); exit(1); } point_in_plane(M, K, m, n_fac); // for(i=0;imax_dist) max_dist=d1; } max_flow=0; for(i=0;imax_flow) max_flow=f1; for(k=1;koverlap) // if we want an un-correlated value { if(f_matrix[0][i][j]==0) { r2=RN*B; fk = (int)(pow(10,r2)); f_matrix[k][i][j] = f_matrix[k][j][i] = fk; } else { fk=0; f_matrix[k][i][j] = f_matrix[k][j][i] = fk; } } else { r2 = RN; if(corr[k]>=0) { //val = corr[k]*r1+(1.0-corr[k])*r2; val = correl_val(r1,corr[k]); //fprintf(stderr, "val=%lf\n", val); } else { val = 1.0-correl_val(r1,-corr[k]); //fprintf(stderr, "val=%lf\n", val); } fk = (int)(pow(10,((B-A)*val+A))); f_matrix[k][i][j]=f_matrix[k][j][i]=fk; } } if(fk>max_flow) max_flow=fk; // fprintf(stderr,"f1 = %d, fk=%d, max_flow=%d\n",f1, fk, max_flow); } } } print_output(); } double correl_val(double v, double c) { double q,w,diff,r,p=0.5; if(c==1) return(v); if(c==0) return(RN); do { q= RN; diff =q-v; if(diff<0) diff*=-1; w = exp(-(diff*diff)/(2.0*(1.0-pow(c,p))*(1.0-pow(c,p))))/(1.0-pow(c,p))*2.506; r=RN*1.0/(1.0-pow(c,p))*2.506; }while(w