如何按特定顺序获得电源设置?

时间:2011-07-05 08:37:09

标签: algorithm set

有一些计算功率集的解决方案,但我在谷歌上发现的这些并没有按顺序给出功率设置,我需要它。 例如,如果我想要(1,2,3,4)常用算法的功率集为我提供功率集 以下顺序:

()
(1)
(2)
(1 2)
(3)
(1 3)
(2 3)
(1 2 3)
(4)
(1 4)
(2 4)
(1 2 4)
(3 4)
(1 3 4)
(2 3 4)
(1 2 3 4)

但我需要的是以下顺序:

()
(1)
(2)
(3)
(4)
(1,2)
(1,3)
(1,4)
(2,3)
(2,4)
(3,4)
(1,2,3)
(1,2,4)
(1,3,4)
(2,3,4)
(1,2,3,4)

由于元素数量可能非常高,因此无法计算整个功率集并在之后对其进行排序。

有人有点想法吗?

3 个答案:

答案 0 :(得分:4)

(您应该提供一些有关您在Google上找到的算法的详细信息...)

但你可以这样处理:

first:创建一个函数,生成给定有序集的长度为n的所有幂集:

这是一个可能的伪代码:

set={a1, ...ap} //is an ordered set
define f( set , n):
   result = {}
   count=1
   for element in set :
         set.pop(element)
         result.append( { f(set,n-1).AppendtoAllInfirstPosition(element) }) // not sure if I write this well, but you process recursively, poping the sorted value one by one a1...ap and using f(popped set, n-1) you append the sets 
   if length(set)=n:
         return set //you initialise the recurence. the above loop will stop when len(popped(set))=n-1
   return result 

第二:完成此操作后,您只需确定:

f(set,i) for i in range(len(set)) and you will get your ordered power set.

希望这有效并且有所帮助

答案 1 :(得分:4)

您希望按长度顺序组合。在Python中,您可以写:

import itertools

def subsets(iterable):
    "Generate the subsets of elements in the iterable, in order by length."
    items = list(iterable)
    for k in xrange(len(items) + 1):
        for subset in itertools.combinations(items, k):
            yield subset

>>> list(subsets([1,2,3,4]))
[(), (1,), (2,), (3,), (4,), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4),
 (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4), (1, 2, 3, 4)]

有关生成组合的算法的概述,请参阅this answer。 (或者你可以看看Raymond Hettinger的Python实现,itertoolsmodule.c lines 2026f。)

答案 2 :(得分:3)

如果初始集合具有N个数字,则功率集将包含2 ^ N个元素。我建议如下

<强>算法:
按顺序生成所有初始集的子集,以增加其元素数量。例如,这可以通过考虑数组的所有排列来完成,包括k个和n-k个零(这也称为 掩码 )。每个掩码描述一个唯一的子集 - 我们只选择站在设置为1的位置上的元素。通过这个,我们将通过增加它们的大小来获得(打印,保存或任何需要的)所有子集,如果等于那么出现在初始集合中的元素的顺序。

<强>复杂度:
迭代2^N个掩码并查看每个N个位置会导致O( N * 2^N )复杂度。

<强>实施
这是我在C ++中的实现,使用std::next_permutation生成固定数量为ones的所有掩码。它从标准输入读取一组整数,然后生成并将所有子集打印到标准输出。请注意,如果没有必要,此解决方案 不会保存 子集:

#include <algorithm>
#include <iostream>
#include <vector>

void calcPowerSet( const std::vector< int >& inputSet )
{
    int n = inputSet.size();
    for( int ones = 0; ones <= n; ++ones )
    {
        std::vector< bool > mask( n, 0 );
        for( int i = 0; i < ones; ++i )
            mask[ i ] = true;           // setting first 'ones' bits to '1'
        do
        {   
           // printing the subset described by current mask
           std::cout << "(";
           for( int i = 0; i < n; ++i )
              if( mask[ i ] )
                  std::cout << ' ' << inputSet[ i ] << ' ';
           std::cout << ")\n";
        }
        while( std::next_permutation( mask.rbegin(), mask.rend() ) ); // generating masks
    }
}


int main ()
{
    int n;
    std::cin >> n;
    std::vector< int > inputSet( n );
    for( int i = 0; i < n; ++i )
        std::cin >> inputSet[ i ];
    calcPowerSet( inputSet );
    return 0;
}