gpt4 book ai didi

f# - F# 并行序列中的奇怪行为

转载 作者:行者123 更新时间:2023-12-04 06:12:26 26 4
gpt4 key购买 nike

我编写了以下代码来生成一些数字的所有可能组合:

let allCombinations (counts:int[]) = 
let currentPositions = Array.create (counts.Length) 0
let idx = ref (counts.Length-1)
seq{
while currentPositions.[0]<counts.[0] do
yield currentPositions
currentPositions.[!idx]<-currentPositions.[!idx]+1
while currentPositions.[!idx] >= counts.[!idx] && !idx>=1 do
currentPositions.[!idx]<-0
idx:=!idx-1
currentPositions.[!idx]<-currentPositions.[!idx]+1
idx:=counts.Length-1
}

我正在使用程序的其他部分中的序列,如下所示:
allCombinations counts |> Seq.map (fun idx -> buildGuess n digitsPerPos idx) ...

到现在为止还挺好。程序按预期运行并生成组合。对于输入 [|2;2;2|],它生成八个值:
 [|0; 0; 0|]
[|0; 0; 1|]
[|0; 1; 0|]
[|0; 1; 1|]
[|1; 0; 0|]
[|1; 0; 1|]
[|1; 1; 0|]
[|1; 1; 1|]

但是,当我使用 PSeq 并行化生成的序列时,所有要消耗的值都会更改为 [|2;0;0|],这是上面 while 循环中 currentPositions 数组的最后一个值。

如果我使用
yield (currentPositions|>Array.copy) 

代替
yield currentPositions

在顺序和并行版本中一切正常。

为什么会发生这种情况;有没有最有效的方法来产生结果;先感谢您;

最佳答案

问题是您正在创建一个在迭代之间发生变异的单个数组。

您可以通过构建一个结果列表而不是一个一个打印出来来消除等式中的并行性 - 如果您先构建列表然后将它们全部打印出来,您将看到相同的结果;该列表将包含 8 次相同的引用,始终指向同一个数组实例。

基本上为了避免副作用,您需要每个结果相互独立 - 因此您应该每次创建一个单独的数组。

关于f# - F# 并行序列中的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7626978/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com