分治算法求螺丝螺母匹配问题
一、问题描述:
有个大小不同的螺丝和与之匹配的n个螺母, 你可以尝试一个螺丝和一个螺母是否匹配, 尝试结果有三种:(1)螺丝太大;(2)匹配成功;(3)螺母太大. 请设计一个分治算法完成所有螺丝和螺母的匹配
二、算法求解:
1、算法思路:
边界条件:当只有一个螺丝和一个螺母时,匹配螺丝和螺母。
Divide:在杯子集合中随机选择一个螺丝x, 将x与所有螺母进行匹配,把结果为螺丝太大的螺母放入G1, 把结果为螺母太大的螺母放入G2, 找到和x匹配成功的螺母记为y。将y与x以外所有杯子进行匹配,把结果为螺母太大的螺丝放入B1, 把匹配结果为螺丝太大的螺丝放入B2。
Conquer:递归地对B1和G1、B2和G2进行匹配。
Merge:返回B1和G1、B2和G2的匹配结果以及(x, y)。
2、算法伪代码:
Match(B, G)
Input: 螺丝集合B, 螺母集合G, |B|=|G|=n, B中每个螺丝都只和G中一个螺母匹配成功
Output: {(x, y)| x∈B, y∈G, x与y匹配成功}
- if |B|=1
- return BG;
- 初始化B1, B2, G1, G2, M=; y=NIL;
- 随机选择螺丝集合B中的一个元素x;
- for G
- if g和x的匹配结果为“螺丝太大”
- 令G1=G1{g};
- else if g和x的匹配结果为“螺母太大”
- G2=G2{g};
- else {
- y=g;
- M=M{(x, y)};
- }
- for B/{x}
- if y和b的匹配结果为“螺母太大”
- B1=B1{b};
- else if g和x的匹配结果为“螺丝太大”
- B2=B2{b};
- if B1
- M=MMatch(B1, G1);
- if B2
- M=MMatch(B2, G2);
- return M;
3、算法时间复杂度分析:
记算法时间复杂性T(n)。 将x与所有螺母匹配代价为O(n); 将y与x以外所有螺母匹配的代价为O(n); 综上, 划分代价为O(n)。Conquer 代价为T(|B1|)+T(n-1-|B1|), 其中|B1|为0、1、…、n-1的概率都是1/n。Combine(Merge)代价不计(算法的时间复杂性用匹配尝试的次数来衡量)。 总体代价与快速排序相同, 最坏情况为O(n2); 期望为O(nlogn)。