【问题标题】:Generate a list of possible subset from a set in ocaml从 ocaml 中的集合生成可能子集的列表
【发布时间】:2017-12-31 10:18:19
【问题描述】:

我正在计算在扑克(德州扑克)游戏中获胜的概率。为此,我必须创建一个函数,从手中的两张牌和桌上的 3 或 4 或 5 张牌中返回 5 张牌的所有可能组合。 我想对桌上的牌数做个比对。因此,如果我有 3 张,那么唯一的五张牌就是手上的两张 + 桌上的 3,但是一旦我的桌子上有 4 或 5 张牌,我将有 6 到 21 种可能的组合,所以我开始了这个方式

let compute_comb (d:donne) (t:table) =
  let l = listTable t in
  let l_size = List.length l in
  match l_size with
  |3 -> listCartes d t
  |4 -> 

注意 donne 是这样定义的类型 type donne = card*card 和表是这样定义的type table = card*card*card*card*card

【问题讨论】:

  • 那么问题是什么?
  • 4、5情况下如何完成功能

标签: ocaml poker probability-theory


【解决方案1】:

在我看来,这是一个典型的问题示例,考虑更一般的情况会使问题变得更容易。考虑在l 牌中找出所有n 牌组合的问题。


为了简单起见,我认为cards 只是通用的'a。另外,我不会在牌桌和牌桌之间做任何区分,我只是将两者视为一个列表。将两者分开可能会带来更好的解决方案,但会使其不那么容易理解:-)


因此,您将拥有一个函数comb n l,它返回列表ln 元素的所有组合的列表(因此comb 返回'a list list)。让我们递归地做:

首先,如果n大于l的长度,就放弃吧:

exception NotEnoughElement of int*int
let rec comb n l = 
let length_l = List.length l in
if n > length_l
  raise (NotEnoughElement (n, length_l))
else

现在我们确定n是合适的,根据n有3种情况需要考虑:如果n = 0,则返回一个空列表

match n with
| 0 -> []

如果n 是列表的大小,则别无选择:唯一合适的子列表是...列表本身(当您在桌子上有cards 时,这与您的情况类似)。请注意,我们返回一个包含 l 的列表以履行我们的约定,即 comb 返回一个包含所有子列表的列表。

| _ when n == length_l -> [l]

最后,如果n 小于l 的长度,我们可以选择:要么取l 的头部,要么不取。

| _ -> 

如果我们取l 的头部,那么我们必须在l 的尾部搜索n-1 元素的组合,并将l 的头部附加到所有这些子组合中。要进行附加,请使用此功能

  let app_head sublist = (List.hd l) :: sublist in

如何在l 的尾部取n-1 元素的组合?好吧,我们有约定说comb n l返回l中所有大小n组合的列表,所以我们可以使用这个“契约”:

  let sublists = comb (n-1) (List.tl l) in

现在,让我们进行追加,List 模块提供了一个 map 函数,它将函数应用于列表的所有元素,我们可以使用我们的 app_head 函数:

  let combination_head_taken = List.map app_head sublists in

现在,如果我们不取头部,那么我们仍然需要在l 的尾部搜索n 元素。再次,我们在comb 上使用我们的聚合:

  let combination_head_not_taken = comb (n-1) (List.tl l) in

然后,只需连接在两个子案例中生成的组合:

  combination_head_taken @ combination_head_not_taken

然后你可以玩utop(假设你在comb.ml中写了这个函数):

$ utop
# #use "comb.ml";;
# let hand = [1;2;3;4;5];;
# comb 3 hand;;
- : int list list = [[2; 3; 4; 5]; [1; 3; 4; 5]; [1; 2; 4; 5]; [1; 2; 3; 5]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-02
    • 2013-08-11
    • 1970-01-01
    • 2015-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多