#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
деления в качестве индекса молекулы.