多序列的懒惰笛卡尔积(序列序列)

时间:2011-06-27 18:09:51

标签: f# sequences

你能建议更简单,更清晰的方式来编写这个函数吗?

let cartesian_product sequences = 
    let step acc sequence = seq { 
        for x in acc do 
        for y in sequence do 
        yield Seq.append x [y] }
    Seq.fold step (Seq.singleton Seq.empty) sequences 

2 个答案:

答案 0 :(得分:2)

我对朱丽叶链接到的函数进行了基准测试:

let items = List.init 6 (fun _ -> [0..9])
cart1 items |> Seq.length |> ignore
  

Real:00:00:03.324,CPU:00:00:03.322,GC gen0:80,gen1:0,gen2:0

并略微修改(以使其成为苹果对苹果的比较版)你的版本:

let cartesian items =
  items |> Seq.fold (fun acc s ->
    seq { for x in acc do for y in s do yield x @ [y] }) (Seq.singleton [])

cartesian items |> Seq.length |> ignore
  

Real:00:00:00.763,CPU:00:00:00.780,GC gen0:37,gen1:2,gen2:1

你的速度明显加快(并导致更少的GC)。在我看来,你所拥有的是好的。

答案 1 :(得分:2)

不太优雅,但(似乎是)更快的解决方案:

let cartesian_product2 sequences = 
    let step acc sequence = seq { 
        for x in acc do 
        for y in sequence do 
        yield seq { yield! x ; yield y } }
    Seq.fold step (Seq.singleton Seq.empty) sequences 

> cartesian items |> Seq.length;;
Real: 00:00:00.405, CPU: 00:00:00.405, GC gen0: 37, gen1: 1, gen2: 0
val it : int = 1000000
> cartesian_product2 items |> Seq.length;;
Real: 00:00:00.228, CPU: 00:00:00.234, GC gen0: 18, gen1: 0, gen2: 0
val it : int = 1000000