random.sample () возврат той же случайной последовательности каждый раз?

Я использую random.sample Python (население, k) функция для генерации ряда случайных значений из списка для создания новых перестановок того списка. Проблема - то, что каждый раз это пробегает цикл, это генерирует ту же самую случайную последовательность. Почему это? Я даже использовал random.seed (i) так, чтобы я переменная (изменяющий каждый раз через цикл) отобрал его различное значение каждый раз. Тем не менее та же последовательность. Что gives!@

Вот то, как я использую его:

def initialBuild(self):
    alphabet = self.alphabet
    for i in range (self.length):
        value = random.sample(alphabet, 1)
        alphabet.remove(value[0])
        self.finalWord.append(value[0])
    print "Final word = ", self.finalWord

который просто называют из init метода Отдельного класса. Как init метод называют так...

def buildPopulation(self, alphabet):
    #Initialize empty individuals
    for i in range(POPULATION_SIZE):
        self.population.append(Individual(alphabet))

и init метод похож на это...

def __init__(self, alphabet = []):
    self.length = len(alphabet)
    self.alphabet = alphabet
    self.initialBuild()

В конце я печатаю заключительное слово. Вот вывод выполнения этого метода дважды:

Заключительный Word = [[1150, 1160], [720, 635], [95, 260], [595, 360], [770, 610], [830, 610], [25, 185], [520, 585], [605, 625], [410, 250], [555, 815], [880, 660], [300, 465], [1220, 580], [1215, 245], [1250, 400], [565, 575], [1605, 620], [845, 680], [1170, 65], [795, 645], [525, 1000], [760, 650], [580, 1175], [420, 555], [25, 230], [345, 750], [700, 500], [725, 370], [1530, 5], [1740, 245], [875, 920], [415, 635], [1340, 725], [975, 580], [575, 665], [1465, 200], [830, 485], [660, 180], [475, 960], [685, 595], [145, 665], [510, 875], [845, 655], [650, 1130], [945, 685], [480, 415], [700, 580], [560, 365], [685, 610], [835, 625], [1320, 315]]

Заключительный Word = [[1150, 1160], [720, 635], [95, 260], [595, 360], [770, 610], [830, 610], [25, 185], [520, 585], [605, 625], [410, 250], [555, 815], [880, 660], [300, 465], [1220, 580], [1215, 245], [1250, 400], [565, 575], [1605, 620], [845, 680], [1170, 65], [795, 645], [525, 1000], [760, 650], [580, 1175], [420, 555], [25, 230], [345, 750], [700, 500], [725, 370], [1530, 5], [1740, 245], [875, 920], [415, 635], [1340, 725], [975, 580], [575, 665], [1465, 200], [830, 485], [660, 180], [475, 960], [685, 595], [145, 665], [510, 875], [845, 655], [650, 1130], [945, 685], [480, 415], [700, 580], [560, 365], [685, 610], [835, 625], [1320, 315]]

Заметьте, что эти два абсолютно идентичны..

Править: Так как мне нелегко выбирать код, что я думаю, будет полезно, все же достаточно короток для входа в это сообщение, я отправил набор его на pastebin. http://pastebin.com/f5f068391 Это - надо надеяться, лучшая альтернатива.. Еще раз спасибо

8
задан Chris 30 January 2010 в 17:28
поделиться

2 ответа

MPS - это не только DSL для Java. На самом деле это язык-ангост. Язык можно создать на любом другом языке, поддерживаемом MPS. Мы поддерживаем Java, XML и простой текст (в крайнем случае) вне рамки в MPS 1.1. Вероятно, в будущей версии мы предоставим другие языки, такие как javascript, css и т.д.

Одной из ключевых особенностей MPS, которая недоступна в других инструментах, является возможность составления языков. Можно создать несколько языковых расширений и составить их путь. Например, один поставщик может внедрить язык для своей базы данных, а другой - язык для финансовых расчетов. Они будут хорошо работать вместе, и у вас не будет никаких проблем, таких как неясности и т.д.

-121--3833094-

Вы можете попытаться вызвать setNeedsDisplay после преобразования, я не уверен, сработает это или нет, но это стоит выстрела.

-121--4998305-

Я не уверен, что вы имеете в виду, «генерируя точно такую же случайную последовательность». Поскольку вы даете нам только фрагмент, который нельзя запустить самостоятельно, вполне возможно, что в других частях вашего кода есть ошибки, которые вы решили не показывать нам - я попытался добавить абсолютно минимальное количество кода, необходимое для запуска вашего фрагмента, то есть:

import random

import string
def self(): pass
self.alphabet = list(string.lowercase)
self.finalWord = []
self.length = 4

