提高在某个时间间隔内生成minHeaps的算法的效率

时间:2018-03-28 07:19:21

标签: algorithm heap

对于给定的自然数n,为了生成所有的最小堆,例如对于n = 4,总堆是3,对于更大的n值,应该生成有限的堆,如20-30,超过合理的interva

  1. 1 2 3 4
  2. 1 2 4 3
  3. 1 3 2 4

    我提出了以下想法来生成所有堆。 从i开始循环从1到n并将i推送到矢量也将其标记为已使用。现在递归函数并且如果标记为continue,那么在添加i的情况下,如果父级已经更大,则继续使用下一个值,因为这将构成无效堆。请参考下面的代码,我想我做了一个糟糕的工作来解释。问题是n = 16或n = 17需要太多时间。我尝试通过减少计算来优化它,其中向量的第一个元素不是1。

  4. 我想提出改进效率的建议或任何其他算法来有效地生成所有最小堆。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    vector<int> v;
    int n,k ;
    int cnt = 0 ;
    vector<int> p(100,0);
    
    void gen(){
        if(v.size() == n){
            cnt++;
            if(cnt % k == 0){
                for(auto x : v){
                    cout<<x<<" ";
                }
                cout<<endl;
            }
    
        }
        else{
    
            for(int i = 1 ; i <= n ; i++){
    
                if(v.size() and v[0] != 1 ){
                    return ;
                }
                if(p[i])
                    continue;
    
    
                int x = v.size();
                int parent ;
                if(x & 1){
                    parent = (x-1)/2;
                }
                else
                    parent = (x-2)/2;
    
                if(x==0)
                    parent = 0 ; 
    
                if(v.size() and v[parent] > i ){
                    continue ;
                }
    
    
                p[i] = 1;
                v.push_back(i);
                gen();
                p[i] = 0;
                v.pop_back();
            }
        }
    }
    int main(){
        //ios_base::sync_with_stdio(false);cin.tie(NULL);
        cin>>n>>k;
        gen();
        cout<<"TOTAL "<<cnt<<endl;
    
    }
    

1 个答案:

答案 0 :(得分:0)

当您处理10个或更多项目时,一种可能效果很好的简单方法是随机化一个数组,然后使用build-heap函数将其转换为堆。泡沫,冲洗,重复。

您每次都必须检查新堆是否与任何现有堆匹配,但如果您只生成20或30堆,则不会是巨大的性能问题。

我承认这个解决方案不是最有效的,但它应该能够合理地快速完成工作。

供参考,build-heap功能:

for (int i = v.size/2; i >= 0; --i)
{
    siftDown(i);
}