Package cc.redberry.core.combinatorics

Source Code of cc.redberry.core.combinatorics.DistinctCombinationsPort

/*
* Redberry: symbolic tensor computations.
*
* Copyright (c) 2010-2012:
*   Stanislav Poslavsky   <stvlpos@mail.ru>
*   Bolotin Dmitriy       <bolotin.dmitriy@gmail.com>
*
* This file is part of Redberry.
*
* Redberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Redberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Redberry. If not, see <http://www.gnu.org/licenses/>.
*/
package cc.redberry.core.combinatorics;

import java.util.Arrays;

import cc.redberry.concurrent.OutputPortUnsafe;
import cc.redberry.core.utils.BitArray;
import cc.redberry.core.utils.LongBackedBitArray;

/**
*
* @author Dmitry Bolotin
* @author Stanislav Poslavsky
*/
public class DistinctCombinationsPort implements OutputPortUnsafe<int[]> {
    private final int[][] sets;
    private final BitArray previousMask;
    private final BitArray[] setMasks;
    private final int[] combination;
    private final BitArray temp;
    private byte state = -1;

    public DistinctCombinationsPort(int[][] sets) {
        this.sets = sets;
        int maxIndex = 0;
        for (int[] set : sets) {
            Arrays.sort(set);
            if (maxIndex < set[set.length - 1])
                maxIndex = set[set.length - 1];
        }
        ++maxIndex;
        previousMask = new LongBackedBitArray(maxIndex);
        temp = new LongBackedBitArray(maxIndex);

        setMasks = new BitArray[sets.length];
        for (int i = 0; i < sets.length; ++i) {
            setMasks[i] = new LongBackedBitArray(maxIndex);
            for (int j : sets[i])
                setMasks[i].set(j);
        }
        combination = new int[sets.length];
        previousMask.setAll();
        init();
    }

    private void init() {
        int i = 0, nextBit;
        while (i < setMasks.length) {

            temp.loadValueFrom(setMasks[i]);
            temp.and(previousMask);

            nextBit = temp.nextTrailingBit(combination[i]);
            if (nextBit != -1) {
                combination[i] = nextBit;
                previousMask.clear(nextBit);
            } else {
                if (i == 0) {
                    state = 1;
                    return;
                }
                combination[i] = 0;
                previousMask.set(combination[--i]);
                ++combination[i];
                continue;
            }
            ++i;
        }
    }

    @Override
    public int[] take() {
        if (state == 1)
            return null;

        if (state == -1) {
            state = 0;
            return combination;
        }
        previousMask.set(combination[setMasks.length - 1]++);

        int i = setMasks.length - 1, nextBit;
        while (i < setMasks.length) {

            temp.loadValueFrom(setMasks[i]);
            temp.and(previousMask);

            nextBit = temp.nextTrailingBit(combination[i]);
            if (nextBit != -1) {
                combination[i] = nextBit;
                previousMask.clear(nextBit);
            } else {
                if (i == 0) {
                    state = 1;
                    return null;
                }
                combination[i] = 0;
                previousMask.set(combination[--i]);
                ++combination[i];
                continue;
            }
            ++i;
        }

        return combination;
    }
}
TOP

Related Classes of cc.redberry.core.combinatorics.DistinctCombinationsPort

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.