2

我正在做一个项目,该项目需要我编写一个从集合中选择指定数量的随机元素的函数。然后将这些元素映射到一个变量以供以后比较。

所以在我的场景中,我必须选择任何给定集合的 5%。

let rec randomSet (a:Set<string>) =
let setLength = (a.Count / 100) * 5

let list = []
let rand = System.Random
if set.Length <> setLength then
    // some code will go here
    randomSet setLength eIDS
else
    set

^请批评我的代码,我只在 F# 中编写了一个星期。

我试过递归地做,但我觉得这是错误的方法。我尝试过其他方法,但它们使用 .take 函数,因此每次返回的集合都是相同的。

有任何想法吗?我不追求一组中的一个元素,我追求的是扔给它的任何一组的 5%。

这不是同一个问题:How can I select a random value from a list using F#

如果你认为是,请解释。

4

2 回答 2

5

有多种方法可以做到这一点。根据输入中的元素数量和您要选择的项目数量,不同的策略可能更有效。

可能最简单的方法是按随机数对输入进行排序,然后用于take获取所需数量的元素:

let data = [| 0 .. 1000 |]

let rnd = System.Random()

data 
|> Seq.sortBy (fun _ -> rnd.Next())
|> Seq.take 50

这将对序列进行随机排序(对于大序列可能会很慢),但是它会精确地获取您想要的元素数量(与 Mark 的解决方案不同,它将返回大约 5% 的项目)。

如果您想从大列表中选择小数字,最好随机生成索引(确保没有重复),然后根据索引进行直接查找。

于 2016-08-31T15:41:02.947 回答
3

由于Set<'a>implements Seq<'a>,这个问题实际上是如何使用 F# 从列表中选择一个随机值一套。

不过,只是为了好玩,这里有另一个解决方案。如果您需要选择 5%,则首先定义一个true仅返回 5% 的调用次数的谓词:

let r = System.Random ()
let fivePercent _ = r.NextDouble () < 0.05

您现在可以使用该谓词过滤您的集合:

let randomlySelectedSubset = stringSet |> Seq.filter fivePercent |> set
于 2016-08-31T15:41:10.527 回答