组合分布数组计算:
从m个样本中抽取n个,进行组合分布。
例如:从[0,1,2,3]中抽取2个的组合分布为:[0,1], [0,2], [1,2], [0,3], [1,3], [2,3]六种情况。
/*
@function: CombinationArray
@brief:m个数中取n个数的组合分布
@param [i] m 样本总数 [0, 1 , ... , m-1]
@param [i] n 抽样个数
@param [o] res 组合分布数组
@return: <=0代表运行错误;>0代表:组合分布数组的组数
@warn:函数返回的是组合的组数,不是内存所需大小。
* 内存所需大小=组合数*n
*/
int CombinationArray(int m, int n, int* res) {
if (m < n || n < 0 || m < 0)
return -1;
// 生成n个位置(值,最小,最大)
int* seat = new int[n*3];
// 初始化位置
for (int i = 0; i < n; ++i) {
seat[i] = i; // 该位置的号码
seat[i + n] = i; // 该位置的最小号码
seat[i + n + n] = i + m - n; // 该位置的最大号码
}
// 计算组合分布
int cnt = 0;
while (cnt > -1) {
// 数据输出与统计
if (res) {
memcpy(res, seat, sizeof(int)*n);
res += n;
}
++cnt;
// 最小位置变化
seat[0]++;
// 变化产生的进位检查
for (int i = 0; i < n; ++i) {
if (seat[i] > seat[i + 2 * n] || (seat[i] == seat[i + 1] && (i + 1 < n))) {
// 进位
if (i == n - 1) {
cnt = -cnt;
break;
}
seat[i] = seat[i + n];
seat[i + 1]++;
}
}
}
// 返回组合数
return -cnt;
}
代码测试:
int main()
{
int m = 4;
int n = 2;
// 计算组合数
int num = CombinationArray(m, n, NULL);
if (num < 0)
{
std::cout << "参数出错" << std::endl;
return 0;
}
// 开辟组合分布的内存空间:组合数*每组的样本数(抽样数)
int* buf = new int[num*n];
// 计算组合分布
num = CombinationArray(m, n, buf);
// 输出组合分布
std::cout << "num:" << num << std::endl;;
for (int i = 0; i < num; ++i) {
std::cout << "[";
for (int j = 0; j < n; ++j) {
std::cout << buf[i*n + j] << " ";
}
std::cout << "]" << std::endl;
}
std::cout << std::endl;
return 0;
}
测试结果:
num:6
[0 1 ]
[0 2 ]
[1 2 ]
[0 3 ]
[1 3 ]
[2 3 ]
Python语言使用itertools库计算排列组合分布:
# -*- coding: utf-8 -*-
#从itertools导入
from itertools import permutations, combinations
#排列:[0,1,2]中取2的所有排列情况
list(permutations([0,1,2],2))
#组合:[0,1,2,3]中取2的所有组合情况
list(combinations([0,1,2,3],2))
运行结果:
C:\Users\mylaf>python
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> #从itertools导入
... from itertools import permutations, combinations
>>>
>>> #排列:[0,1,2]中取2的所有排列情况
... list(permutations([0,1,2],2))
[(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)]
>>>
>>> #组合:[0,1,2,3]中取2的所有组合情况
... list(combinations([0,1,2,3],2))
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
>>>