SORU
7 Kasım 2008, Cuma


Liste<T> C * rastgele#

C genel bir listenin sıralamasını rastgele için en iyi yolu nedir#? Piyango türü bir uygulama için onları çekmek amacıyla rastgele bir sipariş atamak istiyorum bir listesi 75 sayıların sonlu bir kümesi var.

CEVAP
11 AĞUSTOS 2009, Salı


Uzantısı yöntemi Fisher-Yates shuffle dayalı (I)List Shuffle:

private static Random rng = new Random();  

public static void Shuffle<T>(this IList<T> list)  
{  
    int n = list.Count;  
    while (n > 1) {  
        n--;  
        int k = rng.Next(n   1);  
        T value = list[k];  
        list[k] = list[n];  
        list[n] = value;  
    }  
}

Kullanımı:

List<Product> products = GetProducts();
products.Shuffle();

Yukarıdaki kod çok eleştirilen Sistemi kullanır.Rastgele yöntem takas adayları seçmek için. Hızlı ama olması gerektiği kadar rastgele değil. Eğer ihtiyacınız varsa karıştırır içinde rastgelelik daha iyi bir kalite Sistemi içinde rasgele sayı üreteci kullanır.Güvenlik.Kriptografi gibi

using System.Security.Cryptography;
...
public static void Shuffle<T>(this IList<T> list)
{
    RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
    int n = list.Count;
    while (n > 1)
    {
        byte[] box = new byte[1];
        do provider.GetBytes(box);
        while (!(box[0] < n * (Byte.MaxValue / n)));
        int k = (box[0] % n);
        n--;
        T value = list[k];
        list[k] = list[n];
        list[n] = value;
    }
}

Basit bir karşılaştırma mevcuttur: http://thegrenade.blogspot.com/2010/02/when-random-is-too-consistent.html

Edit: birkaç yıl önce bu cevap yazma Beri, birçok insan, ya da benim için yazılmış, benim oranla büyük aptal kusur işaret için yorumladı. Tabii ki haklılar. Hiçbir şey Sistem ile yanlış bir şey yok.Eğer bu şekilde kullanılırsa rastgele düşünülmüştü. Yukarıdaki ilk örnekte, eğer bu yöntem defalarca aradı olacaksa bela olan Shuffle yöntemi, içinde rng değişkeni İ başlatılamadı. Aşağıda sabit, tam bir örnek gerçekten faydalı bir yorum @weston üzerinde bu YÜZDEN bugün alınan göre.

Program.cs:

using System;
using System.Collections.Generic;
using System.Threading;

namespace SimpleLottery
{
  class Program
  {
    private static void Main(string[] args)
    {
      var numbers = new List<int>(Enumerable.Range(1, 75));
      numbers.Shuffle();
      Console.WriteLine("The winning numbers are: {0}", string.Join(",  ", numbers.GetRange(0, 5)));
    }
  }

  public static class ThreadSafeRandom
  {
      [ThreadStatic] private static Random Local;

      public static Random ThisThreadsRandom
      {
          get { return Local ?? (Local = new Random(unchecked(Environment.TickCount * 31   Thread.CurrentThread.ManagedThreadId))); }
      }
  }

  static class MyExtensions
  {
    public static void Shuffle<T>(this IList<T> list)
    {
      int n = list.Count;
      while (n > 1)
      {
        n--;
        int k = ThreadSafeRandom.ThisThreadsRandom.Next(n   1);
        T value = list[k];
        list[k] = list[n];
        list[n] = value;
      }
    }
  }
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Official Android Tips

    Official And

    23 EYLÜL 2009
  • LaKe Lightroom Tutorials

    LaKe Lightro

    22 Temmuz 2014
  • Samantha Crain

    Samantha Cra

    30 EKİM 2008