我用F#编写了这段代码:
type NondeterministicFiniteAutomaton = {
initialState: string
finalStates: string List
transitions: Map<string * char, string List>
}
let private nextState (symbol:char) (state:string) (transitions:Map<string * char, string List>) =
transitions |> Map.tryFind (state, symbol)
let rec private haltState (input:string) (index:int) (state:string) (transitions:Map<string * char, string List>) =
match index with
| x when x = input.Length -> state
| _ ->
match nextState input.[index] state transitions with
| x when x.IsNone -> null
| x -> haltState input (index+1) x.Value transitions
在最后一行中,x.Value
将返回我的自动机可以输入的状态列表,例如["s1"; "s2"; "s3"]
。对于此列表中的每个状态,我想并行调用haltState
,从而并行计算每个可能的路径。
答案 0 :(得分:4)
我建议先写完整的顺序版。然后你可以看到添加并行性是否对你将要进行的计算有意义。
至于加入结果,即使在顺序版本中,您也需要这样做。您的haltState
函数返回单个字符串,但如果这是NFA,则它可能以多个不同的状态结束。所以你可以改变它以返回一系列可能的结果:
let rec private haltState (input:string) (index:int) (state:string) (transitions:Map<string * char, string List>) =
match index with
| x when x = input.Length -> Seq.singleton x
| _ ->
match nextState input.[index] state transitions with
| None -> Seq.empty
| Some states ->
states |> Seq.collect (fun state ->
haltState input (index+1) state transitions)
返回一个序列,它使用Seq.collect
连接为多个可能状态生成的序列。请注意,我还在选项值上使用了更多惯用模式匹配。
您可以使用Array.Parallel.map
对此进行并行化,但我怀疑这会使处理速度更快 - 开销可能会更大。
let rec private haltState (input:string) (index:int) (state:string) (transitions:Map<string * char, string List>) =
match index with
| x when x = input.Length -> [| state |]
| _ ->
match nextState input.[index] state transitions with
| None -> [| |]
| Some states ->
states
|> Array.ofSeq
|> Array.Parallel.collect (fun state -> haltState input (index+1) state transitions)