protected override Result FirstBeam(object q, HashSet<int> evaluated, IResult res) { int samplesize = 0; // the real value can bee really complex, Monte Carlo methods // just use the larger sustainable value, however we are interested // on keep a fixed upper bound if (this.Vertices.Count > 4) { if (this.Vertices.Count < 10000) { samplesize = (int) Math.Sqrt (this.Vertices.Count) * 2; } else { samplesize = 1000; } } // int samplesize = Math.Min (2, this.Vertices.Count); int beamsize = Math.Min (this.BeamSize, this.Vertices.Count); var beam = new Result (beamsize); // initializing the first beam for (int i = 0; i < samplesize; ++i) { var docID = this.Vertices.GetRandom().Key; if (evaluated.Add (docID)) { var d = this.DB.Dist (q, this.DB [docID]); beam.Push (docID, d); res.Push(docID, d); } } return beam; }
/// <summary> /// Build the index /// </summary> public virtual void Build(MetricDB db, int num_centers, Random rand, SequenceBuilder seq_builder = null) { this.DB = db; var n = this.DB.Count; // randomized has very good performance, even compared with more "intelligent" strategies this.node_list = new List<Node> (num_centers); var subset = RandomSets.GetRandomSubSet (num_centers, this.DB.Count, rand); for (int centerID = 0; centerID < num_centers; ++centerID) { this.node_list.Add (new Node (subset [centerID])); } var H = new HashSet<int> (subset); for (int docID = 0; docID < n; ++docID) { if (H.Contains(docID)) { continue; } var near = new Result(1); var far = new Result(1); for (var centerID = 0; centerID < num_centers; ++centerID) { var node = this.node_list[centerID]; var d = this.DB.Dist(this.DB[node.refID], this.DB[docID]); near.Push(centerID, d); far.Push(centerID, -d); } var _near = near.First; var _far = far.First; this.node_list[_near.ObjID].AddNear(docID, _near.Dist); this.node_list[_far.ObjID].AddFar(docID, -_far.Dist); } }
public override IResult SearchKNN(object q, int K, IResult final_result) { var state = new SearchState (); var beam = this.FirstBeam (q, final_result, state); var beamsize = beam.Count; double prevcov = 0; int count_ties = 0; for (int i = 0; i < this.RepeatSearch; ++i) { prevcov = final_result.CoveringRadius; var _beam = new Result (beamsize); //if (this.Vertices.Count == this.DB.Count) // Console.WriteLine ("=== Iteration {0}/{1}, res-count: {2}, res-cov: {3}", i, this.RepeatSearch, final_result.Count, final_result.CoveringRadius); foreach (var pair in beam) { foreach(var neighbor_docID in this.Vertices [pair.docid]) { // Console.WriteLine ("=== B i: {0}, docID: {1}, parent: {2}, beamsize: {3}", i, neighbor_docID, pair, beam.Count); if (state.evaluated.Add(neighbor_docID)) { var d = this.DB.Dist (q, this.DB [neighbor_docID]); final_result.Push (neighbor_docID, d); _beam.Push (neighbor_docID, d); } } } if (final_result.CoveringRadius == prevcov) { if (count_ties == 1) { // we stop after two ties break; } ++count_ties; } else { count_ties = 0; } beam = _beam; } return final_result; }
/// <summary> /// Build the index /// </summary> public virtual void Build(MetricDB db, int num_centers, Random rand, SequenceBuilder seq_builder = null) { this.DB = db; var n = this.DB.Count; // randomized has very good performance, even compared with more "intelligent" strategies this.node_list = new List<Node> (num_centers); var subset = RandomSets.GetRandomSubSet (num_centers, this.DB.Count, rand); for (int centerID = 0; centerID < num_centers; ++centerID) { this.node_list.Add (new Node (subset [centerID])); } var H = new HashSet<int> (subset); for (int docID = 0; docID < n; ++docID) { if (docID % 1000 == 0) { Console.WriteLine ("== {0} {1}/{2}, num_centers: {3}, db: {4}", this, docID + 1, n, num_centers, db.Name); } if (H.Contains(docID)) { continue; } var far = new Result(1); for (var centerID = 0; centerID < num_centers; ++centerID) { var node = this.node_list[centerID]; var d = this.DB.Dist(this.DB[node.refID], this.DB[docID]); far.Push(centerID, -d); } var _far = far.First; this.node_list[_far.docid].Add(docID, -_far.dist); } }
public override IResult SearchKNN(object q, int K, IResult res) { var n = this.Vertices.Count; const int window = 2; var prev = double.MaxValue; var curr = 0.0; var inserted = new HashSet<int> (); var candidates = new Result (Math.Max(K, 32)); // var candidates = new Result (K+K); while (prev > curr) { prev = res.CoveringRadius; for (int i = 0; i < window; ++i) { var next = this.rand.Next (this.Vertices.Count); if (inserted.Add (next)) { var _res = new Result (res.K); var d = this.DB.Dist (q, this.DB [next]); candidates.Push (next, d); res.Push (next, d); this.InternalSearch (q, candidates, inserted, _res); foreach (var p in _res) { res.Push (p.ObjID, p.Dist); } } } curr = res.CoveringRadius; } return res; }
public override IResult SearchKNN(object q, int K, IResult res) { var window = 2; if (this.Vertices.Count > 16) { window = 8; } // if (this.Vertices.Count > 10000) { // Console.WriteLine ("STARTING SEARCH"); // } var prev = double.MaxValue; var curr = 0.0; var inserted = new HashSet<int> (); var candidates = new Result (this.Vertices.Count); while (prev > curr) { prev = res.CoveringRadius; for (int i = 0; i < window; ++i) { var next = this.rand.Next (this.Vertices.Count); if (inserted.Add (next)) { var d = this.DB.Dist (q, this.DB [next]); candidates.Push (next, d); res.Push (next, d); this.InternalSearch (q, candidates, inserted, res); } } curr = res.CoveringRadius; } return res; }
/// <summary> /// Search by range /// </summary> public override IResult SearchRange(object q, double radius) { int L = this.DB.Count; var r = new Result (L); for (int docid = 0; docid < L; docid++) { double d = this.DB.Dist (q, this.DB[docid]); if (d <= radius) { r.Push (docid, d); } } return r; }
/// <summary> /// Filter a result by radius /// </summary> public IResult FilterByRadius(IResult C, double radius) { var R = new Result (C.Count); foreach (var c in C) { if (c.dist <= radius) { R.Push (c.docid, c.dist); } else { break; } } return R; }
protected Result GetStartingPoints(object q) { int ss = Math.Min (this.SampleSize, this.Vertices.Count); var n = this.Vertices.Count; Result sorted = new Result (ss); for (int i = 0; i < ss; ++i) { var objID = this.rand.Next (0, n); var d = this.DB.Dist (q, this.DB [objID]); sorted.Push (objID, d); } return sorted; }
public virtual Result GetStartingPoints(object q, int num_starting_points) { var knr = Math.Min (this.RepeatSearch, this.Vertices.Count); var knrseq = new Result (knr); int ss = Math.Min (this.SampleSize, this.Vertices.Count); var n = this.Vertices.Count; for (int i = 0; i < ss; ++i) { var objID = this.rand.Next (0, n); var d = this.DB.Dist (q, this.DB [objID]); knrseq.Push (objID, d); } return knrseq; }
/// <summary> /// Build the index /// </summary> public virtual void Build(MetricDB db, int k, int m) { this.DB = db; var n = this.DB.Count; this.K = k; this.pivs.AddRange (RandomSets.GetRandomSubSet (m, n)); this.ispivot.Capacity = this.assocpivots.Capacity = n; this.ispivot.Clear (); this.assocpivots.Clear (); for (int objID = 0; objID < n; ++objID) { this.assocpivots.Add (new ItemPair[k + k]); this.ispivot.Add (0); } for (int pivID = 0; pivID < m; ++pivID) { var objID = this.pivs [pivID]; this.ispivot [objID] = 1; } for (int objID = 0; objID < n; ++objID) { var near = new Result (k); var far = new Result (k); var obj = this.DB [objID]; for (int pivID = 0; pivID < m; ++pivID) { var piv = this.DB [this.pivs [pivID]]; var d = this.DB.Dist (obj, piv); near.Push (pivID, d); // this can be buggy when k * 2 < n or dist() is too flat far.Push (pivID, -d); } var _assoc = this.assocpivots [objID]; { int i = 0; foreach (var p in near) { _assoc [i] = new ItemPair (p.ObjID, p.Dist); ++i; } foreach (var p in far) { _assoc [i] = new ItemPair (p.ObjID, -p.Dist); ++i; } } if (objID % 5000 == 0) { Console.WriteLine ("=== db: {0}, k: {1}, available: {2}, advance: {3}/{4}, timestamp: {5}", Path.GetFileName(db.Name), k, m, objID+1, n, DateTime.Now); } } }
protected override Result FirstBeam(object q, IResult final_result, SearchState state) { int samplesize = Math.Min (1024, this.Vertices.Count); //WARNING fixing the parameter beamsize for construction step for testing purposes int beamsize = Math.Min (this.BeamSize, this.Vertices.Count); var beam = new Result (beamsize); // initializing the first beam for (int i = 0; i < samplesize; ++i) { var docID = this.rand.Next(this.Vertices.Count); if (state.evaluated.Add (docID)) { var d = this.DB.Dist (q, this.DB [docID]); beam.Push (docID, d); final_result.Push(docID, d); } } return beam; }
public void InternalSearch(object q, Result candidates, HashSet<int> inserted, IResult res) { do { var start = candidates.PopFirst (); if (start.Dist > res.CoveringRadius) { break; } var adjList = this.Vertices[start.ObjID]; foreach (var item in adjList) { if (inserted.Add(item.ObjID)) { // true iff it wasn't evaluated var d = this.DB.Dist (this.DB [item.ObjID], q); candidates.Push (item.ObjID, d); res.Push(item.ObjID, d); } } } while (candidates.Count > 0); }
public override IResult SearchKNN(object q, int K, IResult res) { // var state = new SearchState (final_result); HashSet<int> evaluated = new HashSet<int> (); var beam = this.FirstBeam (q, evaluated, res); var maxbeamsize = beam.Count; var beamsize = maxbeamsize; double prev; do { prev = res.CoveringRadius; var _beamsize = Math.Min (beamsize, beam.Count); // var _beam = new Result(_beamsize); var _beam = new Result(_beamsize); for (int j = 0; j < _beamsize; ++j) { var item = beam.PopFirst (); foreach (var neighbor_docID in this.Vertices [item.ObjID]) { if (evaluated.Add (neighbor_docID)) { var d = this.DB.Dist (q, this.DB [neighbor_docID]); res.Push (neighbor_docID, d); _beam.Push(neighbor_docID, d); // beam.Push (neighbor_docID, d); // this can include distant items at any step } } } beam = _beam; // foreach (var p in _beam) { // beam.Push(p.ObjID, p.Dist); // } if (beamsize > 32) { beamsize = beamsize / 2; } if (prev == res.CoveringRadius) { beamsize = beamsize / 2; } } while (beamsize > 1); // } while (prev > curr); // } while (beamsize <= maxbeamsize); return res; }
public override Result GetStartingPoints(object q, int num_starting_points) { var C = 8; var knr = Math.Min (this.RepeatSearch * C, this.Vertices.Count); var near = new Result (knr); int ss = Math.Min (this.SampleSize, this.Vertices.Count); var n = this.Vertices.Count; for (int i = 0; i < ss; ++i) { var objID = this.rand.Next (0, n); var d = this.DB.Dist (q, this.DB [objID]); near.Push (objID, d); } if (this.Vertices.Count < this.RepeatSearch) return near; var prob = this.RepeatSearch / knr; // 1.0 / C; var sp = new Result (Math.Min (this.RepeatSearch, this.Vertices.Count)); int I = 0; foreach (var pair in near) { if (I == 0 || this.rand.NextDouble() < prob) { sp.Push (pair.docid, pair.dist); } ++I; } return sp; }
public override IResult SearchKNN(object q, int K, IResult final_result) { var state = new SearchState (); var beam = this.FirstBeam (q, final_result, state); var beamsize = beam.Count; double prevcov = 0; int count_ties = 0; var neighborhood = new List<int> (32); for (int i = 0; i < this.RepeatSearch; ++i) { prevcov = final_result.CoveringRadius; var _beam = new Result (beamsize); foreach (var pair in beam) { neighborhood.Clear (); // neighborhood.Add (pair.docid); foreach (var neighbor_docID in this.Vertices [pair.docid]) { this.ExpandNeighborhood (q, neighbor_docID, neighborhood, state, 8); } foreach (var neighbor_docID in neighborhood) { var d = this.DB.Dist (q, this.DB [neighbor_docID]); final_result.Push (neighbor_docID, d); _beam.Push (neighbor_docID, d); } } if (final_result.CoveringRadius == prevcov) { if (count_ties == 1) { // we stop after two ties break; } ++count_ties; } else { count_ties = 0; } beam = _beam; } return final_result; }
public override IResult SearchRange(object q, double radius) { var res = new Result(this.DB.Count); var dqp_cache = new Dictionary<int, double>(); var _PIVS = (this.PIVS as SampleSpace).SAMPLE; var n = this.DB.Count; var m = this.PIVS.Count; for (int docID = 0; docID < n; ++docID) { if (dqp_cache.ContainsKey(docID)) { continue; } bool check_object = true; for (int __pivID = 0; __pivID < m; ++__pivID) { var db_pivID = _PIVS[__pivID]; double dqp; if (!dqp_cache.TryGetValue(db_pivID, out dqp)) { dqp = this.DB.Dist(q, this.DB[db_pivID]); ++this.internal_numdists; dqp_cache[db_pivID] = dqp; if (db_pivID >= docID) { if (dqp <= radius) { res.Push(db_pivID, dqp); } if (db_pivID == docID) { check_object = false; break; } } } var dpu = this.DIST[__pivID][docID]; if (Math.Abs (dqp - dpu) > radius) { check_object = false; break; } } if (check_object) { var d = this.DB.Dist(this.DB[docID], q); if (d <= radius) { res.Push(docID, d); } } } return res; }
// ref int count_step, int depth) protected virtual void BuildNode(Node node, List<ItemPair> items, int depth) { //Console.WriteLine("======== BUILD NODE: {0}", node.objID); ++count_step; if (count_step < 100 || count_step % 100 == 0) { Console.WriteLine ("======== SAT {4} build_node: {0}, count_step: {1}/{2}, items_count: {3}, timestamp: {5}, db: {6}", node.objID, count_step, this.DB.Count, items.Count, this, DateTime.Now, this.DB.Name); } var partition = new List< List< ItemPair > > (); //var cache = new Dictionary<int,double> (items.Count); this.SortItems (items); var pool = new List<int> (items.Count); foreach (var item in items) { node.cov = Math.Max (node.cov, item.Dist); object currOBJ; currOBJ = this.DB [item.ObjID]; var closer = new Result (1); closer.Push (-1, item.Dist); for (int child_ID = 0; child_ID < node.Children.Count; ++child_ID) { var child = node.Children [child_ID]; var childOBJ = this.DB [child.objID]; var d_child_curr = this.DB.Dist (childOBJ, currOBJ); closer.Push (child_ID, d_child_curr); } { var child_ID = closer.First.ObjID; // var closer_dist = closer.First.dist; if (child_ID == -1) { var new_node = new Node (item.ObjID); node.Children.Add (new_node); partition.Add (new List<ItemPair> ()); } else { // partition [child_ID].Add (new DynamicSequential.Item (item.objID, closer_dist)); pool.Add (item.ObjID); } } } foreach (var objID in pool) { var closer = new Result (1); for (int child_ID = 0; child_ID < node.Children.Count; ++child_ID) { var child = node.Children [child_ID]; var childOBJ = this.DB [child.objID]; var d_child_curr = this.DB.Dist (childOBJ, this.DB[objID]); closer.Push (child_ID, d_child_curr); } { var child_ID = closer.First.ObjID; var closer_dist = closer.First.Dist; partition[child_ID].Add (new ItemPair {ObjID = objID, Dist = closer_dist}); } } pool = null; //Console.WriteLine("===== add children"); // Action<int> build_node = delegate (int child_ID) { // this.BuildNode (node.Children [child_ID], partition [child_ID], depth + 1); // partition [child_ID] = null; // }; // var ops = new ParallelOptions(); // ops.MaxDegreeOfParallelism = -1; // Parallel.For (0, node.Children.Count, build_node); for (int child_ID = 0; child_ID < node.Children.Count; ++child_ID) { //this.BuildNode (node.Children [child_ID], partition [child_ID], ref count_step, depth + 1); this.BuildNode (node.Children [child_ID], partition [child_ID], depth + 1); partition [child_ID] = null; } }
public override IResult SearchRange(object q, double radius) { var m = this.PIVS.Count; var n = this.DB.Count; HashSet<int> A = null; HashSet<int> B = null; for (int piv_id = 0; piv_id < m; ++piv_id) { var dqp = this.DB.Dist (q, this.PIVS [piv_id]); ++this.internal_numdists; var seq = this.DIST[piv_id]; if (A == null) { A = new HashSet<int>(); for (int i = 0; i < n; ++i) { var sym = seq[i]; var stddev = this.STDDEV[piv_id]; var mean = this.MEAN[piv_id]; var lower = this.Discretize(Math.Abs (dqp - radius), stddev, mean); var upper = this.Discretize(dqp + radius, stddev, mean); if (sym < lower || upper < sym ) { A.Add (i); } } } else { B = new HashSet<int>(); foreach (var i in A) { var sym = seq[i]; var stddev = this.STDDEV[piv_id]; var mean = this.MEAN[piv_id]; var lower = this.Discretize(Math.Abs (dqp - radius), stddev, mean); var upper = this.Discretize(dqp + radius, stddev, mean); if (sym < lower || upper < sym ) { B.Add(i); } } A = B; } } var res = new Result(this.DB.Count); foreach (var docid in A) { var d = this.DB.Dist(this.DB[docid], q); if (d <= radius) { res.Push(docid, d); } } return res; }
public override IResult SearchKNN(object q, int K, IResult res) { var inserted = new HashSet<int> (); var candidates = new Result (this.Vertices.Count); for (int restartID = 0; restartID < this.Restarts; ++restartID) { var next = this.rand.Next (this.Vertices.Count); if (inserted.Add (next)) { var d = this.DB.Dist (q, this.DB [next]); candidates.Push (next, d); res.Push (next, d); this.InternalSearch (q, candidates, inserted, res); } } return res; }
public virtual Result GetNear(int[] seq) { var cand = new Result (this.MAXCAND); var n = this.DB.Count; for (int objID = 0; objID < n; ++objID) { /*var d = Jaccard (seq, this.S [objID]); if (d < 1) { cand.Push (objID, d); }*/ var d = SeqSpace<int>.PrefixLength(seq, this.S[objID]); // var d = StringSpace<int>.LCS(seq, this.S[objID]); cand.Push (objID, d); } return cand; }
public override IResult SearchRange(object q, double radius) { var m = this.PIVS.Count; var P = new TopK<Tuple<double, int, int, Sequence>> (m); for (int piv_id = 0; piv_id < m; ++piv_id) { var dqp = this.DB.Dist (q, this.PIVS [piv_id]); ++this.internal_numdists; var stddev = this.STDDEV [piv_id]; var mean = this.MEAN [piv_id]; var start_sym = this.Discretize (dqp - radius, stddev, mean); var seq = this.SEQ [piv_id]; var end_sym = this.Discretize (dqp + radius, stddev, mean); var count = 0; var n = seq.Count; for (int s = start_sym; s <= end_sym; ++s) { count += seq.Rank (s, n - 1); } P.Push (count, Tuple.Create (dqp, start_sym, end_sym, seq)); } HashSet<int> A = new HashSet<int>(); HashSet<int> B = null; int I = 0; foreach (var p in P.Items.Traverse()) { var tuple = p.Value; // var dpq = tuple.Item1; var start_sym = tuple.Item2; var end_sym = tuple.Item3; var seq = tuple.Item4; for (int s = start_sym; s <= end_sym; ++s) { var rs = seq.Unravel(s); var count1 = rs.Count1; for (int i = 1; i <= count1; ++i) { if (B == null) { A.Add( rs.Select1(i) ); } else { var pos = rs.Select1(i); if (A.Contains(pos)) { B.Add( pos ); } } } } if (B == null) { B = new HashSet<int>(); } else { A = B; B = new HashSet<int>(); } ++I; } // Console.WriteLine(); B = null; var res = new Result(this.DB.Count, false); foreach (var docid in A) { var d = this.DB.Dist(this.DB[docid], q); if (d <= radius) { res.Push(docid, d); } } return res; }
/// <summary> /// KNN Search in the index /// </summary> /// <param name="q"> /// The query object /// </param> /// <param name="k"> /// The number of nearest neighbors /// A <see cref="System.Int32"/> /// </param> /// <returns> /// The result set /// A <see cref="Result"/> /// </returns> public override IResult SearchKNN(object q, int k) { var enc = this.Encode (q); this.internal_numdists += this.REFS.Count; //Console.WriteLine ("EncQuery: {0}", BinaryHammingSpace.ToAsciiString (enc)); var cand = this.IndexHamming.SearchKNN (enc, Math.Abs (this.MAXCAND)); if (this.MAXCAND < 0) { return cand; } var res = new Result(k); foreach (ItemPair p in cand) { res.Push(p.ObjID, this.DB.Dist(q, this.DB[p.ObjID])); } return res; }
protected virtual Result GetNearPoint(object q) { var near = new Result (1); int ss = Math.Min (this.SampleSize, this.Vertices.Count); var n = this.Vertices.Count; for (int i = 0; i < ss; ++i) { var objID = this.rand.Next (0, n); var d = this.DB.Dist (q, this.DB [objID]); near.Push (objID, d); } return near; }
public override IResult SearchKNN(object q, int K, IResult final_result) { var state = new SearchState (); var beam = this.FirstBeam (q, final_result, state); var beamsize = beam.Count; //Console.WriteLine ("**** beamsize: {0}, repeatsearch: {1}", beamsize, this.RepeatSearch); //Console.WriteLine ("**** count: {0}, vertices-count: {1}", this.DB.Count, this.Vertices.Count); // expand successors and select the best BeamSize ones among them for (int i = 0; i < this.RepeatSearch; ++i) { var _beam = new Result (beamsize); if (this.Vertices.Count == this.DB.Count) Console.WriteLine ("=== Iteration {0}/{1}, res-count: {2}, res-cov: {3}", i, this.RepeatSearch, final_result.Count, final_result.CoveringRadius); foreach (var pair in beam) { foreach(var neighbor_docID in this.Vertices [pair.docid]) { // Console.WriteLine ("=== B i: {0}, docID: {1}, parent: {2}, beamsize: {3}", i, neighbor_docID, pair, beam.Count); if (state.evaluated.Add(neighbor_docID)) { var d = this.DB.Dist (q, this.DB [neighbor_docID]); final_result.Push (neighbor_docID, d); _beam.Push (neighbor_docID, d); } } } beam = _beam; } return final_result; }
public virtual IResult FilterCandidates(object q, HashSet<int> L) { var query = this.hplanes.GetFP(q); IResult r = new Result(this.hplanes.MaxCandidates, false); var fp = this.hplanes.Fingerprints; foreach(var docID in L){ var d = fp.Dist (query, fp[docID]); r.Push(docID,d); } return r; }
public override IResult SearchKNN(object q, int K, IResult final_result) { var state = new SearchState (); var beam = this.FirstBeam (q, final_result, state); var beamsize = beam.Count; //Console.WriteLine ("**** beamsize: {0}, repeatsearch: {1}", beamsize, this.RepeatSearch); //Console.WriteLine ("**** count: {0}, vertices-count: {1}", this.DB.Count, this.Vertices.Count); // expand successors and select the best BeamSize ones among them for (int i = 0; i < this.RepeatSearch; ++i) { IResult _beam = new Result (beamsize); if (this.Vertices.Count == this.DB.Count) Console.WriteLine ("=== Iteration {0}/{1}, res-count: {2}, res-cov: {3}", i, this.RepeatSearch, final_result.Count, final_result.CoveringRadius); foreach (var pair in beam) { foreach(var neighbor_docID in this.Vertices [pair.docid]) { // Console.WriteLine ("=== B i: {0}, docID: {1}, parent: {2}, beamsize: {3}", i, neighbor_docID, pair, beam.Count); if (state.evaluated.Add (neighbor_docID)) { var d = this.DB.Dist (q, this.DB [neighbor_docID]); // THIS IS THE DIFFERENCE between the variants and the original (this) // local beam search. The others become greedy because we use additional // help (not necessary here) final_result.Push (neighbor_docID, d); _beam.Push (neighbor_docID, d); } } } beam = _beam; } return final_result; }
public override IResult SearchRange(object q, double radius) { var res = new Result(int.MaxValue, false); var R = this.IDX.SearchRange (q, radius); var P = (this.IDX.DB as SampleSpace); foreach (var p in R) { // res.Push(P.PERM.Inverse(p.docid), p.dist); res.Push(P.SAMPLE[p.docid], p.dist); } // IDX 1 2 3 4 // DIR 4 2 1 3 (3,4) => (1,3) => (3,4) // INV 3 2 4 1 return res; }
public override IResult SearchKNN(object q, int K, IResult final_result) { var knr = Math.Min (this.RepeatSearch, this.Vertices.Count); var knrseq = new Result (knr); var n = this.Vertices.Count; int ss = Math.Min (this.SampleSize, this.Vertices.Count); // Get the HSP!!! bool[] subdb=new bool[this.DB.Count]; for (int i = 0; i < ss; ++i) { var objID = this.rand.Next (0, n); subdb[objID]=true; //knrseq.Push (objID, d); } // Get the hsp-neigbors of q IList<int> hsp_neighbors= HSP.ComputeEdges(q,this.DB,subdb); foreach (int id in hsp_neighbors) { var d = this.DB.Dist (q, this.DB [id]); Console.WriteLine("id:{0} d:{1}",id,d); knrseq.Push(id,d); } Console.WriteLine( knrseq.Count); // End getting the HSP var res_array = new Result[knrseq.Count]; int I = 0; // on a parallel implementation these two hashsets must be set to null var state = new SearchState (); // visited = evaluated = null; foreach (var p in knrseq) { var res = new Result (K); //Console.WriteLine ("** starting GreedySearch"); this.GreedySearch(q, res, p.docid, state); res_array [I] = res; ++I; } var inserted = new HashSet<int> (); foreach (var res in res_array) { if (res == null) { break; } foreach (var p in res) { if (inserted.Add(p.docid)) { final_result.Push(p.docid, p.dist); } } } return final_result; }
protected virtual IResult FirstBeam(object q, IResult final_result, SearchState state) { int beamsize = Math.Min (this.BeamSize, this.Vertices.Count); IResult beam = new Result (beamsize); // initializing the first beam for (int i = 0; i < beamsize; ++i) { var docID = RandomSets.GetRandomInt(this.Vertices.Count); if (state.evaluated.Add (docID)) { var d = this.DB.Dist (q, this.DB [docID]); beam.Push (docID, d); final_result.Push(docID, d); } } return beam; }