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

  • DudeFromUkraine

    DudeFromUkra

    7 Ocak 2008
  • Rayone GB

    Rayone GB

    14 Temmuz 2007
  • TheOtherMau5

    TheOtherMau5

    6 Mart 2012