2009-10-31 5 views
47

Это действительно странно, и я не понимаю, почему это происходит. В цикле foreach я повторяюсь через коллекцию класса A, и для каждого класса я вызываю метод Count(), гдеи r2 номера генерируются из диапазона [-1,1]. Проблема в том, что Random.Next возвращает одинаковые «случайные» номера для каждого экземпляра. Когда результаты для первого экземпляра равны 0 и -1, одни и те же будут возвращены из следующих экземпляров. Пожалуйста, не могли бы вы сказать мне, почему это происходит? Кроме того, я не могу получить разные результаты в каждом экземпляре класса А. Это код:Random.Next возвращает всегда одинаковые значения

class a 
{ 
Random rnd = new Random(); 
private void Count() 
{ 
    int r1 = rnd.Next(-1, 1); 
    int r2 = rnd.Next(-1, 1); 
} 
} 
class b 
{ 
List<a> listofA=new list<a>(); 
foreach (a ACLASS in listofA) 
{ 
    ACLASS.Count(); 
} 
} 

ответ

94

Проблема заключается в том, что вы создаете экземпляры класса Random слишком близко во времени.

Когда вы создаете объект Random, он засевается значением из системных часов. Если вы создадите экземпляры Random слишком близко по времени, все они будут засеяны одинаковой случайной последовательностью.

Создайте единый объект Random и передайте его ссылку на конструктор при создании экземпляров класса «a» вместо создания одного объектадля каждого экземпляра «a».

+1

я забыл, как хорошо, я использовал, чтобы иметь один и тот же вопрос еще в день принятия Бинго коробки для клуб, и тогда я использовал худший трюк, когда-либо известный человеку: приостановка потока для 2 г-н Неопытный и сумасшедший ... Сумасшедший достаточно, у меня есть класс, который создает случайные имена со статической случайной декларацией сверху из всего. –

5

Включает случайный экземпляр для каждого экземпляра A. Похоже, что все они получают одинаковое начальное значение по умолчанию. Вероятно, вы захотите сделать статический случайный случай для всех экземпляров A и использовать его повторно или альтернативно предоставить начальное значение экземпляру Random() в конструкторе A.

8

Вы создаете новый экземпляр Random очень близко друг к другу (ваша петля очень плотная), поэтому каждый экземпляр эффективно использует одно и то же начальное значение.

Лучшим подходом было бы создать один экземпляр и передать его вашему методу Count.

Вы знаете problably этот следующий бит, но я включу его здесь для полноты:

MSDN имеет подробности об этом, но в основном ваша проблема является Random.Next метод вы используете генерирует:

32-разрядное знаковое целое число, большее или равное minValue и меньшее, чем maxValue; то есть диапазон возвращаемых значений включает minValue, но не maxValue. Если minValue равно maxValue, возвращается minValue.

из-за этого ваши вызовы будут возвращать -1 или 0.

7

Используйте один статический генератор случайных чисел для всех экземпляров класса.

class a 
{ 
    private static Random rnd; 
    static a() { 
     rnd = new Random(); 
    } 
    private void Count() 
    { 
    int r1 = rnd.Next(-1, 2); 
    int r2 = rnd.Next(-1, 2); 
    } 
} 

Обратите внимание на изменения, чтобы дать вам номера в диапазоне от -1,1, а не -1,0

+0

Я думаю, что с этим диапазоном он также может вернуть 1, и они хотят только 0 и -1? – Lucas

+0

@Svante отредактировал вопрос, чтобы сделать интервал открытым, чтобы он соответствовал образцу кода.В исходном вопросе указан замкнутый интервал, хотя и не используется точный язык. Я думаю, что код был неправильным, и я собираюсь восстановить вопрос, чтобы указать закрытый интервал. – tvanfosson

+0

@tvanfosson Можете ли вы сказать мне, почему это работает? Я не понимаю, как эта статика дает вам случайность. Я знаю, что это работает, но не почему. Они все еще очень близки по времени. Благодарю. – johnny