我出于好奇心正在研究一个研究问题,我不知道如何编写我想到的逻辑。让我向你解释一下:
我有四个载体,比如说,
v1 = 1 1 1 1
v2 = 2 2 2 2
v3 = 3 3 3 3
v4 = 4 4 4 4
我想组合添加它们。也就是说,
v12 = v1+v2
v13 = v1+v3
v14 = v1+v4
v23 = v2+v3
v24 = v2+v4
v34 = v3+v4
直到这一步它很好。问题/技巧现在是,在每次迭代结束时,我将获得的矢量放入一个黑盒子函数,它只返回一些矢量,比如v12,v13和v34。现在,我想从v1,v2,v3,v4中添加这些向量中的每一个,它之前没有添加过。例如,v3和v4尚未添加到v12,因此我想创建v123和v124。类似地,对于所有的矢量,
v12 should become:
v123 = v12+v3
v124 = v12+v4
v13 should become:
v132 // This should not occur because I already have v123
v134 = v13+v4;
v14,v23和v24不予考虑 因为它被删除了黑色 盒子功能所以我们所拥有的一切 与之合作的是v12,v13和v34。
v34 should become:
v341 // Cannot occur because we have 134
v342 = v34+v2
重要的是,我不能在一开始就一步完成。例如,我可以做(4选3)4C3并完成它,但我想在每次迭代时一步一步地做。
如果包含黑匣子功能怎么做?
答案 0 :(得分:2)
好的,这里可能会提高效率,但我认为这可以满足您的需求。
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
typedef vector<int> v_t;
typedef set<int> s_t;
typedef map<s_t, v_t> m_t;
typedef vector<pair<s_t, v_t> > b_t;
// this inserts a new entry into the map with the provided key
// the value_type (vector) is generated by adding the entries in each vector
// NOTE: the first vector is passed by value (so we get a copy in the function)
// the second vector (passed by ref) is then added to it.
void insert_entry(m_t& dest, s_t& key, v_t vdest, v_t const& v2)
{
v_t::const_iterator it2(v2.begin());
// there is no global operator+ for vector, so you have to do something like below
for(v_t::iterator it(vdest.begin()), end(vdest.end()); it != end && (*(it++) += *(it2++)););
// this is just debug
cout << "new key: " << key.size() << " : ";
copy(key.begin(), key.end(), ostream_iterator<int>(cout, " "));
cout << endl;
cout << "vec: ";
copy(vdest.begin(), vdest.end(), ostream_iterator<int>(cout, " "));
// actual insert in to map
// for example, key may be set<1, 2> and value is vector <3, 3, 3, 3>
dest.insert(dest.end(), make_pair(key, vdest));
cout << "size of dest: " << dest.size() << endl;
}
// This function generates all unique combinations of a given size and inserts them into
// the main map
void gen_comb(size_t cmb, b_t const& base, m_t& dest)
{
typedef m_t::iterator m_it;
cout << "combination size: " << cmb << endl;
// Now calculate our starting vector key size, a "key" is imply a combination of
// vectors, e.g. v12, v23 v14 etc. in this case key size = 2 (i.e. two vectors)
// If we need to generate combinations of size 3 (cmb=3), then we start with all
// vectors of key size = 2 (v12, v23, v14 etc.) and add all the base (v1, v2 v3) to it
size_t s_ksz = cmb - 1; // search key size
cout << "search size: " << s_ksz << endl;
// now iterate through all entries in the map
for(m_it it(dest.begin()); it != dest.end(); ++it)
{
// Aha, the key size matches what we require (for example, to generate v123, we
// need v12 (key size == 2) first
if (it->first.size() == s_ksz)
{
// Now iterate through all base vectors (v1, v2, v3, v4)
for(b_t::const_iterator v_it(base.begin()), v_end(base.end()); v_it != v_end; ++v_it)
{
// new key, start with the main key from map, e.g. set<1, 2>
s_t nk(it->first.begin(), it->first.end());
// Add the base key set<3>, reason I do it this way is that, in case you
// that base vectors should be other than size 1 (else insert(*((*v_it)->first.begin())) should work just fine.
nk.insert(v_it->first.begin(), v_it->first.end());
// check if this key exists, this is the main check, this tests whether our map
// already has a key with the same vectors (for example, set<1,2,3> == set<2,3,1> - internally set is ordered)
m_it k_e = dest.find(nk);
// If the key (combination of vectors) does not exist, then insert a new entry
if (k_e == dest.end())
{
// new key
insert_entry(dest, nk, it->second, v_it->second);
}
}
}
}
}
void trim(size_t depth, m_t& dest)
{
for(m_t::iterator it(dest.begin()); it != dest.end();)
{
if (it->first.size() == depth && (rand() % 2))
{
cout << "removing key: " << depth << " : ";
copy(it->first.begin(), it->first.end(), ostream_iterator<int>(cout, " "));
cout << endl;
dest.erase(it++);
}
else
++it;
}
}
int main(void)
{
// combination map
m_t dest;
// this is the set of bases
b_t bases;
int max_i = 4;
for(int i = 1; i <= max_i; ++i)
{
v_t v(4, i);
s_t k;
k.insert(i);
bases.push_back(make_pair(k, v));
}
// for the start, push in the bases
dest.insert(bases.begin(), bases.end());
// for each combination size, generate a new set of vectors and then trim that set.
for (size_t cmb = 1; cmb <= static_cast<size_t>(max_i); ++cmb)
{
if (cmb > 1) gen_comb(cmb, bases, dest);
trim(cmb, dest); // randomly remove some entries...
}
return 0;
}
注意:
trim
函数为您的黑匣子建模,它会从主地图中删除一些具有给定密钥大小的条目(与最近生成的组合大小相同)编辑:
好了,现在base
是一个向量,其中包含pair
的关键&lt; - &gt;向量关系 - 这是常量。最初它被添加到地图中,并且初始状态跳过gen_comb
函数,仍然会调用trim
来删除一些条目。下一次迭代使用相同的搜索算法,但组合使用base
s的常量集。