如何在出现函数最大值的列表中查找值 [英] How to find the value in a list at which a maximum value of a function occurs

查看:77
本文介绍了如何在出现函数最大值的列表中查找值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不仅要查找应用于列表的函数的最大值(我将仅使用List.maxBy),还要找到出现在列表中的值.感觉这是一个相当普通的操作,并且考虑到F#库的丰富程度,总的来说我发现它实际上已经可用并不会感到惊讶,但是如果有的话,我似乎找不到它!

I want to find not just the maximum value of a function applied to a list (for which I would just use List.maxBy) but also the value in the list this occurred at. This feels like a fairly common operation and given the richness of the F# libraries in general I wouldn't be at all surprised to discover it was actually already available but I cannot seem to find it if it is!

为了举例说明,我希望能够映射列表domain和函数f

To illustrate with an example, I want to be able to map a list domain and a function f

let domain = [0 .. 5]
let f x = -x * (x - 2)

(1, 1)(因为应用于列表其他元素的函数小于1).

to (1, 1) (since the function applied to an other element of the list is less than 1).

我首先尝试过:

let findMaximum domain f =
    let candidates = [ for x in domain do
                        yield x, f x ]
    let rec findMaximumHelper domain f currentMax =
        match domain with
        | [] -> currentMax
        | head::tail -> 
            let cand = f head
            match currentMax with
            | None ->
                let newMax = Some(head, cand)
                findMaximumHelper tail f newMax
            | Some(maxAt, possMax) ->
                let newMax =
                    if cand > possMax then Some(head, cand)
                    else Some(maxAt, possMax)
                findMaximumHelper tail f newMax
    findMaximumHelper domain f None

let answer = findMaximum domain f

这时我意识到这与 fold 操作非常接近,并将其放在一起

at which point I realised this is very close to a fold operation, and put together

let findMaximum2 domain f =
    let findMaximumHelper f acc x =
        let cand = f x
        match acc with
        | None -> Some(x, cand)
        | Some(maxAt, possMax) ->
            if cand > possMax then Some(x, cand)
            else Some(maxAt, possMax)
    List.fold (findMaximumHelper f) None domain

let answer2 = findMaximum2 domain f

相反.

我的问题是,这些惯用的F#方法是否可以解决此问题,或者确实有更好的方法来解决此问题?

My question is, are these idiomatic F# ways of solving this problem, or indeed, is there a better way of solving this?

推荐答案

实际上,F#库提供了所有必要的高阶函数来简洁地表达这一点:

Indeed, the F# library provides all the necessary higher order functions to express this succinctly:

domain
|> Seq.map (fun x -> x, f x)
|> Seq.maxBy snd

注意:已更新为使用Seq.mapSeq.maxBy而不是List.mapList.maxBy来解决@ildjarn关于创建不必要的中间列表的担忧.

Note: updated to use Seq.map and Seq.maxBy instead of List.map and List.maxBy to address @ildjarn's concern about creating an unnecessary intermediate list.

这篇关于如何在出现函数最大值的列表中查找值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