在F#中生成两个不同的random

时间:2014-11-18 19:34:28

标签: random f#

我有一个F#列表,我正在列出该列表中的两个元素 如果列表中包含10个元素:

let rnd = new Random()
let elem1 = list.Item(rnd.Next(0,9))
let elem2 = list.Item(rnd.Next(0,9))

有机会elem1和elem2相等。
我已经检查了一些解决方法,其中大多数使用do while工作,但我不想实现可能永远不会以F#结尾的函数。
有没有办法在随机函数中创建限制?

First random  : 0 <= x <= 9 
Second random : 0 <= y <= 9  <> x

3 个答案:

答案 0 :(得分:3)

一个简单的解决方案:

let rnd = new Random()
let ndx1 = rnd.Next(9)
let ndx2 = 
    let x = rnd.Next(8)
    if x < ndx1 then x else x + 1
let elem1, elem2 = list.[ndx1], list.[ndx2]

另一种方法,使用数学并调用随机函数一次:

let r = Random().Next(9 * 8)
let x = 1 + r + r / 9 
let elem1, elem2 = list.[x / 9], list.[x % 9]

可以概括为:

let getTwoElements lst = 
    let c = List.length lst
    let x, y = Math.DivRem(Random().Next(c * (c-1)) * (c+1) / c + 1, c)
    lst.[x], lst.[y]

答案 1 :(得分:3)

更具声明性的方法,考虑到您对图像中的点的评论:

let rnd = System.Random()

/// this will build you a list of 10 pairs of indices where a <> b. 
let indices = 
    Seq.initInfinite (fun _ -> rnd.Next(0,10), rnd.Next(0,10))
    |> Seq.filter (fun (a,b) -> a <> b)
    |> Seq.take 10
    |> List.ofSeq

/// map indices into actual points.
let elems =
    let points = list |> Array.ofList
    List.map (fun (a, b) -> points.[a], points.[b]) indices

作为旁注,请勿在列表中使用随机访问。他们并没有为此做出,而且表现也很差。首先将它们转换为数组。

答案 2 :(得分:0)

有很多方法可以实现这一目标。一个简单的就是这样:

open System
open System.Linq
let rnd = new Random()
let elem1 = list.Item(rnd.Next(0,9))
let elem2 = list.Where(fun x->x <> elem1).ElementAt(rnd.Next(0,8))