Example #1
0
  @Override
  public DeepTree<N, E> snoc(final Node<N, E> lst) {
    if (right.length < MAX_DIGIT) {
      final Node<N, E>[] newRight = slice(right, 0, right.length + 1);
      newRight[right.length] = lst;
      return new DeepTree<>(left, leftSize, middle, newRight, size + lst.size());
    }

    final int rl = right.length, m = NODE_SIZE;
    final Node<N, E>[] sub = slice(right, 0, m), newRight = slice(right, m, rl + 1);
    newRight[rl - m] = lst;
    final FingerTree<Node<N, E>, E> mid = middle.snoc(new InnerNode<>(sub));
    return new DeepTree<>(left, leftSize, mid, newRight, size + lst.size());
  }
Example #2
0
 public void union(Node x, Node y) {
   Node a = find(x);
   Node b = find(y);
   if (a != b) {
     if (a.size > b.size) {
       b.up = a;
       a.size += b.size;
       b.size = 0;
     } else {
       a.up = b;
       b.size += a.size;
       a.size = 0;
     }
   }
 }
Example #3
0
 @Override
 public FingerTree<N, E> replaceLast(final Node<N, E> last) {
   final int lst = right.length - 1;
   final Node<N, E>[] newRight = right.clone();
   newRight[lst] = last;
   return new DeepTree<>(left, leftSize, middle, newRight, size + last.size() - right[lst].size());
 }
Example #4
0
 @Override
 public FingerTree<N, E> replaceHead(final Node<N, E> head) {
   final long sizeDiff = head.size() - left[0].size();
   final Node<N, E>[] newLeft = left.clone();
   newLeft[0] = head;
   return new DeepTree<>(newLeft, leftSize + sizeDiff, middle, right, size + sizeDiff);
 }
Example #5
0
  /**
   * Creates a tree slice from a digit.
   *
   * @param <N> node type
   * @param <E> element type
   * @param nodes the digit
   * @param from element offset
   * @param len number of elements
   * @param buffer buffer to insert the node slice into
   * @param inBuffer initial number of nodes in the buffer
   * @return the slice
   */
  private static <N, E> int splitDigit(
      final Node<N, E>[] nodes,
      final long from,
      final long len,
      final NodeLike<N, E>[] buffer,
      final int inBuffer) {
    if (len <= 0) return inBuffer;

    // find the first sub-node containing used elements
    int firstPos = 0;
    long firstOff = from;
    Node<N, E> first = nodes[0];
    long firstSize = first.size();
    while (firstOff >= firstSize) {
      firstOff -= firstSize;
      first = nodes[++firstPos];
      firstSize = first.size();
    }

    // firstOff < firstSize
    final long inFirst = firstSize - firstOff;
    if (inFirst >= len) {
      // everything in first sub-node
      final NodeLike<N, E> part = len == firstSize ? first : first.slice(firstOff, len);
      return part.append(buffer, inBuffer);
    }

    final NodeLike<N, E> firstSlice = firstOff == 0 ? first : first.slice(firstOff, inFirst);
    int numMerged = firstSlice.append(buffer, inBuffer);

    int pos = firstPos;
    long remaining = len - inFirst;
    while (remaining > 0) {
      final Node<N, E> curr = nodes[++pos];
      final long currSize = curr.size();
      final NodeLike<N, E> slice = remaining >= currSize ? curr : curr.slice(0, remaining);
      numMerged = slice.append(buffer, numMerged);
      remaining -= currSize;
    }

    return numMerged;
  }
Example #6
0
    public void mergeFrom(Node right) {
      assert (right.size() == capacity / 2) || (size == capacity / 2)
          : "Should have exactly half capacity nodes";

      Leaf leaf = (Leaf) right;

      shallowCopy(leaf, 0, this, size, leaf.size());
      next = leaf.next();

      size += leaf.size();
    }
Example #7
0
  @Test
  public void test1() {
    Random random = new Random(228);

    Node root = EmptyNode.instance;
    for (int i = 0; i < 10; i++) {
      root = root.merge(new NotEmptyNode(i, random.nextInt()));

      System.out.println(root.size());
    }

    Node.SplitResult split = root.split(5);
  }
  private Node<K, V> put(K key, V val, Node<K, V> node) {
    if (node == null) return new Node<K, V>(key, val, 1);

    int cmp = key.compareTo(node.key);
    if (cmp == 0) {
      node.value = val;
    } else if (cmp < 0) {
      node.left = put(key, val, node.left);
    } else if (cmp > 0) {
      node.right = put(key, val, node.right);
    }
    node.size = size(node.left) + size(node.right) + 1;
    return node;
  }
