说我有很多整数。整数的数量可以在每组之间变化。我正在寻找' n'它们之间具有最独特整数的集合的数量。如果n = 4,那么我正在寻找所有可用集合中的4个集合,这些集合之间具有尽可能多的唯一整数(因此不计算重复数据集)。
答案 0 :(得分:1)
如果集合总数= N不是太大: 蛮力方法将是以下方法: 考虑每个(N选n)个可能的集合组合并评估它们形成的唯一整数的数量"在向量中合并和删除重复项,然后检查大小"直到你在所有评估后获得最大值。 从这开始,你可以通过使用动态编程或消除许多(N选择n),例如在找到一些MAX = K后,如果这个特定n组中的总数小于K,那么可以制作越来越高效的算法不评价......等等 这是一个让你开始的草稿
答案 1 :(得分:0)
您标记了C ++。如果我理解正确,以下内容就是您所描述的。由于std :: set无论如何都存储了唯一值,因此C ++代码解决方案变得简单明了。
#include <vector>
#include <set>
#include <algorithm>
#include <iostream>
typedef std::set<int> IntSet;
typedef std::vector<IntSet> IntSetV;
// sort the sets in ascending order, by size
bool SortBySetSize(const IntSet& s1, const IntSet& s2)
{ return s1.size() > s2.size(); }
void OutputResults(const IntSet& s)
{ std::cout << "There are " << s.size() << " unique integers in this set" << std::endl; }
void InputData(IntSet& s)
{
// routine to input data into s
}
using namespace std;
int main()
{
size_t nSets;
cout << "Enter number of sets: ";
cin >> nSets;
IntSetV VSets(nSets);
//... input to fill in the sets in the vector
for_each(VSets.begin(), VSets.end(), InputData);
// sort the sets by size
std::sort(VSets.begin(), VSets.end(), SortBySetSize);
// VSets now contains the N largest set of unique integers.
for_each(VSets.begin(), VSets.end(), OutputResults);
}
如果您需要记住原始输入值,可以存储
std::pair<std::vector<int>, IntSet> PairSet;
std::vector<PairSet> IntSetV;
对中的第一个值是原始向量,第二个值是表示向量中的数字的集合。然后可以使用通用代码解决方案,并添加必要的更改。
答案 2 :(得分:0)
这是NP难maximum coverage problem。贪婪算法(通过具有最新元素的集合来增长联合)实现了在最佳因子1 -1 / e(~63%)内的解决方案。尽管最大覆盖范围是NP难度的,integer programming通常可以找到“自然”实例的最佳解决方案(与智能设计的NP-硬度降低相比)。主要的挑战是整合解算器;特别是,求解器实现了所有相关算法。最直接的表达方式就是这个。
maximize sum_{elements e} x_e
subject to
for all elements e, x_e - sum_{input sets S such that e in S} y_S <= 0
sum_{input sets S} y_S <= n
for all elements e, 0 <= x_e <= 1
for all input sets S, y_S in {0, 1}
变量x_e
的含义是x_e
是否出现在联合中。 y_S
的含义是,1
如果S
出现在联合中,则为0
。