Python 数据结构与算法——从二分图到寻找最大排列(Maximum Permutation)
2016-03-21 16:43
190 查看
假设现在有 8 位有着特殊癖好的人去买票看电影,其中有一部分人得到了自己喜欢的座位,但大多数人并不满意。现在的问题是,如果这些人各自都有自己喜欢的座位(喜欢的座位有重叠,这是进行最大排列的前提,否则无法进行;座位有重叠,就必然存在一些无人愿去的座位,这恰是进行有效归纳的前提),那么我们希望给出某种交换座位的方式,以求让更多的人得到满意。
这其实是匹配问题的一种,我们其实可以将该问题(实例)模型化成某种图结构,如下图所示:
这其实是二分图(bipartite graph)的一个具体示例,这意味着在该图中,节点被分成了两个集合,而所有的边线都只存在于两个集合之间(边不存在于两个集合内部)。
问题分析归纳如下:
有没有座位是没有人想座的,也即上图中下排入度为 0 的点(b 和 g)?在一个有效的解决方案(一组排列)中,一个人(元素)最多只能被安排到一个既定座位上。也即不应该有空位,如果有空位的话,等于是让两个人做同一个座位。因此,移除空座位(包括对应的人)的做法不仅是对的,而且是必须的。对待上图,我们可以直接排除 b 和 g。问题得以归纳。
现在是时候将我们的归纳/递归算法转换为实际实现了。这种时候,往往要先解决实例中各对象如何表示(也即数据结构的选择)。就本例而言,我们可能会从图结构或能够反映图像之间映射关系的某个函数开始思考。本质上说,这里的映射关系只不过是各元素(0,…, n-1)与其位置(0,…,n-1)之间的关联性,我们使用 Python 中的列表(list)即可实现。例如,对于图,如果 a, b, c, d, e, f, g, h = range(8),我们就可做如下表示:
接下来我们即可将这个递归算法的思路实现出来,尽管其查找淘汰元素的方式有些粗暴,也必然不会多有效率,但有时效率低下的实现也是一个良好的开始。
这其实是匹配问题的一种,我们其实可以将该问题(实例)模型化成某种图结构,如下图所示:
这其实是二分图(bipartite graph)的一个具体示例,这意味着在该图中,节点被分成了两个集合,而所有的边线都只存在于两个集合之间(边不存在于两个集合内部)。
问题分析归纳如下:
有没有座位是没有人想座的,也即上图中下排入度为 0 的点(b 和 g)?在一个有效的解决方案(一组排列)中,一个人(元素)最多只能被安排到一个既定座位上。也即不应该有空位,如果有空位的话,等于是让两个人做同一个座位。因此,移除空座位(包括对应的人)的做法不仅是对的,而且是必须的。对待上图,我们可以直接排除 b 和 g。问题得以归纳。
现在是时候将我们的归纳/递归算法转换为实际实现了。这种时候,往往要先解决实例中各对象如何表示(也即数据结构的选择)。就本例而言,我们可能会从图结构或能够反映图像之间映射关系的某个函数开始思考。本质上说,这里的映射关系只不过是各元素(0,…, n-1)与其位置(0,…,n-1)之间的关联性,我们使用 Python 中的列表(list)即可实现。例如,对于图,如果 a, b, c, d, e, f, g, h = range(8),我们就可做如下表示:
>>> a, b, c, d, e, f, g, h = range(8) >>> M = [c, c, a, f, d, f, h, e] >>> M[c] 0 # M 本质上是 # [2, 2, 0, 5, 3, 5, 7, 4]
接下来我们即可将这个递归算法的思路实现出来,尽管其查找淘汰元素的方式有些粗暴,也必然不会多有效率,但有时效率低下的实现也是一个良好的开始。
def naive_max_perm(M, A=None): if A is None: A = set(range(len(M))) if len(A) == 1: return A B = set(M[i] for i in A) C = A - B if C: A.remove(C.pop()) return naive_max_perm(M, A) return A >>> naive_max_perm(M) {0, 2, 5} # a、c、f 保留在排列中 # 而其他人不得不留在自己不喜欢的位置上
相关文章推荐
- 数据结构学习笔记01链表
- 数据结构课设 打印选课学生名单 。。
- 数据结构课设 打印学生选课清单 (Hash)
- Python 数据结构与算法——选择排序(迭代版、递归版)
- 数据结构(java语言描述)链栈的使用——表达式求值
- 【小镇的技术天梯】从头写数据结构,C语言实现双向链表
- 数据结构6-树
- Python 数据结构与算法——插入排序(insertion sort)
- hdu 3874(树状数组+离线算法)
- A题常用数据结构
- 数据结构课设 任务调度的合理性 (拓扑排序)
- Operating Systems: Three Easy Pieces(操作系统:三个简单方面)4.5数据结构4.6总结
- 数据结构与算法笔记(一)单链表
- 数据结构5-队列
- 数据结构1 -- 链表的基本方法实现
- 数据结构4-堆栈
- linux2.6内核的DAC数据结构(传统9Bit模式、ACL模式)
- 数据结构与算法javascript描述之队列
- Python 数据结构与算法——从某个列表中找出两个彼此最接近但不相等的数
- javascript算法与数据结构之栈