/** * Recursive function query function. */ private void query(LimitedPriorityNodeList queue, NodeStack i_nodes, BinaryHierarchicalNode node, LongDescripter768 feature) { //近傍ノードをスタックに追加 int sp = i_nodes.getLength(); int num_of_min = nearest(node, i_nodes, queue, feature); //先頭からnum_of_min個の最小ノードについて再帰探索 for (int i = 0; i < num_of_min; i++) { BinaryHierarchicalNode n = i_nodes.getItem(sp + i).node; if (n.is_leaf) { this.append(n); } else { this.query(queue, i_nodes, n, feature); } } //好成績な近傍ノード1つを取り出して探索する。 NodeStack.Item item = this.mlist.popSmallest(); if (item != null) { BinaryHierarchicalNode n = item.node; if (n.is_leaf) { this.append(n); } else { this.query(queue, i_nodes, n, feature); } } return; }
/** * Get a queue of all the children nodes sorted by distance from node center. */ private static int nearest(BinaryHierarchicalNode i_node, NodeStack nodes, LimitedPriorityNodeList queue, LongDescripter768 feature) { int mind = int.MaxValue; int sp = nodes.getLength(); BinaryHierarchicalNode[] children = i_node.children; int num_of_children = children.Length; //最小値の探索 for (int i = 0; i < num_of_children; i++) { NodeStack.Item item = nodes.prePush(); if (item == null) { //ワークエリアを使い切った。 return(0); } int d = children[i].center.descripter.hammingDistance(feature); item.node = children[i]; item.distance = d; if (d < mind) { mind = d; } } int num_of_min = 0; //最小値以外をキューに追記 for (int i = 0; i < num_of_children; i++) { NodeStack.Item item = nodes.getItem(sp + i); if (item.distance == mind) { //最小値は先頭に移動 nodes.swap(sp + num_of_min, sp + i); num_of_min++; } else { //最小値以外はキューに追加 queue.push(item); } } //最小値の数は(min_add_idx-s_idx) return(num_of_min); }