////////////// Main Functions ////////////// /*Run new offline (minDist) */ public static List <double> RunOfflineMinDist(List <double> inputData, int NLength, int maxEntry, int minEntry, int R, int D, ref int this_id_item, ref List <int> this_id_itemList, ref List <Rectangle> this_rectList, ref RTree <int> this_RTree, bool is_first_time) { int id_item = int.MinValue; RTree <int> rtree = new RTree <int>(maxEntry, minEntry); List <int> candidateList = new List <int>(); List <int> beginIndexInner = new List <int>(); List <int> indexOfLeafMBRS = new List <int>(); double best_so_far_dist = 0; int best_so_far_loc = -1; double nearest_neighbor_dist = 0; double dist = 0; bool break_to_outer_loop = false; bool[] is_skipped_at_p = new bool[inputData.Count]; for (int i = 0; i < inputData.Count; i++) { is_skipped_at_p[i] = false; } if (minEntry > maxEntry / 2) { MessageBox.Show("Requirement: MinNodePerEntry <= MaxNodePerEntry/2"); return(new List <double> { best_so_far_dist, best_so_far_loc }); } List <Rectangle> recList = new List <Rectangle>(); List <int> id_itemList = new List <int>(); for (int i = 0; i <= inputData.Count - NLength; i++) { List <double> subseq = inputData.GetRange(i, NLength); id_item++; Rectangle new_rec = new Rectangle(MathFuncs.PAA_Lower(subseq, D, R).ToArray(), MathFuncs.PAA_Upper(subseq, D, R).ToArray(), i); rtree.Add(new_rec, id_item); recList.Add(new_rec); id_itemList.Add(id_item); } Dictionary <int, Node <int> > nodeMap = rtree.getNodeMap(); List <Node <int> > leafNodes = nodeMap.Values.Where(node => node.level == 1).OrderBy(node => node.entryCount).ToList(); List <Rectangle> leafMBRs = leafNodes.Select(node => node.mbr).ToList(); // List rectangle of leaf nodes in order of list leafNodes for (int i = 0; i < leafNodes.Count; i++) { List <Rectangle> leafEntries = leafNodes[i].entries.Where(mbr => mbr != null).Select(mbr => mbr).ToList(); if (leafEntries.Count > 0) { int beginIndex = candidateList.Count; candidateList.AddRange(leafEntries.Select(mbr => mbr.getIndexSubSeq())); beginIndexInner.AddRange(Enumerable.Repeat(beginIndex, leafEntries.Count)); indexOfLeafMBRS.AddRange(Enumerable.Repeat(i, leafEntries.Count)); } } for (int i = 0; i < candidateList.Count; i++)//outer loop { int p = candidateList[i]; // rectangle of subseq in p postion if (is_skipped_at_p[p]) { //p was visited at inner loop before continue; } else { List <double> subseq_p = inputData.GetRange(p, NLength); //Rectangle p_rectangle = recList[p]; List <double> P_PAA = MathFuncs.PAA(subseq_p, D); nearest_neighbor_dist = Constants.INFINITE; List <bool> eliminatedMBR = new List <bool>(); for (int k = 0; k < leafMBRs.Count; k++) { eliminatedMBR.Add(false); } int indexMBRLeaf = -1; int num_leaf_skips = 0; for (int j = 0; j < candidateList.Count; j++)// inner loop { // int q = innerList[j]; int index_inner = (beginIndexInner[i] + j) % candidateList.Count; int q = candidateList[index_inner]; int index_MBRInnner = (beginIndexInner[i] + j) % candidateList.Count; int MBRInnner = indexOfLeafMBRS[index_MBRInnner]; if (indexMBRLeaf < MBRInnner)//the first entry of the next node ? { indexMBRLeaf++; /* Test: * if (indexMBRInnner[j] == MBRInnner) * Console.WriteLine("OK");*/ //calc minDist: //double minDist = MathFuncss.MINDIST(p_rectangle, leafMBRs[MBRInnner], (NLength / (double)(D))); double minDist = MathFuncs.MINDIST(P_PAA, leafMBRs[MBRInnner], (NLength / (double)(D))); //if (minDist_keo > minDist) //{ // Console.WriteLine("STOPPP"); // return; //} if (minDist >= nearest_neighbor_dist) { num_leaf_skips++; eliminatedMBR[MBRInnner] = true; continue;// pruned => skip to the next one } else { if (Math.Abs(p - q) < NLength) { continue;// self-match => skip to the next one } //calculate the Distance between p and q dist = MathFuncs.EuDistance(subseq_p, inputData.GetRange(q, NLength)); if (dist < best_so_far_dist) { //skip the element q at oute_loop, 'cuz if (p,q) is not a solution, neither is (q,p). is_skipped_at_p[q] = true; break_to_outer_loop = true; //break, to the next loop at outer_loop break; // break at inner_loop first } if (dist < nearest_neighbor_dist) { nearest_neighbor_dist = dist; } } } else // still the same node { if (eliminatedMBR[MBRInnner]) // can prune ? { continue; } else //do it normally { if (Math.Abs(p - q) < NLength) { continue;// self-match => skip to the next one } else { //calculate the Distance between p and q dist = MathFuncs.EuDistance(subseq_p, inputData.GetRange(q, NLength)); if (dist < best_so_far_dist) { //skip the element q at oute_loop, 'cuz if (p,q) is not a solution, neither is (q,p). is_skipped_at_p[q] = true; break_to_outer_loop = true; //break, to the next loop at outer_loop break; // break at inner_loop first } if (dist < nearest_neighbor_dist) { nearest_neighbor_dist = dist; } } } } //end ELSE } //end for inner loop //Console.WriteLine("num_leaf_skips="+ num_leaf_skips); if (break_to_outer_loop) { break_to_outer_loop = false; //reset continue; //go to the next p in outer loop } if (nearest_neighbor_dist > best_so_far_dist) { best_so_far_dist = nearest_neighbor_dist; best_so_far_loc = p; } } }//end outer loop if (is_first_time) { this_id_item = id_item; this_id_itemList = id_itemList; this_RTree = rtree; this_rectList = recList; } return(new List <double> { best_so_far_dist, best_so_far_loc }); }