for x in range(5):
  alphabet = self.alphabet
  for i in range (self.length):
      value = random.sample(alphabet, 1)
      alphabet.remove(value[0])
      self.finalWord.append(value[0])
  print "Final word = ", self.finalWord

и вот что я вижу, когда запускаю этот самодостаточный сценарий несколько раз:

$ python sa.py 
Final word =  ['y', 'm', 'u', 'z']
Final word =  ['y', 'm', 'u', 'z', 'h', 'b', 'c', 's']
Final word =  ['y', 'm', 'u', 'z', 'h', 'b', 'c', 's', 'x', 'l', 'r', 'n']
Final word =  ['y', 'm', 'u', 'z', 'h', 'b', 'c', 's', 'x', 'l', 'r', 'n', 'q', 'a', 'k', 'e']
Final word =  ['y', 'm', 'u', 'z', 'h', 'b', 'c', 's', 'x', 'l', 'r', 'n', 'q', 'a', 'k', 'e', 'p', 'd', 'j', 'w']
$ python sa.py 
Final word =  ['k', 'v', 'o', 'd']
Final word =  ['k', 'v', 'o', 'd', 'q', 'p', 'w', 'l']
Final word =  ['k', 'v', 'o', 'd', 'q', 'p', 'w', 'l', 'n', 'u', 'g', 't']
Final word =  ['k', 'v', 'o', 'd', 'q', 'p', 'w', 'l', 'n', 'u', 'g', 't', 'i', 'r', 'e', 'f']
Final word =  ['k', 'v', 'o', 'd', 'q', 'p', 'w', 'l', 'n', 'u', 'g', 't', 'i', 'r', 'e', 'f', 's', 'c', 'j', 'z']
$ python sa.py 
Final word =  ['o', 'a', 'g', 't']
Final word =  ['o', 'a', 'g', 't', 'k', 'j', 'y', 'w']
Final word =  ['o', 'a', 'g', 't', 'k', 'j', 'y', 'w', 'z', 'l', 'i', 's']
Final word =  ['o', 'a', 'g', 't', 'k', 'j', 'y', 'w', 'z', 'l', 'i', 's', 'u', 'p', 'f', 'm']
Final word =  ['o', 'a', 'g', 't', 'k', 'j', 'y', 'w', 'z', 'l', 'i', 's', 'u', 'p', 'f', 'm', 'h', 'e', 'q', 'v']

Как вы видите, это все, что угодно , но «точно такая же случайная последовательность» - она меняет каждый прогон, как и ожидалось.

Я думаю, что я неправильно прочитал ваш разум при попытке сделать ваш код исполняемым, и вы имеете в виду, что он будет использоваться совсем не так, как мой крошечный сценарий использует его - но затем чтение ума является ненадежным искусством (вот почему было бы намного лучше, если бы вы опубликовали автономный, бегущий пример, сделанный как можно крошечнее, пока еще воспроизводите вашу проблему, а не заставляя нас пытаться читать ваш ум! -).

Почему бы вам не изменить автономный сценарий, который я только что разместил на минимально необходимую сумму, чтобы приблизить его к предполагаемому использованию и воспроизвести проблему, которую вы наблюдаете? Тогда нам будет намного проще и продуктивнее обнаружить любую проблему, которую может иметь ваш код, и предложить лучший способ ее исправить!

Изменить : код ОП, вставленный в пастебин, имеет две ошибки, которые не имеют абсолютно никакого отношения к случайным и объединяются для создания наблюдаемого поведения ОП. Вот соответствующая часть кода, отредактированная:

class Phenotype:
   ...
   chromosome = []

   def __init__(self, alleles = []):
    self.length = len(alleles)
    self.alleles = alleles
    self.initialBuild()

   def initialBuild(self):
    alleleSet = self.alleles
    for i in range (self.length):
        value = random.sample(alleleSet, 1)
        alleleSet.remove(value[0])
        self.chromosome.append(value[0])

ОК, здесь есть еще одна ошибка (использование старых, устаревших классов в новом коде, вместо блестящих новых классов стиля, которые всегда должны использоваться), но это не то, что кусает ОП (еще), так что мы просто упомянем его вскользь; -).

Ошибка 1: поскольку ни __ init __ , ни любой другой метод никогда не выполняют присвоение self.chromosome =... , все упоминания self.chromosome в коде фактически относятся к одному и единственному списку Фенотип.хромосома , которую разделяют все экземпляры класса Phenotype . Так что неизбежно все такие экземпляры всегда будут иметь точно такую же, идентичную хромосому , несмотря ни на что. Исправьте: добавьте self.chromosome = [] в __ init __ (лучше также удалить переменные уровня класса, потому что они не приносят пользы и только путают проблему).

Ошибка 2: снова посмотрите на следующие строки кода, чтобы обнаружить его:

    self.alleles = alleles
       ...
    alleleSet = self.alleles
       ...
        alleleSet.remove(value[0])

