|
|
@@ -0,0 +1,106 @@
|
|
|
+#include "MaxHeap.h"
|
|
|
+#include "utils.h"
|
|
|
+
|
|
|
+#define Point(i) (&(data[i * nFeatures]))
|
|
|
+
|
|
|
+
|
|
|
+pyWord findFarestPointTo(SearchParams params, pyReal * point) {
|
|
|
+ pyReal d, bestDist = 0.0;
|
|
|
+ pyWord i, bestIdx = 0 - 1;
|
|
|
+
|
|
|
+ for(i = 0 ; i < params->nPoints ; i ++ ) {
|
|
|
+ d = distSquared(point, Point(i));
|
|
|
+ if (d > bestDist) {
|
|
|
+ bestDist = d;
|
|
|
+ bestIdx = i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return bestIdx;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+void NeighborhoodHeuristic(const pyWord nbhSize, const pyWord nPoints, const pyWord nFeatures, const pyReal * data, pyWord * neighborhoods) {
|
|
|
+ SearchParams params = {
|
|
|
+ .nbhSize = nbhSize,
|
|
|
+ .nPoints = nPoints,
|
|
|
+ .nFeatures = nFeatures,
|
|
|
+ .data = data,
|
|
|
+ .neighborhoods = neighborhoods
|
|
|
+ };
|
|
|
+
|
|
|
+ int success = 0;
|
|
|
+ pyWord i, j;
|
|
|
+ pyReal d;
|
|
|
+ pyReal lineVector = NULL;
|
|
|
+ pyReal accu = NULL;
|
|
|
+
|
|
|
+ if(initNbhHeaps(¶ms)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ do {
|
|
|
+
|
|
|
+ const pyWord lineStartIdx = findFarestPointTo(params, Point(0));
|
|
|
+ if(lineStartIdx >= params->nPoints) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ pyReal * lineStartPoint = Point(lineStartIdx);
|
|
|
+ const pyWord lineEndIdx = findFarestPointTo(params, lineStartPoint);
|
|
|
+ pyReal * lineEndPoint = Point(lineEndIdx);
|
|
|
+
|
|
|
+
|
|
|
+ pyReal lineVector * = malloc(params->nFeatures * sizeof(pyReal));
|
|
|
+ if(!lineVector) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ lineVector = vecSub(nFeatures, lineEndPoint, lineStartPoint);
|
|
|
+ d = vecNorm(lineVector);
|
|
|
+ if(d == 0.0) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ vecScale(nFeatures, lineVector, 1.0 / d, lineVector);
|
|
|
+
|
|
|
+
|
|
|
+ pyReal accu * = malloc(params->nFeatures * sizeof(pyReal));
|
|
|
+ if(!accu) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Berechne alle Distanzen
|
|
|
+ for(i = 0; i < nPoints; i ++) {
|
|
|
+ const pyReal *x = Point(i);
|
|
|
+
|
|
|
+ vecSub(nFeatures, accu, x, lineStartPoint);
|
|
|
+ d = vecScalarProduct(nFeatures, lineVector, accu);
|
|
|
+ vecScale(nFeatures, accu, d, lineVector);
|
|
|
+ vecAdd(nFeatures, accu, accu, lineStartPoint);
|
|
|
+
|
|
|
+ const pyReal di1 = sqrt(distSquared(accu, lineStartPoint, nFeatures));
|
|
|
+ const pyReal di2 = sqrt(distSquared(accu, x, nFeatures));
|
|
|
+
|
|
|
+
|
|
|
+ for(j = i + 1; j < nPoints; j ++) {
|
|
|
+ const pyReal * y = Point(j);
|
|
|
+ d = distSquared(x, y, nFeatures);
|
|
|
+
|
|
|
+ maxHeap_insert(&(params.nbhHeaps.heaps[i]), j, d);
|
|
|
+ maxHeap_insert(&(params.nbhHeaps.heaps[j]), i, d);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } while(0);
|
|
|
+
|
|
|
+ if(lineVector) {
|
|
|
+ free(lineVector);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!success) {
|
|
|
+ nbhSearchBruteForce(¶ms);
|
|
|
+ }
|
|
|
+
|
|
|
+ freeNbhHeaps(¶ms);
|
|
|
+}
|
|
|
+
|
|
|
+
|