/
similarityTest2.c
228 lines (172 loc) · 5.43 KB
/
similarityTest2.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
/*
* file: similarityTest.c
*
* Testing the probablistic graph matching algorithm
* by rotating a set of artificial points and then calculating
* the similarity score for the edges
*
* Kevin Liu & Reid Delaney
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "graphMatching.c"
#include "utils.c"
#define PI 3.14159265
#define TEST_SIZE 5
//function returns a random float value in the interval [-1,1]
float randomfloat(){
//generate random float between 0 and 1
float r = (float)rand()/(float)RAND_MAX;
if(rand()%2 == 0)
return r;
else
return -r;
} //end of function
//function returns a random float value in the interval [0, 2PI]
float randomfloatAngle(){
//generate random float between 0 and 1
float r = fabs(randomfloat());
//scale to the 0 to 2PI range
r *= (2*PI);
return r;
} //end of function
//function takes in a set of points, rotates them and then returns the new set
void rotate(int size, float G1[size][2], float G2[size][2], float centerX, float centerY){
float theta = randomfloatAngle();
for(int i=0; i < size; i++){
G2[i][0] = ((float)cos((double)theta))*(G1[i][0] - centerX) - ((float)sin((double)theta))*(G1[i][1] - centerY) + centerX;
G2[i][1] = ((float)sin((double)theta))*(G1[i][0] - centerX) + ((float)cos((double)theta))*(G1[i][1] - centerY) + centerY;
}
} //end of function
void translate(int size, float G1[size][2], float G2[size][2], float centerX, float centerY){
float distortionX;
float distortionY;
distortionX = randomfloat();
distortionY = randomfloat();
for(int i=0; i < size; i++){
G2[i][0] = distortionX + G1[i][0];
G2[i][1] = distortionY + G1[i][1];
}
} //end of function
void graphDistortion(int size, float G1[size][2], float G2[size][2], float centerX, float centerY){
rotate(size, G1, G2, centerX, centerY);
translate(size, G2, G2, centerX, centerY);
} //end of function
//create a matrix of distances between nodes
void neighborDistances(int size, float G1[size][2], float neighbors[size][size], float adjacency[size][size]){
float distance = 0;
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
if(i == j)
//neighbors[i][j] = -INFINITY;
neighbors[i][j] = 0;
else if (adjacency[i][j] == 1){
distance = sqrt((G1[i][0] - G1[j][0])*(G1[i][0] - G1[j][0]) + (G1[i][1] - G1[j][1])*(G1[i][1] - G1[j][1]));
neighbors[i][j] = distance;
}
else
//neighbors[i][j] = -INFINITY;
neighbors[i][j] = 0;
}
}
}
//similarity function
void similarity(int size, int size2, int edges, float neighbors1[size][size], float neighbors2[size][size], float similarity[size2][size2]){
float simScore = 0;
int j = 0;
int i = 0;
for(int k = 1; k < size; k++){
for(int l = 0; l < k; l++){
for(int m = 1; m < size; m++){
for(int n = 0; n < m; n++){
if(neighbors1[k][l] == 0 || neighbors2[m][n] == 0)
similarity[i][j] = 0;
else
similarity[i][j] = exp(-(fabs(neighbors1[k][l] - neighbors2[m][n])));
j = (j+1) % size2;
}
}
i = (i+1);
}
}
}
void makeAdjacency(int size, float adjacent[size][size], int edges){
float temp;
float p = (float)edges / ((((float)size * (float)size)/2) - ((float)size/2));
// printf("probability = %f\n", p);
int edgeCount = 0;
//the adjacency matrix will be symmetric therefore its only neccessary to
//loop through half of the elements
//we assume there are no loops in this graph
while(edgeCount != edges){
for(int i = 1; i < size; i++){
for(int j = 0; j < i; j++){
temp = fabs(randomfloat());
if(temp < p){
if(adjacent[i][j] != 1){
adjacent[i][j] = 1;
adjacent[j][i] = 1;
edgeCount++;
if(edgeCount == edges)
return;
} //adjacent...
} //temp<p
} // j
} // i
} //while loop
} //end of function
void main(){
srand(time(0));
//create random set of points
int size = TEST_SIZE;
float G1[size][2];
for(int i=0; i < size; i++){
G1[i][0] = randomfloat()/10;
G1[i][1] = randomfloat()/10;
}
//printMatrix(size, 2, G1);
//create adjacency matrix to determine where edges exist
float adjacent[size][size];
zeros(size, size, adjacent);
int edges = 6;
makeAdjacency(size, adjacent, edges);
//printf("Adjacency Matrix\n");
//printMatrix(size, size, adjacent);
//copy original set of points for distortion
float G2[size][2];
for(int i=0; i < size; i++){
G2[i][0] = G1[i][0];
G2[i][1] = G1[i][1];
}
//distort the graph for testing purposes
graphDistortion(size, G1, G2, 0, 0);
//printMatrix(size, 2, G2);
//calculate the distances to each neighbor
float neighborDist1[size][size], neighborDist2[size][size];
neighborDistances(size, G1, neighborDist1, adjacent);
neighborDistances(size, G2, neighborDist2, adjacent);
//printf("neighbor Distances 1\n");
//printMatrix(size, size, neighborDist1);
//printf("neighbor distances 2\n");
//printMatrix(size, size, neighborDist2);
int size2;
size2 = (size*size)/2 - (size/2);
float simMatrix[size2][size2];
zeros(size2, size2, simMatrix);
//check to see if the graphs are the same
similarity(size, size2, edges, neighborDist1, neighborDist2, simMatrix);
//printf("Similarity Scores\n");
//printMatrix(size2, size2, simMatrix);
float X[size][size];
float Z[size][size];
float Y[size][size];
graphMatching(size,neighborDist1,size,neighborDist2, 0.001,size,X,Z,Y);
printf("X(hard):\n");
printMatrix(size, size, X);
printf("Z(soft):\n");
printMatrix(size, size, Z);
printf("Y(debug):\n");
printMatrix(size, size, Y);
}