/* Date: 1-27-2004 Author: Yong Zhang This program is based on graph6node.c. This program is used to find a weighted acyclic graph with 9 vertices that satisfies the following property: The distances from any two vertices are all distinct and belong to the set {1,...,36}. This program can be modified to solve the similar problem for a bigger input. This is the final version of the program. */ #include #include #define FALSE 0 #define TRUE 1 #define ERROR -2 #define DIM 9 /* the dimension of the matrix */ #define min(x,y) ((x) < (y) ? (x) : (y)) #define max(x,y) ((x) > (y) ? (x) : (y)) int compute_path(int A[DIM][DIM], int B[DIM][DIM]); int multiply_matrix(int A[DIM][DIM], int B[DIM][DIM]); int multiply_column(int col_a[DIM], int col_b[DIM]); int isvalid_matrix(int d[DIM][DIM]); int isequal_matrix(int A[DIM][DIM], int B[DIM][DIM]); int nextvalue_matrix(int d[DIM][DIM]); void assign_value(int d[DIM][DIM], int val, int location); void initiate_matrix(int d[DIM][DIM]); void copy_matrix(int A[DIM][DIM], int B[DIM][DIM]); void print_matrix(int d[DIM][DIM]); /* ********************************************************* * * * In addition to the above DIM Macro, the following * * needs to be modified when scale up the program. * * * ********************************************************* */ /* there are 36 paths in a graph of nine nodes */ int positions=36; /* Here is how we match the position and the ijth entry of the matrix. The upper triangular of the original matrix: (0,0) (0,1) (0,2) (0,3) (0,4) (0,5) (0,6) (0,7) (0,8) (1,1) (1,2) (1,3) (1,4) (1,5) (1,6) (1,7) (1,8) (2,2) (2,3) (2,4) (2,5) (2,6) (2,7) (2,8) (3,3) (3,4) (3,5) (3,6) (3,7) (3,8) (4,4) (4,5) (4,6) (4,7) (4,8) (5,5) (5,6) (5,7) (5,8) (6,6) (6,7) (6,8) (7,7) (7,8) (8,8) and the corresponding position: # 0 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 28 # 30 31 32 # 33 34 # 35 # */ /* the pos array serves as a lookup table which maps {0,...,35} to ji'th entry of the matrix */ int pos[36]={10,20,30,40,50,60,70,80,21, 31,41,51,61,71,81,32,42,52, 62,72,82,43,53,63,73,83,54, 64,74,84,65,75,85,76,86,87}; /* the num array was used by isvalid_matrix() */ int num[37]; /* m1 is our input matrix */ int m1[DIM][DIM]={ {0,1,-1,-1,-1,-1,-1,-1,-1}, {1,0,-1,-1,-1,-1,-1,-1,-1}, {-1,-1,0,-1,-1,-1,-1,-1,-1}, {-1,-1,-1,0,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,0,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,0,-1,-1,-1}, {-1,-1,-1,-1,-1,-1,0,-1,-1}, {-1,-1,-1,-1,-1,-1,-1,0,-1}, {-1,-1,-1,-1,-1,-1,-1,-1,0} }; /* in every loop we need to save the intermediate matrix */ int m2[DIM][DIM],m3[DIM][DIM],m4[DIM][DIM]; int m5[DIM][DIM], m6[DIM][DIM],m7[DIM][DIM]; int m8[DIM][DIM], result[DIM][DIM]; /* positions of eight edges*/ int p1,p2,p3,p4,p5,p6,p7,p8; /* weight of eight edges */ int v1,v2,v3,v4,v5,v6,v7,v8; /* for debug use */ int testval; int test[DIM][DIM]={ {0,1,-1,-1,-1,-1,-1,-1,-1}, {1,0,2,-1,-1,-1,-1,-1,-1}, {-1,2,0,3,4,-1,-1,-1,-1}, {-1,-1,3,0,-1,-1,-1,-1,-1}, {-1,-1,4,-1,0,5,6,-1,-1}, {-1,-1,-1,-1,5,0,-1,-1,8}, {-1,-1,-1,-1,6,-1,0,7,-1}, {-1,-1,-1,-1,-1,-1,7,0,-1}, {-1,-1,-1,-1,-1,8,-1,-1,0} }; int test2[DIM][DIM]={ {0,1,3,5,7,9,11,13,15}, {1,0,17,19,21,23,25,27,29}, {3,17,0,31,33,35,2,4,6}, {5,19,31,0,8,10,12,14,16}, {7,21,33,8,0,18,20,22,24}, {9,23,35,10,18,0,26,28,30}, {11,25,2,12,20,26,0,32,34}, {13,27,4,14,22,28,32,0,36}, {15,29,6,16,24,30,34,36,0} }; int main(int argc, char *argv[]) { int i; system("date"); /* for debug use, this is to test if compute_path() and isvalid() works print_matrix(test); compute_path(result, test); print_matrix(result); testval=isvalid_matrix(result); printf("%d\n", testval); testval=isvalid_matrix(test2); printf("%d\n", testval); return; */ /* initiate the num array */ for (i=0;i<37;i++) num[i]=0; /* assign the first edge and weight, in fact we don't need to use them, it is included in the input matrix, we state them here for the sake of clearance */ p1=0; v1=1; /* In fact, p2 only needs to be 1 or 15, v2 is 2 */ p2=1; v2=2; /* make a new copy of input matrix m1 */ copy_matrix(m2,m1); /* assign v2 to given location p2 */ assign_value(m2,v2,p2); /* when p2=1, v3 has to be 4 */ v3=4; for (p3=1;p3positions) return FALSE; /* if there are two path of the same weight, fail */ if (num[d[i][j]]!=0) return FALSE; /* otherwise put the weight in the array */ num[d[i][j]]=d[i][j]; } return TRUE; } /* This routine is used to check if the two given matrices are the same. */ int isequal_matrix(int A[DIM][DIM], int B[DIM][DIM]) { int i,j; /* since all matrices are symmetric, we will only check the upper triangular part. */ for (i=0; ipositions) return ERROR; /* if we find two paths of the same weight, fail */ else if (num[tmp[i][j]]!=0) return ERROR; else num[tmp[i][j]]=tmp[i][j]; } /* return the smallest integer that is not in the tmp matrix */ for (i=2;i