Example #9
0
  @Override
  public DeepTree<N, E> cons(final Node<N, E> fst) {
    final long sz = fst.size();
    if (left.length < MAX_DIGIT) {
      final Node<N, E>[] newLeft = slice(left, -1, left.length);
      newLeft[0] = fst;
      return new DeepTree<>(newLeft, leftSize + sz, middle, right, size + sz);
    }

    final int ll = left.length, m = ll - NODE_SIZE;
    final Node<N, E>[] newLeft = slice(left, -1, m), sub = slice(left, m, ll);
    newLeft[0] = fst;
    final FingerTree<Node<N, E>, E> mid = middle.cons(new InnerNode<>(sub));
    return get(newLeft, mid, right, size + sz);
  }
Example #10
0
 long ans() {
   if (_ans != -3) return _ans;
   if (children.size() == 0) {
     if (this == EMPTY_LEAF) return 0;
     return i;
   }
   long digits = 0;
   long ret = 0;
   for (int i = children.size() - 1; i >= 0; i--) {
     Node node = children.get(i);
     ret = (ret + (node.ans() * modPow(digits)) % MOD) % MOD;
     digits += node.size();
     digits %= MOD - 1;
   }
   _ans = ret;
   return ret;
 }
  // Given a binary tree, find the largest Binary Search Tree (BST),
  // where largest means BST with largest number of nodes in it.
  // The largest BST may or may not include all of its descendants.
  public static LargestBST largestBSTSubtree1(Node node) {
    if (node == null) return null;
    if (node.left == null && node.right == null) {
      return new LargestBST(node, node.size(), node.value, node.value);
    }

    LargestBST leftNode = largestBSTSubtree1(node.left);
    LargestBST rightNode = largestBSTSubtree1(node.right);

    if (leftNode != null && rightNode != null) {
      if ((node.value > leftNode.max && node.left == leftNode.node)
          && (node.value < rightNode.min && node.right == rightNode.node)) {

        LargestBST bst =
            new LargestBST(
                node, leftNode.maxNode + rightNode.maxNode + 1, leftNode.min, rightNode.max);

        return bst;
      } else if (node.value > leftNode.max && node.left == leftNode.node) {
        return new LargestBST(node, leftNode.maxNode + 1, leftNode.min, node.value);

      } else if (node.value < rightNode.min && node.right == rightNode.node) {
        return new LargestBST(node, rightNode.maxNode + 1, node.value, rightNode.max);
      } else {
        return (leftNode.maxNode > rightNode.maxNode) ? leftNode : rightNode;
      }
    } else if (leftNode != null) {
      if (node.value > leftNode.max && node.left == leftNode.node) {
        return new LargestBST(node, leftNode.maxNode + 1, leftNode.min, node.value);
      } else {
        return leftNode;
      }

    } else if (rightNode != null) {
      if (node.value < rightNode.min && node.right == rightNode.node) {
        return new LargestBST(node, rightNode.maxNode + 1, node.value, rightNode.max);
      } else {
        return rightNode;
      }
    }

    return null;
  }
