(这可能是一个经典的,但我不知道如何以最佳方式表达出来)创建路径的F#
列表我开始在左边,在某个日期。 对于一些资产,我可以计算从开始日期到某个未来日期的回报。 从未来的日子,我可以递归地进一步在时间上进一步。
我想生成尽可能正确的所有路径,但在某个目标日期之前停止。
这是我的代码。 'a是一项资产,并且(DateTime * DateTime)是我为此基础报价的两倍。
member this.getPaths dtstart dtend : Set<('a*(DateTime*DateTime)) list>=
let rec getPaths dtstart dtend (pastpath:List<'a*(DateTime*DateTime)>) : seq<('a*(DateTime*DateTime)) list>=
let udls = this.getUnderlyingsQuotingAt dtstart
let onestep = seq { for udl in udls do
let qt = this.QuoteNextAfterSrict udl dtstart
if qt.IsNone || (qt.Value |> fst > dtend) then
yield pastpath |> List.rev
else
let nextdate = qt.Value |> fst
yield! (getPaths nextdate dtend ((udl, (dtstart, nextdate))::pastpath)) }
onestep
getPaths dtstart dtend List.empty |> Set.ofSeq
由于我使用屈服!我会收集到底每次失败了一条新路。 所以,我最终必须去除我的序列。 我的问题是:有没有更好的方法来找到完整的路径,而没有重复删除?
我可以做第二遍或者添加一个List参数,但是有一些“纯”的方法可以一次完成这个吗?
更新
我想我得到了整个做法不妥许多无用的内部循环。 可能矢量化下一个可用的引号会很有用。我将在重构后更新代码。
更新2
第一重写是移动产生以下|> List.rev一个水平之上,从而允许切割不必要的探索。
member this.getPaths dtstart dtend : Set<('a*(DateTime*DateTime)) list>=
let count = ref 0
printfn "computing path from %A to %A " dtstart dtend
let rec getPaths dtstart dtend (pastpath:List<'a*(DateTime*DateTime)>) : seq<('a*(DateTime*DateTime)) list>=
let udls = this.getUnderlyingsQuotingAt dtstart
let udlquotes = udls |> Seq.map (fun udl -> (udl , this.QuoteNextAfterSrict udl dtstart))
|> Seq.filter (fun (_, q) -> q.IsSome)
|> Seq.map (fun (udl, q) -> (udl, q.Value))
|> Seq.filter (fun (_, q) -> fst q <= dtend )
let onestep = seq { if udlquotes.IsEmpty then
yield pastpath |> List.rev
else
for (udl, q) in udlquotes do
let nextdate = (fst q)
count := !count + 1
if !count%1000 = 0 then printfn "!count %A , path : %A " !count pastpath
yield! (getPaths nextdate dtend ((udl, (dtstart, nextdate))::pastpath) )
}
onestep
getPaths dtstart dtend List.empty |> Set.ofSeq
我意识到它没有回答你的问题,但你可能做的一件事是使用类型别名来使你的代码更容易阅读。至少在两个地方使用'a *(DateTime * DateTime)。这可能会更容易阅读__type datespan <'a> ='a *(DateTime * DateTime)__,然后在您的列表和您的列表中使用datespan。正如我所说,我意识到这不是回答你的问题,但它会让你的代码更容易阅读。 – 2012-03-21 16:47:57
你是完全正确的。感谢您的建议。我将添加一些关于代码的评论。 – nicolas 2012-03-21 18:49:21