2013-01-25 34 views
-1

我在这里有一个问题,我需要生成对象的所有可能的组合,并将它们存储在分析以后一个列表的所有组合..在互联网上生成一组对象

搜索包括很多算法这不符合存储组合的要求。 大多数常见搜索只是通过将它们打印出来而生成组合列表,而其他组件仅处理字符串而不是对象。

某些算法使用位来表示不同的组合,但此解决方案仅限于最多32个对象,这不够好。总的来说,我正在寻找一种算法,可以生成所有可能的组合(功率集),处理对象(超过32个),并且不限于仅打印出组合,而是存储这些组合在数组列表中。

+2

您是否有足够的内存(和计算能力)来生成和存储包含超过32个元素的集合的幂集?这样的功率集将包含数十亿的元素...... –

+0

要处理这种数据集,您需要建立一个完整的批量处理系统。忘掉天真的单一JVM解决方案。 –

回答

1

您是否考虑过将所有组合一次生成为一个潜在巨大且难以管理的数组,然后为数组中的每个条目编写一个生成器,从而制作一种伪数组,在访问条目时创建在飞行中进入。

下面是迭代器enum的代码,我在另一个问题中发布了一个更接近于此的代码。虽然它实现Iterator,但它在内部通过解码其索引并从动态索引索引的位模式中生成每个组合(请参阅private Enum[] get(int x)方法)。如果您愿意,应该可以将它扩展为使用BigInteger或甚至byte[]作为索引。

public class EnumIterator implements Iterator<Enum[]> { 
    // The enum classes 
    private final Class<? extends Enum>[] enums; 
    // The pseudo-position in the list. 
    private int i = 0; 
    // The total entries in the list. 
    private final int N; 

    // Construct from classes. 
    private EnumIterator(Class<? extends Enum>... enums) { 
    // Grab the enums. 
    this.enums = enums; 
    // Work out the Max as the product of all sets of constants. 
    int max = 1; 
    for (int n = 0; n < enums.length; n++) { 
     max *= enums[n].getEnumConstants().length; 
    } 
    N = max; 
    } 

    // Get that one from the possibles. 
    private Enum[] get(int x) { 
    // Make new array. 
    Enum[] next = new Enum[enums.length]; 
    // Fill it with the ith entry. 
    for (int j = next.length - 1; j >= 0; j--) { 
     Enum[] e = enums[j].getEnumConstants(); 
     // Pick the right one from it. 
     next[j] = e[x % e.length]; 
     // Fold out that enum. 
     x /= e.length; 
    } 
    return next; 
    } 

    @Override 
    public boolean hasNext() { 
    return i < N; 
    } 

    @Override 
    public Enum[] next() { 
    if (hasNext()) { 
     return get(i++); 
    } else { 
     throw new NoSuchElementException(); 
    } 
    } 

    @Override 
    public void remove() { 
    throw new UnsupportedOperationException("Not supported."); 
    } 

    enum ABC { 
    A, B, C; 
    } 

    enum XY { 
    X, Y; 
    } 

    enum IJ { 
    I, J; 
    } 

    enum OneTwoThree { 
    ONE, TWO, THREE 
    } 

    private static void test() { 
    // Also works - but constructing from classes is cleaner. 
    //Iterator<Enum[]> i = new EnumIterator(ABC.values(), XY.values(), IJ.values()); 
    System.out.println("ABC x XY x IJ"); 
    for (Enum[] e : Iterables.in(new EnumIterator(ABC.class, XY.class, IJ.class))) { 
     System.out.println(Arrays.toString(e)); 
    } 
    System.out.println("ABC"); 
    for (Enum[] e : Iterables.in(new EnumIterator(ABC.class))) { 
     System.out.println(Arrays.toString(e)); 
    } 
    System.out.println("ABC x OneTwoThree"); 
    for (Enum[] e : Iterables.in(new EnumIterator(ABC.class, OneTwoThree.class))) { 
     System.out.println(Arrays.toString(e)); 
    } 
    System.out.println("MT"); 
    for (Enum[] e : Iterables.in(new EnumIterator())) { 
     System.out.println(Arrays.toString(e)); 
    } 
    } 

    public static void main(String args[]) { 
    test(); 
    } 
}