Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm N选择K的迭代算法,无重复,顺序重要_Algorithm_Iteration_Permutation - Fatal编程技术网

Algorithm N选择K的迭代算法,无重复,顺序重要

Algorithm N选择K的迭代算法,无重复,顺序重要,algorithm,iteration,permutation,Algorithm,Iteration,Permutation,我正在寻找一种迭代算法,以获得从一组N个元素中提取的K个元素的所有排列,无需重复(即,无替换),并且顺序很重要。 我知道排列的数量必须是N/(N-K)!。 你有什么想法吗? 多谢各位 Ivan方法1: [0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]. [0,1,2] // initialization [0,2,1] // next permutation ... // all perm

我正在寻找一种迭代算法,以获得从一组N个元素中提取的K个元素的所有排列,无需重复(即,无替换),并且顺序很重要。 我知道排列的数量必须是N/(N-K)!。 你有什么想法吗? 多谢各位


Ivan方法1:

[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2]    // initialization
[0,2,1]    // next permutation
...        // all permutations of [0,1,2]
...
[2,1,0]    // reached last permutation of current selection
[0,1,3]    // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0]   // reached last permutation of current selection
[0,2,3]    // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0]   // reached last permutation of current selection
[1,2,3]    // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1]   // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
    int k = (int)a.size();
    if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
    // if `a` was already in descending order, 
    // next_permutation returned false and changed the array to sorted order.
    // now find next combination if possible
    for (int i = k - 1; i >= 0; i--) {
        if (a[i] < n - k + i + 1) {
            a[i]++;
            for (int j = i + 1; j < k; j++)
                a[j] = a[j - 1] + 1;
            return true;
        }
    }
    return false;
}
更简单的想法:

[0, 1, 2],
[0, 2, 1],
[1, 0, 2],
[1, 2, 0],
[2, 0, 1],
[2, 1, 0].
[0,1,2]    // initialization
[0,2,1]    // next permutation
...        // all permutations of [0,1,2]
...
[2,1,0]    // reached last permutation of current selection
[0,1,3]    // get next selection in lexicographic order as permutations are exhausted
...
[3,1,0]   // reached last permutation of current selection
[0,2,3]    // get next selection in lexicographic order as permutations are exhausted
...
[3,2,0]   // reached last permutation of current selection
[1,2,3]    // get next selection in lexicographic order as permutations are exhausted
...
[3,2,1]   // reached last permutation of current selection
bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
    int k = (int)a.size();
    if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
    // if `a` was already in descending order, 
    // next_permutation returned false and changed the array to sorted order.
    // now find next combination if possible
    for (int i = k - 1; i >= 0; i--) {
        if (a[i] < n - k + i + 1) {
            a[i]++;
            for (int j = i + 1; j < k; j++)
                a[j] = a[j - 1] + 1;
            return true;
        }
    }
    return false;
}
由于顺序很重要,我们将尝试使用
下一个排列
next\u permutation
函数提供了next字典中唯一的排列

