作为礼物,我感到困惑。它由4个并排排列的立方体组成。每个立方体的面是四种颜色之一。

为了解决这个难题,必须对多维数据集进行定向,以使所有四个多维数据集的顶部都不同,它们的正面都不同,背面都不同,底部都不同。左右两侧无所谓。

我的伪代码解决方案是:


创建每个的表示
立方体。
获取所有可能的方向
每个立方体(每个有24个)。
获取以下所有可能的组合
每个立方体的方向。
查找方向的组合
满足解决方案。


我使用F#中的伪代码实现解决了这个难题,但是我对步骤3的方式不满意:

let problemSpace =
    seq { for c1 in cube1Orientations do
              for c2 in cube2Orientations do
                  for c3 in cube3Orientations do
                      for c4 in cube4Orientations do
                          yield [c1; c2; c3; c4] }


上面的代码非常具体,只能计算出四个方向序列的笛卡尔积。我开始考虑为n个方向序列编写它的方法。

我想出了(从现在开始,所有代码都应在F#交互中很好地执行):

// Used to just print the contents of a list.
let print =
    Seq.fold (fun s i -> s + i.ToString()) "" >> printfn "%s"

// Computes the product of two sequences - kind of; the 2nd argument is weird.
let product (seq1:'a seq) (seq2:'a seq seq) =
    seq { for item1 in seq1 do
              for item2 in seq2 do
                  yield item1 |> Seq.singleton |> Seq.append item2 }


产品功能可以像这样使用...

seq { yield Seq.empty }
|> product [ 'a'; 'b'; 'c' ]
|> product [ 'd'; 'e'; 'f' ]
|> product [ 'h'; 'i'; 'j' ]
|> Seq.iter print


...导致...

let productn (s:seq<#seq<'a>>) =
    s |> Seq.fold (fun r s -> r |> product s) (seq { yield Seq.empty })

[ [ 'a'; 'b'; 'c' ]
  [ 'd'; 'e'; 'f' ]
  [ 'h'; 'i'; 'j' ] ]
|> productn
|> Seq.iter print


这正是我想要的用法。 productn完全具有我想要的签名并且可以工作。

但是,使用product涉及到讨厌的行seq {yield Seq.empty},这很不直观:


一系列值(seq )
一系列值序列(seq )


第二个参数似乎不正确。

这个奇怪的界面被productn很好地隐藏了,但是无论如何仍然困扰着我。

是否有更好,更直观的方法来一般性地计算n个序列的笛卡尔积?是否有任何内置函数(或它们的组合)可以做到这一点?

最佳答案

使用递归:n个列表{L1..LN}的笛卡尔乘积是将L1中的每个元素添加到列表{L2..LN}的笛卡尔积的每个子列表时得到的列表的集合。

let rec cart1 LL =
    match LL with
    | [] -> Seq.singleton []
    | L::Ls -> seq {for x in L do for xs in cart1 Ls -> x::xs}


例:

> cart1 [[1;2];[3;4;5];[6;7]] |> Seq.toList;;
val it : int list list =
  [[1; 3; 6]; [1; 3; 7]; [1; 4; 6]; [1; 4; 7]; [1; 5; 6]; [1; 5; 7]; [2; 3; 6];
   [2; 3; 7]; [2; 4; 6]; [2; 4; 7]; [2; 5; 6]; [2; 5; 7]]


[1; 2] [3; 4; 5]和[6; 7]的笛卡尔积是{1的并集,附加到购物车[[3; 4; 5]; [6; 7]]中的每个列表和{2附加到购物车[[3; 4; 5]; [6; 7]]}中的每个列表中。这是match语句中的第二个子句。

关于f# - 如何计算F#中n个序列的笛卡尔积?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3334429/

10-12 03:55