Changeset 14767 for branches/TSNE/HeuristicLab.Algorithms.DataAnalysis
- Timestamp:
- 03/19/17 18:47:00 (7 years ago)
- Location:
- branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4
- Files:
-
- 6 deleted
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj
r14682 r14767 331 331 <Compile Include="Interfaces\ISupportVectorMachineSolution.cs" /> 332 332 <Compile Include="Interfaces\IDataAnalysisAlgorithm.cs" /> 333 <Compile Include="Interfaces\TSNEInterfaces\IKernelFunction.cs" /> 333 <Compile Include="Interfaces\TSNEInterfaces\ICell.cs" /> 334 <Compile Include="Interfaces\TSNEInterfaces\IDataPoint.cs" /> 335 <Compile Include="Interfaces\TSNEInterfaces\IDistance.cs" /> 336 <Compile Include="Interfaces\TSNEInterfaces\ISPTree.cs" /> 337 <Compile Include="Interfaces\TSNEInterfaces\IVPTree.cs" /> 334 338 <Compile Include="kMeans\KMeansClustering.cs" /> 335 339 <Compile Include="kMeans\KMeansClusteringModel.cs" /> … … 416 420 <Compile Include="TSNE\Cell.cs" /> 417 421 <Compile Include="TSNE\DataPoint.cs" /> 418 <Compile Include="TSNE\Distances\FuctionalDistance.cs" />419 422 <Compile Include="TSNE\Distances\DistanceBase.cs" /> 420 423 <Compile Include="TSNE\Distances\DataPointDistance.cs" /> 421 424 <Compile Include="TSNE\Distances\EuclidianDistance.cs" /> 422 <Compile Include="Interfaces\TSNEInterfaces\IDistance.cs" />423 425 <Compile Include="TSNE\Distances\InnerProductDistance.cs" /> 424 426 <Compile Include="TSNE\TSNEAnalysis.cs" /> … … 426 428 <Compile Include="TSNE\SPtree.cs" /> 427 429 <Compile Include="TSNE\TSNE.cs" /> 428 <Compile Include="Interfaces\TSNEInterfaces\ICell.cs" />429 <Compile Include="Interfaces\TSNEInterfaces\IDataPoint.cs" />430 <Compile Include="Interfaces\TSNEInterfaces\IHeap.cs" />431 <Compile Include="Interfaces\TSNEInterfaces\ISPTree.cs" />432 <Compile Include="Interfaces\TSNEInterfaces\ITSNE.cs" />433 <Compile Include="Interfaces\TSNEInterfaces\IVPTree.cs" />434 430 <Compile Include="TSNE\TSNEUtils.cs" /> 435 431 <Compile Include="TSNE\VPTree.cs" /> -
branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/TSNEInterfaces/IDistance.cs
r14512 r14767 26 26 public interface IDistance<in T> : IItem { 27 27 /// <summary> 28 /// Calculates a distance measure between two arbitrary Vectors. The distance value d is29 /// 1.) positive d(x,y)>=028 /// Calculates a distance measure between two objects. 29 /// 1.) non-negative d(x,y) >= 0 30 30 /// 2.) symmetric d(x,y) = d(y,x) 31 /// 3.) zero-reflexive d(x,x) = 0;31 /// 3.) zero-reflexive d(x,x) = 0; 32 32 /// </summary> 33 /// <param name="a">an array representing point x</param>34 /// <param name="b">>an array representing point y</param>35 33 /// <returns>d(x,y)</returns> 36 double Get(T a, T b); 37 38 /// <summary> 39 /// Calculates the correct kernel measure if it is smaller than threshold, but any value greater then threshold if the correct distance is greater. 40 /// This is for performace only 41 /// </summary> 42 /// <param name="a"></param> 43 /// <param name="b"></param> 44 /// <param name="threshold"></param> 45 /// <returns></returns> 46 double Get(T a, T b, double threshold); 34 double Get(T x, T y); 47 35 48 36 /// <summary> -
branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4/TSNE/DataPoint.cs
r14518 r14767 88 88 #endregion 89 89 90 91 92 90 } 93 91 } -
branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4/TSNE/Distances/DataPointDistance.cs
r14512 r14767 49 49 return dist.Get(a.X, b.X); 50 50 } 51 52 public override double Get(IDataPoint<T> a, IDataPoint<T> b, double threshold) {53 return dist.Get(a.X, b.X, threshold);54 }55 51 } 56 52 } -
branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4/TSNE/Distances/DistanceBase.cs
r14512 r14767 37 37 38 38 public abstract double Get(T a, T b); 39 public abstract double Get(T a, T b, double threshold);40 39 41 40 public IComparer<T> GetDistanceComparer(T item) { -
branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4/TSNE/Distances/EuclidianDistance.cs
r14512 r14767 45 45 return Math.Sqrt(point1.Zip(point2, (a1, b1) => (a1 - b1) * (a1 - b1)).Sum()); 46 46 } 47 public static double GetDistance(IEnumerable<double> a, IEnumerable<double> b, double threshold) {48 double sum = 0;49 var it1 = a.GetEnumerator();50 var it2 = b.GetEnumerator();51 while (sum > threshold * threshold && it1.MoveNext() && it2.MoveNext()) {52 var d = it1.Current - it2.Current;53 sum += d * d;54 }55 it1.Dispose();56 it2.Dispose();57 return sum;58 }59 47 #endregion 60 48 … … 62 50 return GetDistance(a.ToArray(), b.ToArray()); 63 51 } 64 public override double Get(IEnumerable<double> a, IEnumerable<double> b, double threshold) {65 return GetDistance(a, b, threshold);66 }67 52 } 68 53 } -
branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4/TSNE/Distances/InnerProductDistance.cs
r14512 r14767 30 30 31 31 /// <summary> 32 /// this is not a proper distance 32 /// The angluar distance as defined as a normalized distance measure dependent on the angle between two vectors. 33 /// It is designed for vectors with all positive coordinates. 33 34 /// </summary> 34 35 [StorableClass] 35 [Item("InnerProductDistance", "The Angluar Distance as defined as a normalized distance measure dependent on the angle between two vectors.\nIt is designed for vectors with all positive coordinates")]36 public class InnerProductDistance : DistanceBase<I ReadOnlyList<double>> {36 [Item("InnerProductDistance", "The angluar distance as defined as a normalized distance measure dependent on the angle between two vectors.\nIt is designed for vectors with all positive coordinates")] 37 public class InnerProductDistance : DistanceBase<IEnumerable<double>> { 37 38 38 39 #region HLConstructors … … 48 49 49 50 #region statics 50 public static double GetDistance(IReadOnlyList<double> point1, IReadOnlyList<double> point2) { 51 if (point1.Count != point2.Count) throw new ArgumentException("Inner Product distance not defined on vectors of different length"); 52 return point1.Zip(point2, (x, y) => x * y).Sum(); 53 } 54 public static double GetDistance(IEnumerable<double> a, IEnumerable<double> b, double threshold) { 55 return GetDistance(a.ToArray(), b.ToArray()); //no shortcut evaluation for Inner Product (summands may be negative => no way of telling if threshold is reached or not) 51 public static double GetDistance(IEnumerable<double> point1, IEnumerable<double> point2) { 52 var xs = point1.GetEnumerator(); 53 var ys = point2.GetEnumerator(); 54 var sum = 0.0; 55 while(xs.MoveNext() & ys.MoveNext()) { 56 if(xs.Current < 0 || ys.Current < 0) throw new ArgumentException("Inner product distance is only defined for vectors with non-negative elements"); 57 sum += xs.Current * ys.Current; 58 } 59 if(xs.MoveNext() || ys.MoveNext()) throw new ArgumentException("Enumerables contain a different number of elements"); 60 return sum; 56 61 } 57 62 #endregion 58 public override double Get(I ReadOnlyList<double> a, IReadOnlyList<double> b) {63 public override double Get(IEnumerable<double> a, IEnumerable<double> b) { 59 64 return GetDistance(a, b); 60 }61 public override double Get(IReadOnlyList<double> a, IReadOnlyList<double> b, double threshold) {62 return GetDistance(a, b, threshold);63 65 } 64 66 } -
branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4/TSNE/PriorityQueue.cs
r14414 r14767 29 29 // implementation based on C++ version from Peter Sanders 30 30 // http://www.mpi-inf.mpg.de/~sanders/programs/spq/ 31 public sealed class PriorityQueue<TK, TV> : IHeap<TK, TV>where TK : IComparable {31 public sealed class PriorityQueue<TK, TV> where TK : IComparable { 32 32 private class KNElement { 33 33 public TK Key { get; set; } … … 35 35 } 36 36 37 private int capacity;37 private readonly int capacity; 38 38 private int size; // index of last used element 39 39 private int finalLayerSize; // size of first layer with free space 40 40 private int finalLayerDist; // distance to end of layer 41 41 //private KNElement[] rawData; 42 private KNElement[] data; // alligned version of rawData42 private readonly KNElement[] data; // aligned version of rawData 43 43 44 44 public PriorityQueue(TK supremum, TK infimum, int cap) { … … 53 53 } 54 54 55 public int Size 56 { 55 public int Size { 57 56 get { return size; } 58 57 } 59 58 60 public TK Supremum 61 { 59 public TK Supremum { 62 60 get { return data[capacity + 1].Key; } 63 61 } 64 62 65 63 public KeyValuePair<TK, TV> PeekMin() { 66 if 64 if(size == 0) { 67 65 throw new InvalidOperationException("Heap is empty"); 68 66 } … … 87 85 size = sz - 1; 88 86 finalLayerDist++; 89 if 87 if(finalLayerDist == finalLayerSize) { 90 88 finalLayerSize >>= 2; 91 89 finalLayerDist = 0; 92 90 } 93 91 94 while 92 while(succ < sz) { 95 93 var minKey = data[succ].Key; 96 94 var delta = 0; 97 95 98 96 var otherKey = data[succ + 1].Key; 99 if 97 if(otherKey.CompareTo(minKey) < 0) { 100 98 minKey = otherKey; 101 99 delta = 1; 102 100 } 103 101 otherKey = data[succ + 2].Key; 104 if 102 if(otherKey.CompareTo(minKey) < 0) { 105 103 minKey = otherKey; 106 104 delta = 2; 107 105 } 108 106 otherKey = data[succ + 3].Key; 109 if 107 if(otherKey.CompareTo(minKey) < 0) { 110 108 minKey = otherKey; 111 109 delta = 3; … … 137 135 pred = pred - layerDist; // finally preds index 138 136 139 while 137 while(data[pred].Key.CompareTo(bubble) > 0) { // must terminate since inf at root 140 138 data[hole].Key = data[pred].Key; 141 139 data[hole].Value = data[pred].Value; … … 159 157 finalLayerDist--; 160 158 161 if 162 159 if(finalLayerDist == -1) { // layer full 160 // start next layer 163 161 finalLayerSize <<= 2; 164 162 finalLayerDist = finalLayerSize - 1; … … 173 171 pred = pred - layerDist; // finally preds index 174 172 var predKey = data[pred].Key; 175 while 173 while(predKey.CompareTo(key) > 0) { 176 174 data[hole].Key = predKey; 177 175 data[hole].Value = data[pred].Value; … … 196 194 var sup = Supremum; 197 195 var cap = capacity; 198 for 196 for(var i = 1; i <= cap; i++) { 199 197 data[i].Key = sup; 200 198 } -
branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4/TSNE/TSNE.cs
r14742 r14767 67 67 namespace HeuristicLab.Algorithms.DataAnalysis { 68 68 [StorableClass] 69 public class TSNE<T> : DeepCloneable , ITSNE<T>where T : class, IDeepCloneable {69 public class TSNE<T> : DeepCloneable where T : class, IDeepCloneable { 70 70 71 71 private const string IterationResultName = "Iteration"; … … 192 192 return new TSNE<TR>(distance, random).Run(data, newDimensions, perplexity, theta); 193 193 } 194 public static double[,] Run<TR>(TR[] data, int newDimensions, double perplexity, double theta, Func<TR, TR, double> distance, IRandom random) where TR : class, IDeepCloneable {195 return new TSNE<TR>(new FuctionalDistance<TR>(distance), random).Run(data, newDimensions, perplexity, theta);196 }197 194 198 195 #region helpers … … 224 221 if (results == null) return; 225 222 var plot = results[ErrorPlotResultName].Value as DataTable; 226 if (plot == null) throw new ArgumentException("Could not create/access Error-DataTable in Results-Collection. Was it removed by some effect?");223 if (plot == null) throw new ArgumentException("Could not create/access error data table in results collection. Was it removed by some effect?"); 227 224 var errors = plot.Rows["errors"].Values; 228 225 var c = exact -
branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4/TSNE/TSNEAnalysis.cs
r14742 r14767 38 38 namespace HeuristicLab.Algorithms.DataAnalysis { 39 39 /// <summary> 40 /// Linear regression data analysis algorithm. 40 /// t-distributed stochastic neighbourhood embedding (TSNE) projects the data in a low dimensional 41 /// space to allow visual cluster identification. 41 42 /// </summary> 42 [Item("TSNE", "t-distributed stochastic neighbourhood embedding projects the data in a low dimensional space to allow visual cluster identification")] 43 [Item("TSNE", "t-distributed stochastic neighbourhood embedding projects the data in a low " + 44 "dimensional space to allow visual cluster identification.")] 43 45 [Creatable(CreatableAttribute.Categories.DataAnalysis, Priority = 100)] 44 46 [StorableClass] 45 47 public sealed class TSNEAnalysis : BasicAlgorithm { 46 public override bool SupportsPause 47 { 48 public override bool SupportsPause { 48 49 get { return false; } 49 50 } 50 public override Type ProblemType 51 { 51 public override Type ProblemType { 52 52 get { return typeof(IDataAnalysisProblem); } 53 53 } 54 public new IDataAnalysisProblem Problem 55 { 54 public new IDataAnalysisProblem Problem { 56 55 get { return (IDataAnalysisProblem)base.Problem; } 57 56 set { base.Problem = value; } … … 76 75 77 76 #region Parameterproperties 78 public IFixedValueParameter<DoubleValue> PerplexityParameter 79 { 77 public IFixedValueParameter<DoubleValue> PerplexityParameter { 80 78 get { return Parameters[PerplexityParameterName] as IFixedValueParameter<DoubleValue>; } 81 79 } 82 public OptionalValueParameter<DoubleValue> ThetaParameter 83 { 80 public OptionalValueParameter<DoubleValue> ThetaParameter { 84 81 get { return Parameters[ThetaParameterName] as OptionalValueParameter<DoubleValue>; } 85 82 } 86 public IFixedValueParameter<IntValue> NewDimensionsParameter 87 { 83 public IFixedValueParameter<IntValue> NewDimensionsParameter { 88 84 get { return Parameters[NewDimensionsParameterName] as IFixedValueParameter<IntValue>; } 89 85 } 90 public IValueParameter<IDistance<RealVector>> DistanceParameter 91 { 86 public IValueParameter<IDistance<RealVector>> DistanceParameter { 92 87 get { return Parameters[DistanceParameterName] as IValueParameter<IDistance<RealVector>>; } 93 88 } 94 public IFixedValueParameter<IntValue> MaxIterationsParameter 95 { 89 public IFixedValueParameter<IntValue> MaxIterationsParameter { 96 90 get { return Parameters[MaxIterationsParameterName] as IFixedValueParameter<IntValue>; } 97 91 } 98 public IFixedValueParameter<IntValue> StopLyingIterationParameter 99 { 92 public IFixedValueParameter<IntValue> StopLyingIterationParameter { 100 93 get { return Parameters[StopLyingIterationParameterName] as IFixedValueParameter<IntValue>; } 101 94 } 102 public IFixedValueParameter<IntValue> MomentumSwitchIterationParameter 103 { 95 public IFixedValueParameter<IntValue> MomentumSwitchIterationParameter { 104 96 get { return Parameters[MomentumSwitchIterationParameterName] as IFixedValueParameter<IntValue>; } 105 97 } 106 public IFixedValueParameter<DoubleValue> InitialMomentumParameter 107 { 98 public IFixedValueParameter<DoubleValue> InitialMomentumParameter { 108 99 get { return Parameters[InitialMomentumParameterName] as IFixedValueParameter<DoubleValue>; } 109 100 } 110 public IFixedValueParameter<DoubleValue> FinalMomentumParameter 111 { 101 public IFixedValueParameter<DoubleValue> FinalMomentumParameter { 112 102 get { return Parameters[FinalMomentumParameterName] as IFixedValueParameter<DoubleValue>; } 113 103 } 114 public IFixedValueParameter<DoubleValue> EtaParameter 115 { 104 public IFixedValueParameter<DoubleValue> EtaParameter { 116 105 get { return Parameters[EtaParameterName] as IFixedValueParameter<DoubleValue>; } 117 106 } 118 public IFixedValueParameter<BoolValue> SetSeedRandomlyParameter 119 { 107 public IFixedValueParameter<BoolValue> SetSeedRandomlyParameter { 120 108 get { return Parameters[SetSeedRandomlyParameterName] as IFixedValueParameter<BoolValue>; } 121 109 } 122 public IFixedValueParameter<IntValue> SeedParameter 123 { 110 public IFixedValueParameter<IntValue> SeedParameter { 124 111 get { return Parameters[SeedParameterName] as IFixedValueParameter<IntValue>; } 125 112 } 126 public IFixedValueParameter<StringValue> ClassesParameter 127 { 113 public IFixedValueParameter<StringValue> ClassesParameter { 128 114 get { return Parameters[ClassesParameterName] as IFixedValueParameter<StringValue>; } 129 115 } 130 public IFixedValueParameter<BoolValue> NormalizationParameter 131 { 116 public IFixedValueParameter<BoolValue> NormalizationParameter { 132 117 get { return Parameters[NormalizationParameterName] as IFixedValueParameter<BoolValue>; } 133 118 } … … 135 120 136 121 #region Properties 137 public IDistance<RealVector> Distance 138 { 122 public IDistance<RealVector> Distance { 139 123 get { return DistanceParameter.Value; } 140 124 } 141 public double Perplexity 142 { 125 public double Perplexity { 143 126 get { return PerplexityParameter.Value.Value; } 144 127 } 145 public double Theta 146 { 128 public double Theta { 147 129 get { return ThetaParameter.Value == null ? 0 : ThetaParameter.Value.Value; } 148 130 } 149 public int NewDimensions 150 { 131 public int NewDimensions { 151 132 get { return NewDimensionsParameter.Value.Value; } 152 133 } 153 public int MaxIterations 154 { 134 public int MaxIterations { 155 135 get { return MaxIterationsParameter.Value.Value; } 156 136 } 157 public int StopLyingIteration 158 { 137 public int StopLyingIteration { 159 138 get { return StopLyingIterationParameter.Value.Value; } 160 139 } 161 public int MomentumSwitchIteration 162 { 140 public int MomentumSwitchIteration { 163 141 get { return MomentumSwitchIterationParameter.Value.Value; } 164 142 } 165 public double InitialMomentum 166 { 143 public double InitialMomentum { 167 144 get { return InitialMomentumParameter.Value.Value; } 168 145 } 169 public double FinalMomentum 170 { 146 public double FinalMomentum { 171 147 get { return FinalMomentumParameter.Value.Value; } 172 148 } 173 public double Eta 174 { 175 get 176 { 149 public double Eta { 150 get { 177 151 return EtaParameter.Value == null ? 0 : EtaParameter.Value.Value; 178 152 } 179 153 } 180 public bool SetSeedRandomly 181 { 154 public bool SetSeedRandomly { 182 155 get { return SetSeedRandomlyParameter.Value.Value; } 183 156 } 184 public uint Seed 185 { 157 public uint Seed { 186 158 get { return (uint)SeedParameter.Value.Value; } 187 159 } 188 public string Classes 189 { 160 public string Classes { 190 161 get { return ClassesParameter.Value.Value; } 191 162 } 192 public bool Normalization 193 { 163 public bool Normalization { 194 164 get { return NormalizationParameter.Value.Value; } 195 165 } … … 230 200 public override void Stop() { 231 201 base.Stop(); 232 if 202 if(tsne != null) tsne.Running = false; 233 203 } 234 204 … … 239 209 240 210 //color datapoints acording to Classes-Variable (be it double or string) 241 if 242 if 211 if(problemData.Dataset.VariableNames.Contains(Classes)) { 212 if((problemData.Dataset as Dataset).VariableHasType<string>(Classes)) { 243 213 var classes = problemData.Dataset.GetStringValues(Classes).ToArray(); 244 for 245 if 214 for(var i = 0; i < classes.Length; i++) { 215 if(!dataRowNames.ContainsKey(classes[i])) dataRowNames.Add(classes[i], new List<int>()); 246 216 dataRowNames[classes[i]].Add(i); 247 217 } 248 } else if 218 } else if((problemData.Dataset as Dataset).VariableHasType<double>(Classes)) { 249 219 var classValues = problemData.Dataset.GetDoubleValues(Classes).ToArray(); 250 220 var max = classValues.Max() + 0.1; 251 221 var min = classValues.Min() - 0.1; 252 222 const int contours = 8; 253 for 223 for(var i = 0; i < contours; i++) { 254 224 var contourname = GetContourName(i, min, max, contours); 255 225 dataRowNames.Add(contourname, new List<int>()); … … 258 228 rows[contourname].VisualProperties.PointSize = i + 3; 259 229 } 260 for 230 for(var i = 0; i < classValues.Length; i++) { 261 231 dataRowNames[GetContourName(classValues[i], min, max, contours)].Add(i); 262 232 } … … 268 238 269 239 //Set up and run TSNE 270 if 240 if(SetSeedRandomly) SeedParameter.Value.Value = new System.Random().Next(); 271 241 var random = new MersenneTwister(Seed); 272 242 tsne = new TSNE<RealVector>(Distance, random, Results, MaxIterations, StopLyingIteration, MomentumSwitchIteration, InitialMomentum, FinalMomentum, Eta, dataRowNames, rows); … … 274 244 var allowedInputVariables = problemData.AllowedInputVariables.ToArray(); 275 245 var data = new RealVector[dataset.Rows]; 276 for 277 if 246 for(var row = 0; row < dataset.Rows; row++) data[row] = new RealVector(allowedInputVariables.Select(col => dataset.GetDoubleValue(col, row)).ToArray()); 247 if(Normalization) data = NormalizeData(data); 278 248 tsne.Run(data, NewDimensions, Perplexity, Theta); 279 249 } … … 284 254 var sd = new double[n]; 285 255 var nData = new RealVector[data.Count]; 286 for 256 for(var i = 0; i < n; i++) { 287 257 var i1 = i; 288 258 sd[i] = Enumerable.Range(0, data.Count).Select(x => data[x][i1]).StandardDeviation(); 289 259 mean[i] = Enumerable.Range(0, data.Count).Select(x => data[x][i1]).Average(); 290 260 } 291 for 261 for(var i = 0; i < data.Count; i++) { 292 262 nData[i] = new RealVector(n); 293 for 263 for(var j = 0; j < n; j++) nData[i][j] = (data[i][j] - mean[j]) / sd[j]; 294 264 } 295 265 return nData; … … 309 279 return "[" + (min + i * size) + ";" + (min + (i + 1) * size) + ")"; 310 280 } 311 312 281 } 313 282 } -
branches/TSNE/HeuristicLab.Algorithms.DataAnalysis/3.4/TSNE/VPTree.cs
r14518 r14767 99 99 100 100 public void Search(T target, int k, out List<T> results, out List<double> distances) { 101 IHeap<double, HeapItem>heap = new PriorityQueue<double, HeapItem>(double.MaxValue, double.MinValue, k);101 var heap = new PriorityQueue<double, HeapItem>(double.MaxValue, double.MinValue, k); 102 102 tau = double.MaxValue; 103 103 Search(root, target, k, heap); … … 142 142 } 143 143 144 private void Search(Node node, T target, int k, IHeap<double, HeapItem> heap) {144 private void Search(Node node, T target, int k, PriorityQueue<double, HeapItem> heap) { 145 145 if (node == null) return; 146 146 var dist = distance.Get(items[node.index], target); 147 147 if (dist < tau) { 148 148 if (heap.Size == k) heap.RemoveMin(); 149 heap.Insert(-dist, new HeapItem(node.index, dist));//TODO check if minheap or maxheap s chould be used here149 heap.Insert(-dist, new HeapItem(node.index, dist));//TODO check if minheap or maxheap should be used here 150 150 if (heap.Size == k) tau = heap.PeekMinValue().Dist; 151 151 }
Note: See TracChangeset
for help on using the changeset viewer.