Example #12
0
  @Override
  public TreeSlice<N, E> remove(final long pos) {
    if (pos < leftSize) return new TreeSlice<>(removeLeft(pos));
    final long rightStart = leftSize + middle.size();
    if (pos >= rightStart) return new TreeSlice<>(removeRight(pos - rightStart));

    final TreeSlice<Node<N, E>, E> slice = middle.remove(pos - leftSize);
    if (slice.isTree()) {
      // no underflow
      final FingerTree<Node<N, E>, E> newMiddle = slice.getTree();
      return slice.setTree(new DeepTree<>(left, leftSize, newMiddle, right, size - 1));
    }

    // middle tree had an underflow, one sub-node left
    final Node<N, E> node = (Node<N, E>) ((PartialInnerNode<N, E>) slice.getPartial()).sub;

    // try to extend the smaller digit
    if (left.length < right.length) {
      // merge into left digit
      final Node<N, E>[] newLeft = slice(left, 0, left.length + 1);
      newLeft[left.length] = node;
      return slice.setTree(get(newLeft, leftSize + node.size(), right, size - 1));
    }

    if (right.length < MAX_DIGIT) {
      // merge into right digit
      final Node<N, E>[] newRight = slice(right, -1, right.length);
      newRight[0] = node;
      return slice.setTree(get(left, leftSize, newRight, size - 1));
    }

    // redistribute the nodes
    final int n = 2 * MAX_DIGIT + 1, ll = (n - NODE_SIZE) / 2;
    @SuppressWarnings("unchecked")
    final Node<N, E>[] newLeft = slice(left, 0, ll), ch = new Node[NODE_SIZE];
    final int inL = left.length - ll, inR = NODE_SIZE - inL - 1;
    System.arraycopy(left, ll, ch, 0, inL);
    ch[inL] = node;
    System.arraycopy(right, 0, ch, inL + 1, inR);
    final Node<N, E>[] newRight = slice(right, inR, MAX_DIGIT);
    final Node<Node<N, E>, E> newMid = new InnerNode<>(ch);
    return slice.setTree(get(newLeft, new SingletonTree<>(newMid), newRight, size - 1));
  }
Example #13
0
  /**
   * Deletes an element from the given digit containing at least two nodes.
   *
   * @param <N> node type
   * @param <E> element type
   * @param arr array of nodes
   * @param pos deletion position
   * @return new digit
   */
  private static <N, E> Node<N, E>[] remove(final Node<N, E>[] arr, final long pos) {
    int i = 0;
    long off = pos;
    Node<N, E> node;
    while (true) {
      node = arr[i];
      final long nodeSize = node.size();
      if (off < nodeSize) break;
      off -= nodeSize;
      i++;
    }

    final int n = arr.length;
    final NodeLike<N, E>[] res =
        arr[i].remove(i == 0 ? null : arr[i - 1], i == n - 1 ? null : arr[i + 1], off);
    final Node<N, E> l = (Node<N, E>) res[0], m = (Node<N, E>) res[1], r = (Node<N, E>) res[2];
    if (m != null) {
      // same number of nodes
      final Node<N, E>[] out = arr.clone();
      if (i > 0) out[i - 1] = l;
      out[i] = m;
      if (i < n - 1) out[i + 1] = r;
      return out;
    }

    // the node was merged
    @SuppressWarnings("unchecked")
    final Node<N, E>[] out = new Node[n - 1];
    if (i > 0) {
      // nodes to the left
      System.arraycopy(arr, 0, out, 0, i - 1);
      out[i - 1] = l;
    }

    if (i < n - 1) {
      // nodes to the right
      out[i] = r;
      System.arraycopy(arr, i + 2, out, i + 1, n - i - 2);
    }

    return out;
  }
 /**
  * Returns the number of character sequences with non-zero counts, including the empty (zero
  * length) character sequence.
  *
  * @return Number of character sequences with non-zero counts.
  */
 public long uniqueSequenceCount() {
   return mRootNode.size();
 }
