All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jamieswhiteshirt.rtree3i.RStarSplitter Maven / Gradle / Ivy

The newest version!
package com.jamieswhiteshirt.rtree3i;

import java.util.*;
import java.util.function.Function;
import java.util.function.ToIntFunction;

import com.google.common.base.Preconditions;

/**
 * An R*-tree splitter.
 */
public final class RStarSplitter implements Splitter {

    private final Comparator> groupsComparator;

    /**
     * Constructs an R*-tree splitter.
     */
    public RStarSplitter() {
        this.groupsComparator = com.jamieswhiteshirt.rtree3i.Comparators.groupsVolumeComparator.thenComparing(com.jamieswhiteshirt.rtree3i.Comparators.groupsIntersectionVolumeComparator);
    }

    @Override
    public  Groups split(List items, int minSize, Function boxMapper) {
        Preconditions.checkArgument(!items.isEmpty());
        // sort nodes into increasing x, calculate min overlap where both groups
        // have more than minChildren

        Map>> map = new EnumMap<>(SortType.class);
        for (SortType sortType : SortType.values()) {
            ToIntFunction accessor = item -> sortType.keyAccessor.applyAsInt(boxMapper.apply(item));
            Comparator comparator = Comparator.comparingInt(accessor);
            map.put(sortType, createPairs(minSize, sort(items, comparator), boxMapper));
        }

        // compute S the sum of all margin-values of the lists above
        // the list with the least S is then used to find minimum overlap

        SortType leastMarginSumSortType = Collections.min(sortTypes, marginSumComparator(map));
        List> pairs = map.get(leastMarginSumSortType);

        return Collections.min(pairs, groupsComparator);
    }

    private enum SortType {
        X1(Box::x1),
        X2(Box::x2),
        Y1(Box::y1),
        Y2(Box::y2),
        Z1(Box::z1),
        Z2(Box::z2);

        final ToIntFunction keyAccessor;

        SortType(ToIntFunction keyAccessor) {
            this.keyAccessor = keyAccessor;
        }
    }

    private static final List sortTypes = Collections
            .unmodifiableList(Arrays.asList(SortType.values()));

    private static  Comparator marginSumComparator(final Map>> map) {
        return Comparator.comparing(sortType -> marginValueSum(map.get(sortType)));
    }

    private static  int marginValueSum(List> list) {
        int sum = 0;
        for (Groups p : list)
            sum += p.getMarginSum();
        return sum;
    }

    static  List> createPairs(int minSize, List list, Function key) {
        List> pairs = new ArrayList>(list.size() - 2 * minSize + 1);
        for (int i = minSize; i < list.size() - minSize + 1; i++) {
            List list1 = list.subList(0, i);
            List list2 = list.subList(i, list.size());
            Groups pair = new Groups<>(Group.of(list1, key), Group.of(list2, key));
            pairs.add(pair);
        }
        return pairs;
    }

    private static  List sort(List items, Comparator comparator) {
        ArrayList list = new ArrayList<>(items);
        list.sort(comparator);
        return list;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy