组合个数

/// <summary>
/// <paramref name="n"/>个元素集合中所有<paramref name="m"/>个元素组合的个数。
/// <paramref name="m"/> &gt;= 0; <paramref name="n"/> &gt;= 0
/// </summary>
public static int BinomialCoefficient(int n, int m)
{if (n < 0)throw new ArgumentOutOfRangeException("n should be nonegative");if (m < 0)throw new ArgumentOutOfRangeException("m should be nonegative");if (n < m) return 0;if (n == m) return 1;if (m == 0) return 1;return BinomialCoefficient(n - 1, m - 1) + BinomialCoefficient(n - 1, m);
}

Lexicographic(字典顺序)

给定两个整数n, m(1 < m < n),升序返回int[]集合,数组里的数字代表索引。譬如n = 6, m = 3时,返回

210,310,320,321,410,420,421,430,431,432,510,520,521,530,531,532,540,541,542,543

对于任意n个元素的集合,根据索引选取对应元素就可以得到该集合的所有m个元素组合。

/// <summary>
/// <paramref name="n"/>个元素集合中所有<paramref name="m"/>个元素组合。
/// </summary>
public static IEnumerable<int[]> Lexicographic(int n, int m)
{if (n < 2)throw new ArgumentOutOfRangeException("n shouble be greater than 1");if (m < 1 || m > n)throw new ArgumentOutOfRangeException("m shouble be positive and not greater than " + n);var pos = new int[m + 3];pos[m + 1] = n;for (int i = 1; i <= m; ++i)pos[i] = i - 1;var result = new List<int[]>();while (true){var combination = pos.Skip(1).Take(m).Reverse().ToArray();result.Add(combination);var index = 1;while (pos[index] + 1 == pos[index + 1]){pos[index] = index - 1;++index;}if (index > m) break;++pos[index];}return result;
}/// <summary>
/// <paramref name="n"/>个元素集合中所有<paramref name="m"/>个元素组合。
/// </summary>
public static IEnumerable<int[]> FastLexicographic(int n, int m)
{if (n < 2)throw new ArgumentOutOfRangeException("n shouble be greater than 1");if (m < 1 || m > n)throw new ArgumentOutOfRangeException("m shouble be positive and not greater than " + n);var pos = new int[m + 3];pos[m + 1] = n;for (int i = 1; i <= m; ++i)pos[i] = i - 1;var result = new List<int[]>();var index = m;while (true){var combination = pos.Skip(1).Take(m).Reverse().ToArray();result.Add(combination);int tmp;if (index > 0)tmp = index;else{if (pos[1] + 1 < pos[2]){++pos[1];continue;}elseindex = 2;while (true){pos[index - 1] = index - 2;tmp = pos[index] + 1;if (tmp != pos[index + 1]) break;++index;}if (index > m) break;}pos[index] = tmp;--index;}return result;
}/// <summary>
/// <paramref name="n"/>个元素集合中所有<paramref name="m"/>个元素组合。
/// </summary>
public static IEnumerable<int[]> DecreasingLexicographic(int n, int m)
{if (n < 2)throw new ArgumentOutOfRangeException("n shouble be greater than 1");if (m < 1 || m > n)throw new ArgumentOutOfRangeException("m shouble be positive and not greater than " + n);var pos = new int[m + 1];for (int i = 1; i < pos.Length; ++i)pos[i] = i + n - m - 1;var result = new List<int[]>();var index = 1;while (true){var combination = pos.Skip(1).Take(m).Reverse().ToArray();result.Add(combination);if (index > m) break;--pos[index];if (pos[index] < index){++index;continue;}while (index > 1){pos[index - 1] = pos[index] - 1;--index;}}return result;
}

Revolving-Door

n = 6, m = 3时返回

210,320,321,310,430,431,432,420,421,410,540,541,542,543,530,531,532,520,521,510

/// <summary>
/// <paramref name="n"/>个元素集合中所有<paramref name="m"/>个元素组合。
/// </summary>
public static IEnumerable<int[]> RevolvingDoor(int n, int m)
{if (n < 2)throw new ArgumentOutOfRangeException("n shouble be greater than 1");if (m < 1 || m > n)throw new ArgumentOutOfRangeException("m shouble be positive and not greater than " + n);var pos = new int[m + 3];pos[m + 1] = n;for (int i = 1; i <= m; ++i)pos[i] = i - 1;var result = new List<int[]>();var flag = true;while (flag){var combination = pos.Skip(1).Take(m).Reverse().ToArray();result.Add(combination);var condition = false;int index;if (IsEven(m)){if (pos[1] > 0){--pos[1];continue;}else{index = 2;condition = true;}}else{if (pos[1] + 1 < pos[2]){++pos[1];continue;}elseindex = 2;}while (true){if (!condition){if (pos[index] >= index){pos[index] = pos[index - 1];pos[index - 1] = index - 2;break;}else++index;}elsecondition = false;if (pos[index] + 1 < pos[index + 1]){pos[index - 1] = pos[index];++pos[index];break;}else if (++index > m){flag = false;break;}}}return result;
}

Chase Sequence(这几个方法中最好的组合方法)

/// <summary>
/// <paramref name="n"/>个元素集合中所有<paramref name="m"/>个元素组合。
/// </summary>
public static IEnumerable<int[]> ChaseSequence(int n, int m)
{if (n < 2)throw new ArgumentOutOfRangeException("n shouble be greater than 1");if (m < 1 || m > n)throw new ArgumentOutOfRangeException("m shouble be positive and not greater than " + n);var pos = new int[n];for (var i = n - m; i < pos.Length; ++i)pos[i] = 1;var aux = new int[n + 1];Array.Fill(aux, 1);var result = new List<int[]>();var tmp = n - m;while (true){var combination = new int[m];for (int i = 0, j = 0; i < pos.Length; ++i)if (pos[i] == 1)combination[j++] = i;result.Add(combination);var index = tmp;if (aux[index] == 0)while (aux[index] != 1)aux[index++] = 1;if (index == n) break;aux[index] = 0;if (pos[index] == 0){if (!IsEven(index) && pos[index - 1] == 0){pos[index] = 1;pos[index - 2] = 0;if (tmp == index - 2)tmp = index;else if (tmp == index - 1)tmp = index - 2;}else{pos[index] = 1;pos[index - 1] = 0;if (tmp == index && index > 1)tmp = index - 1;else if (tmp == index - 1)tmp = index;}}else{if (IsEven(index) && pos[index - 2] == 0){pos[index - 2] = 1;pos[index] = 0;if (tmp == index)tmp = Math.Max(index - 2, 1);else if (tmp == index - 2)tmp = index - 1;}else{pos[index - 1] = 1;pos[index] = 0;if (tmp == index && index > 1){tmp = index - 1;}else if (tmp == index - 1){tmp = index;}}}}return result;
}public static bool IsEven(int n) => (n & 1) == 0;

Fixed Length Binary Sequence(n个0和m个1的所有组合)

譬如numberOfZero = 2, numberOfOne = 3返回

11100,01110,10110,11010,01101,10101,01011,00111,10011,11001

/// <summary>
/// 返回长度为<paramref name="numberOfZero"/>+<paramref name="numberOfOne"/>的二进制字符串,
/// 其中包含<paramref name="numberOfZero"/>个0和<paramref name="numberOfOne"/>个1
/// </summary>
public static IEnumerable<string> FixedLengthBinarySequence(int numberOfZero, int numberOfOne)
{if (numberOfZero < 1)throw new ArgumentOutOfRangeException("numberOfZero shouble be positive");if (numberOfOne < 1)throw new ArgumentOutOfRangeException("numberOfOne shouble be positive");var Length = numberOfZero + numberOfOne;var aux = new int[Length + 1];for (var i = 0; i < numberOfOne; ++i)aux[i] = 1;var index1 = numberOfOne - 1;var index2 = numberOfOne - 1;var result = new List<string>();while (true){var temp = aux.Take(Length).ToArray();result.Add(string.Join("", temp));aux[index1++] = 0;if (aux[index1] == 1){aux[index2++] = 1;continue;}if (index1 == Length) break;aux[index1] = 1;if (index2 > 0){aux[index2] = 1;aux[0] = 0;index1 = 1;index2 = 0;}}return result;
}

Fenichel(指定长度及最大和值的所有组合)

譬如sum = 2, len = 3返回

200,110,020,101,011,002,100,010,001,000

/// <summary>
/// 返回长度为<paramref name="length"/>的数字字符串,其所有数字字符的和不超过<paramref name="sum"/>
/// </summary>
public static IEnumerable<string> Fenichel(int sum, int length)
{if (sum < 1)throw new ArgumentOutOfRangeException("sum shouble be positive");if (length < 1)throw new ArgumentOutOfRangeException("length shouble be positive");var pos = new int[length + 1];pos[0] = sum;var index = 0;var result = new List<string>();while (true){var temp = pos.Take(length).ToArray();result.Add(string.Join("", temp));if (pos[0] == 0){if (index == length) break;pos[0] = pos[index] - 1;pos[index++] = 0;}else{--pos[0];index = 1;}++pos[index];}return result;
}

【笔记】TAOCP Vol4 - Combination相关推荐

  1. LeetCode笔记:39. Combination Sum

    题目描述 给定一个无重复的正整数数组 candidates 和一个正整数 target, 求所有和为 target 的 candidates 中数的组合中.其中相同数的不同顺序组合算做同一种组合,ca ...

  2. 出自上帝之手的精妙算法 - Algorithm from THE BOOK (1)

            <Proofs from THE BOOK>是一本非常出名的书籍, 收录了不少精妙的证明.         类似地, 在cstheory.stackexchange.com ...

  3. 敏感性分析算法 程序_计算机程序设计艺术(TAOCP)精读笔记1 - 算法分析真正应该有的样子 Part 1...

    系列文章的导航链接: 张浩驰:<趣味算法>专栏所有文章分类 - 导航​zhuanlan.zhihu.com 下篇文章Part 2导航: 张浩驰:计算机程序设计艺术(TAOCP)精读笔记1 ...

  4. 线性代数 --- 什么叫线性组合 Linear Combination(个人笔记扫描版)

     线性代数的核心是基于向量的两种基本操作 1,加法:把两个向量(v, w)加在一起. 2,常数乘法:常量(c)乘以向量(v, w). 把这两种操作放在一起,就叫线性组合(linear combinat ...

  5. 【论文笔记】知识图谱推理PRA——Relational retrieval using a combination of path-constrained random walks

    知识图谱的概念于2012年由谷歌提出,这篇文章虽然发表于2010年,但文章中的对于数据的使用已经接近知识图谱了.文章提出的PRA算法是知识图谱推理的早期探索,在RWR(重启随机游走算法)的基础上进行了 ...

  6. LSCP: Locally Selective Combination in Parallel Outlier Ensembles-学习笔记

    LSCP: Locally Selective Combination in Parallel Outlier Ensembles LSCP框架: 1.训练多个基础异常检测器(Base Detecto ...

  7. 万字长文!线性代数的本质课程笔记完整合集

    点击上方"Datawhale",选择"星标"公众号 第一时间获取价值内容 系列目录 1.向量究竟是什么 https://www.bilibili.com/vid ...

  8. 3Blue1Brown:“线性代数的本质”完整笔记

    我最早系统地学习线性代数是在大二时候,当时特意选修了学校物理系开设的4学分的线代,大概也就是比我们自己专业的线代多了一章向量空间的内容,其实最后上完发现,整个课程内容还是偏向于计算,对线性代数的几何直 ...

  9. Opencv-Python学习笔记五

    本篇笔记主要记录Opencv里的图像翻转,平移,旋转,仿射及透视功能,主要是下面几个API: cv2.flip() # 图像翻转 cv2.warpAffine() #图像仿射 cv2.getRotat ...

  10. 软件质量保证与测试笔记——江湖救急版

    软件质量保证与测试笔记--江湖救急版 Powered by DZY 以下部分图片来源于老师课件,仅供学习交流使用,侵权致删! Ch1 软件质量与测试概念 软件质量的定义 软件质量是"反映实体 ...

最新文章

  1. R语言dplyr包获取dataframe分组聚合汇总统计值实战(group_by() and summarize() ):均值、中位数、分位数、IQR、MAD、count、unique
  2. 数据库设计原则【转】
  3. 6、删除视图(DORP VIEW)
  4. 4由通道检测_大唐阜新煤制天然气「榜样力量」实训做实出实效——废水总酚检测时间由4小时缩短至10分钟...
  5. 研讨会 | 知识图谱前沿技术课程暨学术研讨会(武汉大学站)
  6. android 本地 播放器,Android 本地播放器
  7. MySQL主从同步延迟
  8. 云存储市场上演“新三国演义”
  9. 监听下拉框,当前选中值
  10. 2021财经直播系统 H5网页直播 大区直播间源码
  11. 火狐一键检测自己的邮箱是否被泄露信息 输入邮箱即可查看是否安全
  12. Tableau入门(一):条形图、堆积图、直方图绘制
  13. matlab什么样的数表示0,matlab里a(i)~=0什么意思
  14. 写SQL的21个好习惯
  15. excel 作图-- 主次纵坐标轴 横坐标名称太长
  16. 算法基础、算法比赛快速入门(java)
  17. 大数据营销更需要消费者洞察
  18. 重庆2018年度进出口总值时隔四年重返5000亿元规模
  19. 程序员的新年计划,你选择几个?
  20. 实体企业直播困局该如何打破

热门文章

  1. 甘特图控件VARCHART XGantt,分析拖动工具!
  2. 浅谈批处理for命令中的变量扩展
  3. 博弈论数据可用性声明_手机数据恢复,低调使用~
  4. visual studio 2010 破解版 破解方法
  5. 如何在Word中输入英语音标?非常简单好用
  6. 条码打印软件如何制作二维码
  7. 扫雷可以用计算机,windows扫雷
  8. 微商加人方法,感动你我的加人故事
  9. 常见图像格式清晰度对比
  10. Python实现高斯滤波