算法

  • 创建一个大小等于原始数组大小的新数组
  • 分配最后k个数字1,2,3,…k,使k最后结束。将剩余的数字指定为0
  • 现在,当使用
    next\u permutation
    迭代置换时,只选择原始数组中值为>0的索引,保持顺序
  • 正确性说明:

    [0, 1, 2],
    [0, 2, 1],
    [1, 0, 2],
    [1, 2, 0],
    [2, 0, 1],
    [2, 1, 0].
    
    [0,1,2]    // initialization
    [0,2,1]    // next permutation
    ...        // all permutations of [0,1,2]
    ...
    [2,1,0]    // reached last permutation of current selection
    [0,1,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,1,0]   // reached last permutation of current selection
    [0,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,0]   // reached last permutation of current selection
    [1,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,1]   // reached last permutation of current selection
    
    bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
        int k = (int)a.size();
        if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
        // if `a` was already in descending order, 
        // next_permutation returned false and changed the array to sorted order.
        // now find next combination if possible
        for (int i = k - 1; i >= 0; i--) {
            if (a[i] < n - k + i + 1) {
                a[i]++;
                for (int j = i + 1; j < k; j++)
                    a[j] = a[j - 1] + 1;
                return true;
            }
        }
        return false;
    }
    
    因为在新创建的数组中有N个重复的N-k个数,所以总的唯一排列变为N/(N-k)!这给了我们想要的结果

    示例:

    [0, 1, 2],
    [0, 2, 1],
    [1, 0, 2],
    [1, 2, 0],
    [2, 0, 1],
    [2, 1, 0].
    
    [0,1,2]    // initialization
    [0,2,1]    // next permutation
    ...        // all permutations of [0,1,2]
    ...
    [2,1,0]    // reached last permutation of current selection
    [0,1,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,1,0]   // reached last permutation of current selection
    [0,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,0]   // reached last permutation of current selection
    [1,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,1]   // reached last permutation of current selection
    
    bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
        int k = (int)a.size();
        if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
        // if `a` was already in descending order, 
        // next_permutation returned false and changed the array to sorted order.
        // now find next combination if possible
        for (int i = k - 1; i >= 0; i--) {
            if (a[i] < n - k + i + 1) {
                a[i]++;
                for (int j = i + 1; j < k; j++)
                    a[j] = a[j - 1] + 1;
                return true;
            }
        }
        return false;
    }
    
    输入:X=[1,2,3],k=2

    现在,我们创建一个=[0,1,2]

    所有排列:

    [0, 1, 2],
    [0, 2, 1],
    [1, 0, 2],
    [1, 2, 0],
    [2, 0, 1],
    [2, 1, 0].
    
    [0,1,2]    // initialization
    [0,2,1]    // next permutation
    ...        // all permutations of [0,1,2]
    ...
    [2,1,0]    // reached last permutation of current selection
    [0,1,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,1,0]   // reached last permutation of current selection
    [0,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,0]   // reached last permutation of current selection
    [1,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,1]   // reached last permutation of current selection
    
    bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
        int k = (int)a.size();
        if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
        // if `a` was already in descending order, 
        // next_permutation returned false and changed the array to sorted order.
        // now find next combination if possible
        for (int i = k - 1; i >= 0; i--) {
            if (a[i] < n - k + i + 1) {
                a[i]++;
                for (int j = i + 1; j < k; j++)
                    a[j] = a[j - 1] + 1;
                return true;
            }
        }
        return false;
    }
    
    仅从原始数组中选择这些置换的索引i,其中[i]>0将产生

    [2,3],
    [3,2],
    [1,3],
    [1,2],
    [3,1],
    [2,1].
    
    如果您希望按排序顺序执行上述操作,请使用负数,并使用-k、-k-1、…-1初始化前k个数字,剩余的数字为0,并通过在原始数组中选择索引i来应用算法,以便在保持顺序的同时[i]<0

    旁注: 如果顺序不重要,则在开始处用
    k
    -1s初始化
    A
    ,剩余的0,并使用迭代排列算法,该算法将从N个项目中生成唯一的可能k个选择

    方法2:(优于方法1)

    算法:

    [0, 1, 2],
    [0, 2, 1],
    [1, 0, 2],
    [1, 2, 0],
    [2, 0, 1],
    [2, 1, 0].
    
    [0,1,2]    // initialization
    [0,2,1]    // next permutation
    ...        // all permutations of [0,1,2]
    ...
    [2,1,0]    // reached last permutation of current selection
    [0,1,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,1,0]   // reached last permutation of current selection
    [0,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,0]   // reached last permutation of current selection
    [1,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,1]   // reached last permutation of current selection
    
    bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
        int k = (int)a.size();
        if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
        // if `a` was already in descending order, 
        // next_permutation returned false and changed the array to sorted order.
        // now find next combination if possible
        for (int i = k - 1; i >= 0; i--) {
            if (a[i] < n - k + i + 1) {
                a[i]++;
                for (int j = i + 1; j < k; j++)
                    a[j] = a[j - 1] + 1;
                return true;
            }
        }
        return false;
    }
    
  • 首先选择前K个数字并填充到数组
    A
    ,它将存储原始数组中所选元素的索引。我们把它列为第一选择
  • 现在按字典顺序获取所有剩余的排列
  • 考虑订单,如何获得下一个组合?如果可能的话,我们将排列选择,否则将返回按字典顺序排列的更大选择
  • 如果排列已用尽,则按词汇顺序获取下一个选择的想法:

    [0, 1, 2],
    [0, 2, 1],
    [1, 0, 2],
    [1, 2, 0],
    [2, 0, 1],
    [2, 1, 0].
    
    [0,1,2]    // initialization
    [0,2,1]    // next permutation
    ...        // all permutations of [0,1,2]
    ...
    [2,1,0]    // reached last permutation of current selection
    [0,1,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,1,0]   // reached last permutation of current selection
    [0,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,0]   // reached last permutation of current selection
    [1,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,1]   // reached last permutation of current selection
    
    bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
        int k = (int)a.size();
        if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
        // if `a` was already in descending order, 
        // next_permutation returned false and changed the array to sorted order.
        // now find next combination if possible
        for (int i = k - 1; i >= 0; i--) {
            if (a[i] < n - k + i + 1) {
                a[i]++;
                for (int j = i + 1; j < k; j++)
                    a[j] = a[j - 1] + 1;
                return true;
            }
        }
        return false;
    }
    
    我们考虑当前的组合,找出最右边的元素。 这还没有达到可能的最高值。一旦找到这个 元素,我们将其递增1,并为 所有后续元素

    发件人:

    示例:

    [0, 1, 2],
    [0, 2, 1],
    [1, 0, 2],
    [1, 2, 0],
    [2, 0, 1],
    [2, 1, 0].
    
    [0,1,2]    // initialization
    [0,2,1]    // next permutation
    ...        // all permutations of [0,1,2]
    ...
    [2,1,0]    // reached last permutation of current selection
    [0,1,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,1,0]   // reached last permutation of current selection
    [0,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,0]   // reached last permutation of current selection
    [1,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,1]   // reached last permutation of current selection
    
    bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
        int k = (int)a.size();
        if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
        // if `a` was already in descending order, 
        // next_permutation returned false and changed the array to sorted order.
        // now find next combination if possible
        for (int i = k - 1; i >= 0; i--) {
            if (a[i] < n - k + i + 1) {
                a[i]++;
                for (int j = i + 1; j < k; j++)
                    a[j] = a[j - 1] + 1;
                return true;
            }
        }
        return false;
    }
    
    输入:X=[1,2,3,4],k=3

    现在,我们创建一个=[0,1,2]

    所有排列:

    [0, 1, 2],
    [0, 2, 1],
    [1, 0, 2],
    [1, 2, 0],
    [2, 0, 1],
    [2, 1, 0].
    
    [0,1,2]    // initialization
    [0,2,1]    // next permutation
    ...        // all permutations of [0,1,2]
    ...
    [2,1,0]    // reached last permutation of current selection
    [0,1,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,1,0]   // reached last permutation of current selection
    [0,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,0]   // reached last permutation of current selection
    [1,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,1]   // reached last permutation of current selection
    
    bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
        int k = (int)a.size();
        if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
        // if `a` was already in descending order, 
        // next_permutation returned false and changed the array to sorted order.
        // now find next combination if possible
        for (int i = k - 1; i >= 0; i--) {
            if (a[i] < n - k + i + 1) {
                a[i]++;
                for (int j = i + 1; j < k; j++)
                    a[j] = a[j - 1] + 1;
                return true;
            }
        }
        return false;
    }
    
    代码(基于0的索引,因此从0-k-1初始化开始):

    [0, 1, 2],
    [0, 2, 1],
    [1, 0, 2],
    [1, 2, 0],
    [2, 0, 1],
    [2, 1, 0].
    
    [0,1,2]    // initialization
    [0,2,1]    // next permutation
    ...        // all permutations of [0,1,2]
    ...
    [2,1,0]    // reached last permutation of current selection
    [0,1,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,1,0]   // reached last permutation of current selection
    [0,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,0]   // reached last permutation of current selection
    [1,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,1]   // reached last permutation of current selection
    
    bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
        int k = (int)a.size();
        if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
        // if `a` was already in descending order, 
        // next_permutation returned false and changed the array to sorted order.
        // now find next combination if possible
        for (int i = k - 1; i >= 0; i--) {
            if (a[i] < n - k + i + 1) {
                a[i]++;
                for (int j = i + 1; j < k; j++)
                    a[j] = a[j - 1] + 1;
                return true;
            }
        }
        return false;
    }
    
    bool-next\u-composition\u与顺序(向量&a,int-n,bool-order\u-matters=true){
    int k=(int)a.size();
    if(order_matters&&std::next_排列(a.begin(),a.end())返回True;//检查下一个排列是否存在,否则向前移动并获得下一个唯一组合
    //如果'a'已经按降序排列,
    //接下来,置换返回false并将数组更改为排序顺序。
    //如果可能,现在找到下一个组合
    对于(int i=k-1;i>=0;i--){
    if(a[i]
    参考文献:

    [0, 1, 2],
    [0, 2, 1],
    [1, 0, 2],
    [1, 2, 0],
    [2, 0, 1],
    [2, 1, 0].
    
    [0,1,2]    // initialization
    [0,2,1]    // next permutation
    ...        // all permutations of [0,1,2]
    ...
    [2,1,0]    // reached last permutation of current selection
    [0,1,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,1,0]   // reached last permutation of current selection
    [0,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,0]   // reached last permutation of current selection
    [1,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,1]   // reached last permutation of current selection
    
    bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
        int k = (int)a.size();
        if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
        // if `a` was already in descending order, 
        // next_permutation returned false and changed the array to sorted order.
        // now find next combination if possible
        for (int i = k - 1; i >= 0; i--) {
            if (a[i] < n - k + i + 1) {
                a[i]++;
                for (int j = i + 1; j < k; j++)
                    a[j] = a[j - 1] + 1;
                return true;
            }
        }
        return false;
    }
    
    下一个排列:

    [0, 1, 2],
    [0, 2, 1],
    [1, 0, 2],
    [1, 2, 0],
    [2, 0, 1],
    [2, 1, 0].
    
    [0,1,2]    // initialization
    [0,2,1]    // next permutation
    ...        // all permutations of [0,1,2]
    ...
    [2,1,0]    // reached last permutation of current selection
    [0,1,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,1,0]   // reached last permutation of current selection
    [0,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,0]   // reached last permutation of current selection
    [1,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,1]   // reached last permutation of current selection
    
    bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
        int k = (int)a.size();
        if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
        // if `a` was already in descending order, 
        // next_permutation returned false and changed the array to sorted order.
        // now find next combination if possible
        for (int i = k - 1; i >= 0; i--) {
            if (a[i] < n - k + i + 1) {
                a[i]++;
                for (int j = i + 1; j < k; j++)
                    a[j] = a[j - 1] + 1;
                return true;
            }
        }
        return false;
    }
    

    下一个无顺序组合:

    [0, 1, 2],
    [0, 2, 1],
    [1, 0, 2],
    [1, 2, 0],
    [2, 0, 1],
    [2, 1, 0].
    
    [0,1,2]    // initialization
    [0,2,1]    // next permutation
    ...        // all permutations of [0,1,2]
    ...
    [2,1,0]    // reached last permutation of current selection
    [0,1,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,1,0]   // reached last permutation of current selection
    [0,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,0]   // reached last permutation of current selection
    [1,2,3]    // get next selection in lexicographic order as permutations are exhausted
    ...
    [3,2,1]   // reached last permutation of current selection
    
    bool next_combination_with_order(vector<int>& a, int n, bool order_matters=true) {
        int k = (int)a.size();
        if(order_matters && std::next_permutation(a.begin(), a.end()))return True; // check if next permutation exists otherwise move forward and get next unique combination
        // if `a` was already in descending order, 
        // next_permutation returned false and changed the array to sorted order.
        // now find next combination if possible
        for (int i = k - 1; i >= 0; i--) {
            if (a[i] < n - k + i + 1) {
                a[i]++;
                for (int j = i + 1; j < k; j++)
                    a[j] = a[j - 1] + 1;
                return true;
            }
        }
        return false;
    }
    

    不必构建所有排列,因为只有N个/(N-K)!有效的“next_置换函数给出了next字典唯一的置换”。在新创建的数组
    A
    中有
    N-k
    重复的
    0
    值。所以会有N/(N-k)!独特的排列。伟大的答案!非常感谢。欢迎光临,很高兴它有帮助!如果顺序不重要怎么办?如何才能获得N/(k!(N-k)!)独特的组合?