python- construction of lattice which traps molecu

2019-02-28 04:21发布

问题:

I have this problem :

Create a program which constructs a lattice of one (1) dimension and 100000 sites. In this lattice put at random positions a number of trap molecules, which will have concentration c. Put 1 particle in a random position on the lattice and let it perform a random walk. In this walk you will not place a time restriction, namely you will not declare a specific number of steps. The walk will stop when the particle falls on a trap.............................. ...Beware of boundary conditions. When the particle reaches the borders of the lattice it shouldn’t be allowed to escape from it but to remain in the lattice, either by returning on it former position or by being placed in the opposite site of the lattice........

My approach is shown in the code i created (i have comments in it).

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

I have 3 problems :

1) The results i am taking for example for pos=10 are sth like:

[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...]

I would expect 10 numbers each for 1 run (variable pos).

2) I am not sure how to handle the boundary conditions. I am thinking something like:

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

But I can't test it. Also,i am not sure if this applies for both borders of the grid.

3) If i want the first step to begin from the middle of the grid, how can I do it?

If someone has a hint on that, I'll be grateful.

回答1:

On a smaller lattice, to see what is happening:

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

I would encourage you to thrown in print statements throughout to see what values each variable is holding. Trying it out on smaller lattices will help you understand how this works.

EDIT:

I'm going to let you figure out the specifics, but I would wrap this in a function like follows. It sets up the function, then prepares empty steps and histories lists to hold the results of each run. We run the function, then append the results to those lists.

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)


回答2:

The part where the grid is created is OK (although you used traps twice - I suppose you don't need the 1st line and the 4th line should be grid[traps]=0).

Then according to the problem you have to put a molecule and make it walk on the grid, and this part of your program is completely wrong. What you need to do is find a random starting point for the molecule (with sc.random.randint(pos) maybe), and then count the number of steps the molecule makes before falling in a trap. Steps in 1d random walk can be either to the left (starting_point - 1) or to the right (starting_point + 1). You have to choose randomly between [-1, +1], add the step to the index of the molecule on the grid and if the resultant index appears to be free on the grid then increment your free variable. If the resultant index hits the trap, then append the free variable to the steps_count list.

To answer your second question, periodic boundary conditions can be applied seamlessly to the grid if you take the remainder of index % pos division as the index of the molecule.