0

したがって、sCount はソース配列内の要素の数であり、iCount は削除する要素の数です。

let indices = Array.init iCount (fun _ -> rng.Next sCount) |> Seq.distinct |> Seq.toArray |> Array.sort

上記の方法の問題は、具体的に iCount インデックスを削除する必要があることであり、これはそれを保証するものではありません。

私は次のようなものを試しました

while indices.Count < iCount do
    let x = rng.Next sCount
    if not (indices.Contains x) then
        indices <- indices.Add x

他にも似たようなものをいくつか...

私が試したすべての方法は非常に遅いですが、最大 2,000 万要素のサイズのソース配列を扱っています。

4

4 に答える 4

1

配列と比較してごくわずかなサイズのインデックスのセットが必要な場合、あなたがしていることはうまくいくはずです。それ以外の場合は、 Knuth-Fisher-Yates シャッフルのバリエーションを実行して、i1 .. n のランダム順列で最初の要素を取得することを検討してください。

let rndSubset i n =
    let arr = Array.zeroCreate i
    arr.[0] <- 0
    for j in 1 .. n-1 do
        let ind = rnd.Next(j+1)
        if j < i then arr.[j] <- arr.[ind]
        if ind < i then arr.[ind] <- j
    arr
于 2013-07-03T19:58:59.300 に答える
0

iCount は配列のサイズに近いですか、それとも 0 に近いですか? これにより、使用するアルゴリズムが変更されます。

0 に近い場合は、以前に生成された数値を追跡し、追加の数値が既に生成されているかどうかを確認します。

配列のサイズに近い場合は、@feralin で説明されている方法を使用します

于 2013-07-03T19:04:39.473 に答える
0
let getRandomNumbers =
  let rand = Random()
  fun max count -> 
    Seq.initInfinite (fun _ -> rand.Next(max))
    |> Seq.distinct
    |> Seq.take count

let indices = Array.init 100 id
let numToRemove = 10

let indicesToRemove = getRandomNumbers (indices.Length - 1) numToRemove |> Seq.toList
> val indicesToRemove : int list = [32; 38; 26; 51; 91; 43; 92; 94; 18; 35]
于 2013-07-03T19:34:17.947 に答える
0

このための F# コードは提供しませんが (私は F# を知らないため...)、使用すべきアプローチ/アルゴリズムについて説明します。

基本的に、やりたいことはn、指定されたリストのランダムな要素を選択することですlist。これは疑似コードで行うことができます:

chosen = []
n times:
    index = rng.upto(list.length)
    elem = list.at(index)
    list.remove-at(index)
    chosen.add(elem)

変数listには、ソース リスト内の可能なすべてのインデックスを入力する必要があります。次に、nそのインデックス リストからランダムな値を選択すると、値の出力、値の削除、ノックなど、任意の操作を実行できるランダムで個別のインデックスが作成されます。価値観などで自分を出し...

于 2013-07-03T18:56:27.943 に答える