Skip to content

Commit 6f0f4fd

Browse files
authored
Merge pull request #6 from Sitaras/HyperCube2
Hypercube Neighbor Methods (NN,KNN,RangeSearch)
2 parents ecc233c + 6d8bc1e commit 6f0f4fd

File tree

10 files changed

+312
-3
lines changed

10 files changed

+312
-3
lines changed

Hypercube/hypercube.c

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@ int binaryToDecimal(int n)
4848

4949
return dec_value;
5050
}
51+
52+
int binaryArrayToDecimal(int s[],int size)
53+
{
54+
int n = 0;
55+
int i;
56+
57+
for (i = 0; i < size; ++i) {
58+
n <<= 1;
59+
n += s[i];
60+
}
61+
62+
return n;
63+
}
64+
5165
/* H FUNCTIONS*/
5266

5367
void generateH(h_function *hfun){
@@ -124,3 +138,178 @@ void deleteHyperCube(HyperCube hc){
124138
htDelete(hc->hypercube,1);
125139
free(hc);
126140
}
141+
142+
143+
void searchForHammingDistance(HyperCube hc,Vector v,int *v_index,int hammingDist,int startFrom,Vector *nearest,double *nearestDist,int *numOfSearched,int maxToSearch){
144+
if(hammingDist<=0){
145+
int new_index = binaryArrayToDecimal(v_index,k);
146+
printf("** HAMMING INDEX =%d\n",new_index);
147+
htFindNearestNeighborCube(hc->hypercube,new_index,v,nearest,nearestDist,d,numOfSearched,maxToSearch);
148+
return;
149+
}
150+
for(int i=startFrom;i<k;i++){
151+
v_index[i] = v_index[i]^1;
152+
searchForHammingDistance(hc,v,v_index,hammingDist-1,i+1,nearest,nearestDist,numOfSearched,maxToSearch);
153+
// search
154+
v_index[i] = v_index[i]^1;
155+
if((*numOfSearched)>=maxToSearch){
156+
break;
157+
}
158+
}
159+
}
160+
161+
void nearestNeigbor(HyperCube hc,Vector q,int hammingDist,int m){
162+
printf("ABOUT TO SEARCH NEAREST NEIGHBOR FOR : ");
163+
printVector(q);
164+
Vector nearest=NULL;
165+
double nearestDist=-1;
166+
int index[k];
167+
int searched = 0;
168+
for(int i=0;i<k;i++){
169+
int h_result = computeH(hc->h_functions[i],q);
170+
int f_result = computeF(hc->f_funs[i],h_result);
171+
index[i] = f_result;
172+
}
173+
int index_decimal = binaryArrayToDecimal(index,k);
174+
printf("** INITIAL INDEX =%d\n",index_decimal);
175+
htFindNearestNeighborCube(hc->hypercube,index_decimal,q,&nearest,&nearestDist,d,&searched,m);
176+
177+
for(int i=1;i<=hammingDist;i++){
178+
if(searched>=m){
179+
break;
180+
}
181+
searchForHammingDistance(hc,q,index,i,0,&nearest,&nearestDist,&searched,m);
182+
}
183+
184+
if(nearestDist>=0 && nearest!=NULL){
185+
printf("FOUND NEAREST NEIGHBOR ");
186+
printVector(nearest);
187+
printf("WITH DISTANCE = %f\n",nearestDist);
188+
}else{
189+
printf("- DID NOT FIND NEAREST NEIGHBOR\n");
190+
}
191+
printf("Checked: %d vectors\n",searched);
192+
}
193+
194+
void searchForHammingDistanceKNN(HyperCube hc,Vector v,int *v_index,int hammingDist,int startFrom,Vector *nearest,double *nearestDist,int *numOfSearched,int maxToSearch,int knn){
195+
if(hammingDist<=0){
196+
int new_index = binaryArrayToDecimal(v_index,k);
197+
printf("** HAMMING INDEX =%d\n",new_index);
198+
htKFindNearestNeighborsCube(hc->hypercube,new_index,v,nearest,nearestDist,d,knn,numOfSearched,maxToSearch);
199+
return;
200+
}
201+
for(int i=startFrom;i<k;i++){
202+
v_index[i] = v_index[i]^1;
203+
searchForHammingDistanceKNN(hc,v,v_index,hammingDist-1,i+1,nearest,nearestDist,numOfSearched,maxToSearch,knn);
204+
// search
205+
v_index[i] = v_index[i]^1;
206+
if((*numOfSearched)>=maxToSearch){
207+
break;
208+
}
209+
}
210+
}
211+
212+
void kNearestNeigbors(HyperCube hc,Vector q,int knn,int hammingDist,int m){
213+
printf("ABOUT TO SEARCH %d NEAREST NEIGHBORS FOR : ",knn);
214+
printVector(q);
215+
Vector nearest[knn];
216+
double knearestDists[knn];
217+
for (int i = 0; i < knn; i++){
218+
knearestDists[i]=-1;
219+
nearest[i]=NULL;
220+
}
221+
222+
int index[k];
223+
int searched = 0;
224+
for(int i=0;i<k;i++){
225+
int h_result = computeH(hc->h_functions[i],q);
226+
int f_result = computeF(hc->f_funs[i],h_result);
227+
index[i] = f_result;
228+
}
229+
int index_decimal = binaryArrayToDecimal(index,k);
230+
printf("** INITIAL INDEX =%d\n",index_decimal);
231+
htKFindNearestNeighborsCube(hc->hypercube,index_decimal,q,nearest,knearestDists,d,knn,&searched,m);
232+
233+
for(int i=1;i<=hammingDist;i++){
234+
if(searched>=m){
235+
break;
236+
}
237+
printf("--------*********--------------\n");
238+
searchForHammingDistanceKNN(hc,q,index,i,0,nearest,knearestDists,&searched,m,knn);
239+
}
240+
241+
int flag=1;
242+
for (int i = knn-1; i >= 0; i--){
243+
if (knearestDists[i] >= 0 && nearest[i] != NULL){
244+
printf("FOUND %d NEAREST NEIGHBOR: ",i);
245+
printVector(nearest[i]);
246+
printf("WITH DISTANCE = %f\n", knearestDists[i]);
247+
flag=0;
248+
}
249+
}
250+
if(flag){
251+
printf("- DID NOT FIND NEAREST NEIGHBOR\n");
252+
}
253+
}
254+
255+
256+
257+
void searchForHammingDistanceRadius(HyperCube hc,Vector v,int *v_index,int hammingDist,int startFrom,HashTable vecsInRadius,int *numOfSearched,int maxToSearch,int radius){
258+
if(hammingDist<=0){
259+
int new_index = binaryArrayToDecimal(v_index,k);
260+
printf("** HAMMING INDEX =%d\n",new_index);
261+
htFindNeighborsInRadiusCube(hc->hypercube,new_index,vecsInRadius,v,d,radius,numOfSearched,maxToSearch);
262+
return;
263+
}
264+
for(int i=startFrom;i<k;i++){
265+
v_index[i] = v_index[i]^1;
266+
searchForHammingDistanceRadius(hc,v,v_index,hammingDist-1,i+1,vecsInRadius,numOfSearched,maxToSearch,radius);
267+
// search
268+
v_index[i] = v_index[i]^1;
269+
if((*numOfSearched)>=maxToSearch){
270+
break;
271+
}
272+
}
273+
}
274+
275+
276+
void radiusNeigbor(HyperCube hc,Vector q,double radius,int hammingDist,int m){
277+
printf("ABOUT TO SEARCH FOR NEIGHBORS INSIDE RANGE : %f\n",radius);
278+
HashTable vecsInRadius = htInitialize(100); // TODO: CHANGE SIZE
279+
280+
int index[k];
281+
int searched = 0;
282+
for(int i=0;i<k;i++){
283+
int h_result = computeH(hc->h_functions[i],q);
284+
int f_result = computeF(hc->f_funs[i],h_result);
285+
index[i] = f_result;
286+
}
287+
int index_decimal = binaryArrayToDecimal(index,k);
288+
printf("** INITIAL INDEX =%d\n",index_decimal);
289+
htFindNeighborsInRadiusCube(hc->hypercube,index_decimal,vecsInRadius,q,d,radius,&searched,m);
290+
291+
for(int i=1;i<=hammingDist;i++){
292+
if(searched>=m){
293+
break;
294+
}
295+
printf("--------*********--------------\n");
296+
searchForHammingDistanceRadius(hc,q,index,i,0,vecsInRadius,&searched,m,radius);
297+
}
298+
299+
htRangePrint(vecsInRadius,q,d);
300+
301+
htDelete(vecsInRadius,0);
302+
}
303+
304+
305+
306+
307+
308+
309+
310+
311+
312+
313+
314+
315+
///

Hypercube/hypercube.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,10 @@ void printHyperCube(HyperCube );
1111

1212
void deleteHyperCube(HyperCube );
1313

14+
void nearestNeigbor(HyperCube ,Vector ,int ,int );
15+
16+
void kNearestNeigbors(HyperCube ,Vector ,int ,int ,int );
17+
18+
void radiusNeigbor(HyperCube ,Vector ,double ,int ,int );
19+
1420
#endif

Hypercube/hypercube.h.gch

0 Bytes
Binary file not shown.

hashTable/hashTable.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ int hashFunction(const HashTable ht,Vector v,int d){ /* Hash function only used
5858
int c;
5959
for(int i=0;i<d;i++){
6060
c = coords[i];
61-
hash = ((hash * 33) + hash) + c; /* hash * 33 + c */
61+
hash = (int)(((hash * 33) + hash) + c)% ht->buckets; /* hash * 33 + c */
6262
}
6363
return (((int)hash) % ht->buckets);
6464
}
@@ -113,3 +113,16 @@ void htKFindNearestNeighbors(HashTable ht,int index,Vector q,Vector *nearest,dou
113113
void htFindNeighborsInRadius(HashTable ht,int index,HashTable storeNeighbors,Vector q,int d,int id,int radius){
114114
listFindNeighborsInRadius(ht->table[index].head,storeNeighbors,q,d,id,radius);
115115
}
116+
117+
118+
void htFindNearestNeighborCube(HashTable ht,int index,Vector q,Vector *nearest,double *nearestDist,int d,int *numOfSearched,int maxToSearch){
119+
listFindNearestNeighborCube(ht->table[index].head,q,nearest,nearestDist,d,numOfSearched,maxToSearch);
120+
}
121+
122+
void htKFindNearestNeighborsCube(HashTable ht,int index,Vector q,Vector *nearest,double *nearestDist,int d,int k,int *numOfSearched,int maxToSearch){
123+
listFindKNearestNeighborsCube(ht->table[index].head, q, nearest, nearestDist, d,k,numOfSearched,maxToSearch);
124+
}
125+
126+
void htFindNeighborsInRadiusCube(HashTable ht,int index,HashTable storeNeighbors,Vector q,int d,int radius,int *numOfSearched,int maxToSearch){
127+
listFindNeighborsInRadiusCube(ht->table[index].head,storeNeighbors,q,d,radius,numOfSearched,maxToSearch);
128+
}

hashTable/hashTable.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@ void htKFindNearestNeighbors(HashTable, int, Vector, Vector *, double *, int ,in
1919
void htFindNeighborsInRadius(HashTable ,int ,HashTable ,Vector ,int ,int ,int );
2020
void htRangeInsert(HashTable , Vector ,int ,int );
2121

22+
void htFindNearestNeighborCube(HashTable ,int ,Vector ,Vector *,double *,int ,int *,int );
23+
void htKFindNearestNeighborsCube(HashTable ,int ,Vector ,Vector *,double *,int ,int ,int *,int );
24+
void htFindNeighborsInRadiusCube(HashTable ,int ,HashTable ,Vector ,int ,int ,int *,int );
25+
2226
#endif

hashTable/hashTable.h.gch

4 KB
Binary file not shown.

hashTable/hashTableList/hashTableList.c

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void listPrint(List list){
9797
}
9898
}
9999
void listRangePrint(List list,Vector q,int d){
100-
if(list==NULL){ return;}
100+
if(list==NULL){ return;}
101101
List temp=list;
102102
while(temp!=NULL){
103103
printf("Found vector: ");
@@ -142,6 +142,23 @@ void listFindNearestNeighbor(List list,Vector q,Vector *nearest,double *nearestD
142142
}
143143
}
144144

145+
void listFindNearestNeighborCube(List list,Vector q,Vector *nearest,double *nearestDist,int d,int *numOfSearched,int maxToSearch){
146+
if(list==NULL){ return;}
147+
List temp=list;
148+
while(temp!=NULL){
149+
if((*numOfSearched)>=maxToSearch){
150+
return;
151+
}
152+
double dist = distance_metric(temp->v,q,d);
153+
if(dist<(*nearestDist) || (*nearestDist)<0){
154+
(*nearestDist) = dist;
155+
(*nearest) = temp->v;
156+
}
157+
(*numOfSearched)+=1;
158+
temp=temp->next;
159+
}
160+
}
161+
145162
void swapDoubles(double *xp, double *yp)
146163
{
147164
double temp = *xp;
@@ -267,6 +284,58 @@ void listFindKNearestNeighbors(List list,Vector q,Vector *nearest,double *neares
267284
}
268285
}
269286

287+
void listFindKNearestNeighborsCube(List list,Vector q,Vector *nearest,double *nearestDist,int d,int k,int *numOfSearched,int maxToSearch){
288+
if(list==NULL){ return;}
289+
List temp=list;
290+
int filled=0;
291+
while(temp!=NULL){
292+
if((*numOfSearched)>=maxToSearch){
293+
return;
294+
}
295+
int flag = 1;
296+
int eq = 0;
297+
int added=0;
298+
double dist = distance_metric(temp->v,q,d);
299+
(*numOfSearched) += 1;
300+
301+
int index=binarySearch(nearestDist,0,k-1,dist);
302+
if(index!=-1 && nearest[index] != NULL && compareVectors(nearest[index], temp->v)){
303+
eq = 1;
304+
}
305+
if (eq){
306+
temp = temp->next;
307+
continue;
308+
}
309+
if(!filled)
310+
for (int i = 0; i < k; i++){
311+
if(nearestDist[i]<0){
312+
flag=0;
313+
added=1;
314+
nearestDist[i]=dist;
315+
nearest[i]=temp->v;
316+
break;
317+
}
318+
}
319+
320+
if (flag){
321+
filled=1;
322+
if(dist<nearestDist[0]){
323+
added = 1;
324+
nearestDist[0] = dist;
325+
nearest[0] = temp->v;
326+
}
327+
}
328+
if(added)
329+
quickSort(nearestDist, nearest,0, k-1);
330+
temp = temp->next;
331+
}
332+
}
333+
334+
335+
336+
337+
338+
270339
void listFindNeighborsInRadius(List list,HashTable storeNeighbors,Vector q,int d,int id,int radius){
271340
if(list==NULL){ return;}
272341
List temp=list;
@@ -280,3 +349,19 @@ void listFindNeighborsInRadius(List list,HashTable storeNeighbors,Vector q,int d
280349
temp=temp->next;
281350
}
282351
}
352+
353+
void listFindNeighborsInRadiusCube(List list,HashTable storeNeighbors,Vector q,int d,int radius,int *numOfSearched,int maxToSearch){
354+
if(list==NULL){ return;}
355+
List temp=list;
356+
while(temp!=NULL){
357+
if((*numOfSearched)>=maxToSearch){
358+
return;
359+
}
360+
double dist = distance_metric(temp->v,q,d);
361+
(*numOfSearched) += 1;
362+
if(dist<=radius){
363+
htRangeInsert(storeNeighbors,temp->v,temp->vector_ID,d);
364+
}
365+
temp=temp->next;
366+
}
367+
}

hashTable/hashTableList/hashTableList.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ List listDelete(List ,int );
1717

1818
void listFindNearestNeighbor(List ,Vector ,Vector *,double *,int ,int );
1919
void listFindKNearestNeighbors(List, Vector, Vector *, double *, int,int ,int );
20-
2120
void listFindNeighborsInRadius(List ,HashTable ,Vector ,int ,int ,int );
21+
22+
void listFindNearestNeighborCube(List ,Vector ,Vector *,double *,int ,int *,int );
23+
void listFindKNearestNeighborsCube(List ,Vector ,Vector *,double *,int ,int ,int *,int );
24+
void listFindNeighborsInRadiusCube(List ,HashTable ,Vector ,int ,int ,int *,int );
2225
#endif
4 KB
Binary file not shown.

mainCube.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ int main(int argc, char *argv[]) {
133133

134134
printHyperCube(hc);
135135

136+
double vec[6] = {21, 3, 3, 18, 25, 11};
137+
Vector vecTmp=initVector(vec);
138+
139+
nearestNeigbor(hc,vecTmp,1,4);
140+
printf("================================================\n");
141+
kNearestNeigbors(hc,vecTmp,3,3,100);
142+
printf("================================================\n");
143+
radiusNeigbor(hc,vecTmp,25,2,100);
144+
136145
// printOptions(); // just printing the commands options for the user
137146
//
138147
//

0 commit comments

Comments
 (0)