python- построение решетки, которая захватывает молекулы — работает неправильно

#python #scipy #random-walk

#python #scipy #случайное блуждание

Вопрос:

У меня такая проблема :

Создайте программу, которая строит решетку одного (1) измерения и 100000 узлов. В этой решетке поместите в случайные позиции ряд молекул-ловушек, которые будут иметь концентрацию c . Поместите 1 частицу в случайном положении на решетке и позвольте ей выполнять случайное блуждание. В этом обходе вы не будете устанавливать ограничение по времени, а именно вы не будете объявлять определенное количество шагов. Прогулка остановится, когда частица попадет в ловушку………………………… …Остерегайтесь граничных условий. Когда частица достигает границ решетки, ей не следует позволять покидать ее, но оставаться в решетке, либо возвращая на нее прежнее положение, либо помещая в противоположный участок решетки……..

Мой подход показан в коде, который я создал (у меня есть комментарии к нему).

 def steps1d(self,pos,c):
    #pos: number of positions
    #c:   concentration of trap-particles

    # array full of traps (zeros)
    myzeros = sc.zeros(self.c*self.pos)

    # grid full of available positions(ones)
    grid = sc.ones(self.pos)

    # distribute c*pos zeros(traps) in random positions (number of positions is pos)
    traps = sc.random.permutation(pos)[:c*pos]

    # the grid in which the particle is moving which has traps inside it 
    grid[traps] = myzeros
    steps_count = []    # list which holds the number of steps
    free = 0
    for i in range(pos):
        # the step of the particle can be 0 or 1
        step=sc.random.random_integers(0,1)
        for step in grid[:]:
            if step == 1:
                free  = 1
                steps_count.append(free)
            else:
                break
    return steps_count
  

У меня 3 проблемы :

1) Результаты, которые я беру, например, для pos = 10, выглядят примерно так:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35…]

Я бы ожидал 10 чисел для каждого за 1 запуск (переменный pos).

2) Я не уверен, как обрабатывать граничные условия. Я думаю что-то вроде:

 if free > grid.size:
    free = free - 1
  

Но я не могу это проверить. Кроме того, я не уверен, применимо ли это к обеим границам сетки.

3) Если я хочу, чтобы первый шаг начинался с середины сетки, как я могу это сделать?

Если у кого-то есть намек на это, я буду благодарен.

Ответ №1:

На решетке меньшего размера, чтобы увидеть, что происходит:

 import numpy

# Populate the lattice
lattice = numpy.concatenate([numpy.ones(90), numpy.zeros(10)])
numpy.random.shuffle(lattice)

# Intialize problem
in_trap = False
steps = 0
pos = int(numpy.random.randint(0,len(lattice),1))
history = []

while in_trap == False:
    # Step of -1 is backward, 1 is forward
    step = numpy.random.permutation([-1,1])[0]

    # Check position for edges and fix if required
    if pos   step > len(lattice) - 1:
        pos = 0
    elif pos   step < 0:
        pos = len(lattice) - 1
    else:
        pos  = step

    # Keep track of random walk
    history.append(pos)

    # Check if it's a trap
    if lattice[pos] == 0:
        in_trap = True

    # If not, continue
    steps  = 1


print steps
print history
print lattice
  

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

Редактировать:

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

 def lattice():
    code
    return steps, history

steps = []
histories = []
for i in range(0,10):
    num_steps, history = lattice()
    steps.append(num_steps)
    histories.append(history)
  

Комментарии:

1. Прежде всего, большое спасибо за помощь! Однако у меня есть несколько вопросов. 1) Вы добавляете позицию (pos) к истории, которая просто содержит разные позиции, в которые попадает частица. Но мне нужно количество шагов, которые делает частица, пока не найдет ловушку. Я хочу, чтобы шаги были добавлены, верно? Кроме того, я не понял инструкцию «elif pos step<0».

2. ХОРОШО, хорошо,хорошо! Я понял! Ладно, для меня это было немного сложно, но теперь я понял! Спасибо!

3. : Здравствуйте, у меня возникли трудности в части, которая выполняет запуск. Например, я должен выполнить вышеуказанное 10 раз. Итак, я помещаю оператор while в цикл for. для i в диапазоне(10). И я ожидаю предпринять 10 разных шагов. Но я делаю только один шаг! Я пробую это со вчерашнего дня, но я не могу заставить это работать!!

4. : Кроме того, я думаю, что в инструкции elif это должно быть: pos= len (решетка)-1, а не len (решетка-1) , верно?

5. Спасибо, исправлена ошибка. Если вы помещаете цикл while только в цикл for, вы не устраняете проблему. Вам нужно также поместить строки в раздел «Инициализация проблемы».

Ответ №2:

Часть, в которой создается сетка, в порядке (хотя вы использовали traps дважды — я полагаю, вам не нужна 1-я строка, а должна быть 4-я строка grid[traps]=0 ).

Тогда, согласно задаче, вы должны поместить молекулу и заставить ее перемещаться по сетке, и эта часть вашей программы совершенно неверна. Что вам нужно сделать, это найти случайную отправную точку для молекулы (с sc.random.randint(pos) возможно), а затем подсчитать количество шагов, которые молекула делает, прежде чем попасть в ловушку. Шаги в одномерном случайном блуждании могут быть либо слева ( starting_point - 1 ), либо справа ( starting_point 1 ). Вы должны случайным образом выбирать между [-1, 1] , добавлять шаг к индексу молекулы в сетке, и если результирующий индекс в сетке оказывается свободным, тогда увеличьте свою free переменную. Если результирующий индекс попадает в ловушку, добавьте free переменную в steps_count список.

Чтобы ответить на ваш второй вопрос, периодические граничные условия могут быть легко применены к сетке, если вы возьмете остаток от index % pos деления в качестве индекса молекулы.