Example #15
0
  /** @param args */
  public static void main(final String[] args) throws Exception {
    final BufferedReader br =
        new BufferedReader(
            new InputStreamReader(
                (new GZIPInputStream(
                    new FileInputStream(
                        new File(
                            new File(System.getProperty("user.dir")), "testdata/mobo1.txt.gz"))))));

    final List<Instance> instances = Lists.newLinkedList();

    int count = 0;
    while (true) {
      count++;
      final String line = br.readLine();
      if (line == null) {
        break;
      }
      final JSONObject jo = (JSONObject) JSONValue.parse(line);
      final HashMapAttributes a = new HashMapAttributes();
      a.putAll((JSONObject) jo.get("attributes"));
      Instance instance = new Instance(a, (String) jo.get("output"));
      instances.add(instance);
    }

    final List<Instance> train = instances.subList(0, instances.size() / 2);
    final List<Instance> test = instances.subList(instances.size() / 2 + 1, instances.size() - 1);

    System.out.println("Read " + instances.size() + " instances");

    System.out.println("Testing scorers with single decision node");
    for (final Scorer scorer : Sets.newHashSet(new Scorer1())) {
      final TreeBuilder tb = new TreeBuilder(scorer);

      final long startTime = System.currentTimeMillis();
      final Node tree = tb.buildPredictiveModel(train).node;
      System.out.println(
          scorer.getClass().getSimpleName()
              + " build time "
              + (System.currentTimeMillis() - startTime)
              + ", size: "
              + tree.size()
              + " mean depth: "
              + tree.meanDepth());

      int correctlyClassified = 0;
      for (Instance testInstance : test) {
        String result = (String) tree.getLeaf(testInstance.getAttributes()).getBestClassification();
        if (result.equals(testInstance.getClassification())) {
          correctlyClassified++;
        }
      }
      System.out.println(", accuracy: " + (double) correctlyClassified / test.size());

      System.out.println("Testing random forest");

      for (int i = 2; i <= 20; i++) {
        RandomForestBuilder rfBuilder = new RandomForestBuilder(new TreeBuilder());
        RandomForest randomForest = rfBuilder.buildPredictiveModel(train);
        correctlyClassified = 0;
        for (Instance testInstance : test) {
          Serializable result =
              randomForest.getClassificationByMaxProb(testInstance.getAttributes());
          if (result.equals(testInstance.getClassification())) {
            correctlyClassified++;
          }
        }
        System.out.println(
            "accuracy with " + i + " trees: " + (double) correctlyClassified / test.size());
        // ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new
        // File("baggedTree.ser")));
        // out.writeObject(baggedTree);
      }
    }
  }
Example #16
0
  /**
   * Remove an element from the left digit.
   *
   * @param pos position inside the left digit
   * @return resulting tree
   */
  private FingerTree<N, E> removeLeft(final long pos) {
    if (left.length > 1) {
      // left digit cannot underflow, just delete the element
      return new DeepTree<>(remove(left, pos), leftSize - 1, middle, right, size - 1);
    }

    // singleton digit might underflow
    final Node<N, E> node = left[0];

    if (!middle.isEmpty()) {
      // next node for balancing is in middle tree
      final InnerNode<N, E> head = (InnerNode<N, E>) middle.head();
      final Node<N, E> first = head.getSub(0);
      final NodeLike<N, E>[] rem = node.remove(null, first, pos);
      final Node<N, E> newNode = (Node<N, E>) rem[1], newFirst = (Node<N, E>) rem[2];

      if (newNode == null) {
        // nodes were merged
        final Node<N, E>[] newLeft = head.children.clone();
        newLeft[0] = newFirst;
        return get(newLeft, middle.tail(), right, size - 1);
      }

      @SuppressWarnings("unchecked")
      final Node<N, E>[] newLeft = new Node[] {newNode};

      if (newFirst != first) {
        // nodes were balanced
        final FingerTree<Node<N, E>, E> newMid = middle.replaceHead(head.replaceFirst(newFirst));
        return new DeepTree<>(newLeft, newNode.size(), newMid, right, size - 1);
      }

      // no changes to this tree's structure
      return new DeepTree<>(newLeft, newNode.size(), middle, right, size - 1);
    }

    // potentially balance with right digit
    final NodeLike<N, E>[] rem = node.remove(null, right[0], pos);
    final Node<N, E> newNode = (Node<N, E>) rem[1], newFirstRight = (Node<N, E>) rem[2];

    if (newNode == null) {
      // nodes were merged
      if (right.length == 1) return new SingletonTree<>(newFirstRight);
      final int mid = right.length / 2;
      final Node<N, E>[] newLeft = slice(right, 0, mid);
      newLeft[0] = newFirstRight;
      return get(newLeft, middle, slice(right, mid, right.length), size - 1);
    }

    // structure does not change
    @SuppressWarnings("unchecked")
    final Node<N, E>[] newLeft = new Node[] {newNode};

    if (newFirstRight == right[0]) {
      // right digit stays the same
      return new DeepTree<>(newLeft, newLeft[0].size(), middle, right, size - 1);
    }

    // adapt the right digit
    final Node<N, E>[] newRight = right.clone();
    newRight[0] = newFirstRight;
    return new DeepTree<>(newLeft, newNode.size(), middle, newRight, size - 1);
  }