Получил? self.alleles и локальное имя allele Set - это все ссылки на точно один и тот же набор alleles (или список, на самом деле), который передан - так что remove call i изменяет переданную коллекцию. Так что эта коллекция остается пустой после того, как был создан самый первый фенотип (вот почему, несмотря на Bug 1, хромосома не продолжает расти: потому что коллекция аллелей остается пустой forevermore).

Исправление: сделайте копию, например allele Set = list (self.alleles) , чтобы избежать повреждения оригинальной коллекции.

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

self.chromosome = list(self.alleles)
random.shuffle(self.chromosome)

, то есть просто получить случайную перестановку. Построение случайной перестановки, делающее N отдельных выборок и удаляющее каждую выборку из набора по мере ее генерации, - это действительно обходной, медленный и сложный способ атаки на чрезвычайно простую проблему! -)

16
ответ дан 5 December 2019 в 06:53
поделиться

Если вы хотите нарисовать фон холста, я бы рекомендовал использовать ImageBrush в качестве фона , 'потому что это просто, так как вам не нужно подкласс Canvas для переопределения Onender .

Но я дам вам демонстрационный исходный код для того, что вы просили:

Создайте класс (я назвал его ImageCanvas )

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;

    namespace WpfApplication1
    {
        public class ImageCanvas : Canvas
        {
            public ImageSource CanvasImageSource
            {
                get { return (ImageSource)GetValue(CanvasImageSourceProperty); }
                set { SetValue(CanvasImageSourceProperty, value); }
            }

            public static readonly DependencyProperty CanvasImageSourceProperty =
                DependencyProperty.Register("CanvasImageSource", typeof(ImageSource),
                typeof(ImageCanvas), new FrameworkPropertyMetadata(default(ImageSource)));

            protected override void OnRender(System.Windows.Media.DrawingContext dc)
            {
                dc.DrawImage(CanvasImageSource, new Rect(this.RenderSize));
                base.OnRender(dc);
            }
        }
    }

Теперь вы можете использовать его так:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1" Title="Window1" Height="300" Width="300">
    <Grid>
        <local:ImageCanvas CanvasImageSource="/Splash.png">
            <TextBlock Text="Hello From Mihir!" />
        </local:ImageCanvas>
    </Grid>
</Window>
-121--3242455-

Глядя на некоторые ответы, я думаю, что я могу объяснить это лучше, используя условия, которые

Закон ДеМоргана относится к тому факту, что существует два одинаковых способа написания любой комбинации двух условий - в частности, комбинация AND (оба условия должны быть истинными) и комбинация OR (одно из них может быть истинным). Примеры:

Часть 1 закона ДеМоргана

Утверждение: Алиса имеет родного брата.
Условия: У Алисы есть брат ИЛИ у Алисы есть сестра.
Напротив: Алиса является единственным ребёнком ( НЕ имеет родного брата).
Условия: У Алисы НЕТ брата, И у нее НЕТ сестры.

Другими словами: НЕ [A OR B] = [НЕ A] И [НЕ B]

Часть 2 закона ДеМоргана

Заявление: Боб является водителем автомобиля.
Условия: Боб имеет автомобиль И Боб имеет лицензию.
Напротив: Боб НЕ водитель автомобиля.
Условия: Боб НЕ имеет автомобиль, ИЛИ Боб НЕ имеет лицензию.

Другими словами: НЕ [А И В] = [НЕ А] ИЛИ [НЕ В] .

Я думаю, что это было бы немного менее запутанно для 12-летнего ребенка. Это, конечно, менее запутанно, чем вся эта ерунда о таблицах правды (даже я путаюсь, глядя на все это).

-121--2175552-

Не изменяйте начальное число для каждого образца. Это ломает генератор случайных чисел и абсолютно уверяет, что он не случайный.

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

Генератор случайных чисел запускается с известным постоянным начальным числом. Каждый раз, когда вы запускаете, вы должны получить одну и ту же последовательность. Установка «no seed» дает предсказуемую последовательность. Установка любого постоянного начального числа (как i в примере) дает предсказуемую последовательность.

Если вам нужна непредсказуемая последовательность, вам нужно непредсказуемое начальное число. Используйте время суток или некоторые байты, считанные из/dev/random, в качестве начальных значений. Один раз.

Рассмотрим это как упрощение.

word = random.sample( alphabet, length )

Мне кажется, что это производит разные последовательности.

>>> import string, random
>>> alphabet = string.ascii_lowercase
>>> random.sample( alphabet, 5 )
['x', 'p', 's', 'k', 'h']
>>> random.sample( alphabet, 5 )
['y', 'h', 'u', 'n', 'd']
6
ответ дан 5 December 2019 в 06:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: