生成列表的电源集

Generating the power set of a list

本文关键字:电源 列表      更新时间:2023-10-16

我必须编写背包问题的暴力实现。这是伪代码:

computeMaxProfit(weight_capacity)
    max_profit = 0
    S = {} // Each element of S is a weight-profit pair.
    while true
        if the sum of the weights in S <= weight_capacity
            if the sum of the profits in S > max_profit
                update max_profit
        if S contains all items // Then there is no next subset to generate
            return max
        generate the next subset S

虽然该算法很容易实现,但我完全不知道如何生成S的幂集,以及如何将幂集的子集输入While循环的每次迭代。

我目前的实现使用一个成对的列表来保持物品的重量和利润:

list< pair<int, int> > weight_profit_pair;

我想为我的computeMaxProfit函数生成这个列表的幂集。有没有一种算法可以生成列表的子集?列表是正确的容器吗?

这里有两个函数可以完成任务:

// Returns which bits are on in the integer a                                                                                                                                                                                              
vector<int> getOnLocations(int a) {
  vector<int> result;
  int place = 0;
  while (a != 0) {
    if (a & 1) {
      result.push_back(place);
    }
    ++place;
    a >>= 1;
  }
  return result;
}
template<typename T>
vector<vector<T> > powerSet(const vector<T>& set) {
  vector<vector<T> > result;
  int numPowerSets = static_cast<int>(pow(2.0, static_cast<double>(set.size())));
  for (size_t i = 0; i < numPowerSets; ++i) {
    vector<int> onLocations = getOnLocations(i);
    vector<T> subSet;
    for (size_t j = 0; j < onLocations.size(); ++j) {
      subSet.push_back(set.at(onLocations.at(j)));
    }
    result.push_back(subSet);
  }
  return result;
}

numPowerSets使用了Marcelo在这里提到的关系。正如LiKao所提到的,矢量似乎是一种自然的方式。当然,不要用大套试试这个!

不要使用列表,而是使用任何类型的随机访问数据结构,例如std::vector。如果您现在有另一个std::vector<bool>,您可以将这两个结构一起使用来表示幂集的一个元素。即,如果位置x处的bool为真,则位置x处的元素在子集中。

现在,您必须对幂集中的所有集合进行迭代。也就是说,你必须从每个当前子集生成下一个子集,这样所有的集合都会生成。这只是std::vector<bool>上的二进制计数。

如果集合中的元素少于64个,则可以使用长整数进行计数,并在每次迭代时获得二进制表示。

数字集S={0,1,2,…,2n-1}形成比特集{1,2,4,…,2*sup>n-1}的幂集。对于集合S中的每个数字,通过将数字的每个位映射到集合中的一个元素来导出原始集合的子集。由于对所有64位整数进行迭代是很困难的,因此您应该能够在不使用bigint库的情况下完成此操作。