您的位置:首页 > 其它

P27 (**) Group the elements of a set into disjoint subsets.

2016-01-31 19:03 477 查看

问题描述

a) In how many ways can a group of 9 people work in 3 disjoint subgroups of 2, 3 and 4 persons? Write a function that generates all the possibilities and returns them in a list.

sash> (group3 '(aldo beat carla david evi flip gary hugo ida))
-> (((aldo beat) (carla david evi) (flip gary hugo ida)) ... )


b) Generalize the above predicate in a way that we can specify a list of group sizes and the predicate will return a list of groups.

sash> (subsets '(aldo beat carla david evi flip gary hugo ida) '(2 2 5))
-> (((aldo beat) (carla david) (evi flip gary hugo ida)) ... )


Note that we do not want permutations of the group members; i.e. ((aldo beat) …) is the same solution as ((beat aldo) …). However, we make a difference between ((aldo beat) (carla david) …) and ((carla david) (aldo beat) …).

You may find more about this combinatorial problem in a good book on discrete mathematics under the term “multinomial coefficients”.

解法

该题目涉及到多项式系数,有关内容可参考这里。链接给出了多项式系数的公式,可以用来检验自己的答案是不是正确。

(define subsets
(lambda (set groups)
(cond
[(null? groups) '(())]
[else
(let f ([s (combination (car groups) set)])
(if (null? s)
'()
(let ([comb (car s)])
(append (map (lambda (group)
(cons comb group))
(subsets (difference set comb) (cdr groups)))
(f (cdr s))))))])))

(define difference
(lambda (set1 set2)
(cond
[(null? set1) '()]
[(member (car set1) set2)
(difference (cdr set1) set2)]
[else (cons (car set1)
(difference (cdr set1) set2))])))


set
是一个集合,不允许元素重复;
groups
包含分为多少个组,以及每个组包含元素个数的信息,如
'(2 3 4)
表示包含3个组,每组的大小分别为2、3、4。

这里使用了前一问题定义的
combination
函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  scheme lisp