2012-02-23 16 views
6

Próbuję rozwiązać problem dwuwymiarowego losowego spaceru z książki, eksplorując pythona. Ale nie mogłem wymyślić, jak mogę rozwiązać ten problem. Zrobiłem kilka badań, ale te były zbyt skomplikowane, aby zrozumieć, o co chodzi. Jestem początkującym uczniem. Więc nie mogę zrozumieć kodu, szukając go. Proszę wyjaśnij mi ten problem w szczegółach.Kolejna prosta symulacja losowego spaceru przy użyciu Pythona (dwuwymiarowa)

W każdym razie, pytanie brzmi:

dwuwymiarowego wariacja na losowej spacer rozpoczyna się w środkowej siatki, takie jak 11 przez 11 tablicy. Na każdym kroku pijak ma cztery wybory : w górę, w dół, w lewo lub w prawo. Wcześniej w rozdziale opisaliśmy jak stworzyć dwuwymiarową tablicę liczb. Używając tego typu danych, napisz symulację dwuwymiarowego losowego spaceru.

Ok, Co wiem; wiem jak utworzyć dwuwymiarową tablicę w Pythonie:

times = [0] * 11 
for i in range(0,11): 
    times[i] = [0] * 11 

I mam pomysł funkcji „randint”:

A także Pisałem jednowymiarowym odmianę tego problemu w ostatnim czasie. Ale jest to kod spaghetti i jest bardzo brudny, a także nie jestem pewien, czy to prawda.

Mój kod jest tutaj:

''' 
Created on Feb 11, 2012 

@author: msarialp 
''' 
from random import randint 

def drunken_man(): 
    steps = 0 
    times = [0] * 11 
    left_move = 0 
    right_move = 0 
    i = 0 
    while left_move < 5 or right_move < 5: 
     value = randint(0,1) 
     times[5] = 1 
     if value == 1: 
      steps += 1 
      print("He moved left") 
      left_move += 1 
      if right_move > 0: 
       right_move -= 1 
      if left_move == 1: 
       times[4] += 1 
      elif left_move == 2: 
       times[3] += 1 
      elif left_move == 3: 
       times[2] += 1 
      elif left_move == 4: 
       times[1] += 1 
      #elif left_move == 5: 
       #times[0] += 1 
     elif value == 0: 
      steps += 1 
      print("He moved right") 
      right_move += 1 
      if left_move > 0: 
       left_move -= 1 
      if right_move == 1: 
       times[6] += 1 
      elif right_move == 2: 
       times[7] += 1 
      elif right_move == 3: 
       times[8] += 1 
      elif right_move == 4: 
       times[9] += 1 
      #elif right_move == 5: 
       #times[10] += 1 
     times[i] += 1     
    for i in range(1,10): 
     print("He took {steps} steps until he reaches end of the sidewalk.".format(steps = steps), "He stood on {1} square at {0} times".format(times[i], i)) 

def main(): 
    drunken_man() 

    return 0 
if __name__ == '__main__': 
    main() 

EDIT Jeden

Po zrobieniu kilku dobrych rad od Dan Gerhardsson. Postanowiłem edytować moje pytanie. Więc gdzie jestem na to pytanie: Rozumiem, w jaki sposób mogę śledzić etapy mojego pijanego mężczyzny w dwóch wymiarach.

Używanie krotki do rozwiązania tego ćwiczenia było bardzo zrozumiałe i jasne.

Tak więc, po tym, jak cały mój segment kodu jest tutaj, proszę sprawdzić i dać mi informacje zwrotne.

def two_dimensional_random_walk(): 
    steps = 0 
    times = [0] * 11 
    for i in range(0,11): 
     times[i] = [0] * 11 
    x = 5 
    y = 5 
    moves = [(1,0), (0,1), (-1,0), (0,-1)] 
    while x<11 and x >= 0 or y < 11 and y >= 0: 
     dx, dy = moves[randint(0,3)] 
     x += dx 
     y += dy 
     if dx == 1 and dy == 0: 
      print("He moved right") 
     elif dx == 0 and dy == 1: 
      print("He moved up") 
     elif dx == -1 and dy == 0: 
      print("He moved left") 
     elif dx == 0 and dy == -1: 
      print("He moved down") 
     try: 
      times[x][y] += 1 
      steps += 1 
     except IndexError: 
      break 

I moja funkcja druku:

for i in range(0,11): 
    for j in range(0,11): 
     print("He took {steps} steps until he reaches end of the sidewalk.".format(steps = steps), "He stood on {1}x{2} square at {0} times".format(times[i][j], i+1,j+1)) 

Więc w sumie myślę, ze pomaga Dan Gerhardsson, I rozwiązać ćwiczenia.

Ale, dlaczego nie zmienię mojego rozwiązania jednowymiarowego z tymi podpowiedziami.

def drunken_man(): 
steps = 0 
x = 6 
times = [0] * 11 
moves = [(1), (-1)] 

while x < 11 and x >= 0: 
    dx = moves[randint(0,1)] 
    print(dx, x) 
    x += dx 
    try: 
     times[x] += 1 
     steps += 1 
    except IndexError: 
     break   
for i in range(1,11): 
    print("He took {0} steps until he reaches end of the sidewalk.".format(steps), "He stood on {1} square at {0} times".format(times[i], i)) 

EDIT Dwa końcowe (dotyka)

Nie jestem pewien, czy jest to konieczne, aby edytować mój post na stosowanie podpowiedzi Dan Gerhardsson. Aby pomóc komuś, kto tęskni za punktami takimi jak ja, postanowiłem połączyć wszystko razem.

Więc tutaj jest moja funkcja, która jest połączona z nutą Dan Gerhardsson:

def two_dimensional_random_walk(): 
steps = 0 # Steps counter for understand how many steps that our drunken man take 
grid_size = 11 # Grid size variable, 
# Creating Two dimensional array by using lists 
times = [0] * grid_size 
for i in range(0,grid_size): 
    times[i] = [0] * grid_size 
# Initial variables to start in the middle of grid 
x = 5 
y = 5 
# Tuples to get directions and decide where to go 
moves = [(1,0, "right"), (0,1, "up"), (-1,0, "left"), (0,-1, "down")] 
# My loop for evaluate the steps 
while True: 
    dx, dy, position = moves[randint(0,3)] # By using randint I could make decision randomly 
    x += dx 
    y += dy 
    print("He moved", position) 
    try: 
     times[x][y] += 1 # And here is, how many times have he stood on each square 
     steps += 1 
    except IndexError: # The exit of loop 
     break 
# My print function which answers these questions (How long will it be until he reaeches the end of the sidewalk, and how many times will he have stood on each square) 
for i in range(0,11): 
    for j in range(0,11): 
     print("He took {steps} steps until he reaches end of the sidewalk.".format(steps = steps), "He stood on {1}x{2} square at {0} times".format(times[i][j], i+1,j+1)) 

Dzięki za duży pomaga Dan Gerhardsson. Chyba wreszcie mam rozwiązanie.

+0

Czy to zadanie domowe? – amindfv

+2

Nie, ja po prostu studiuje Pythona z tej książki, http://books.google.com.tr/books/about/Exploring_Python.html?id=VnAsHwAACAAJ&redir_esc=y – mustafaSarialp

Odpowiedz

8

Mogę przynajmniej podać kilka wskazówek. Więc masz cztery możliwe ruchy. Każdy ruch może być reprezentowany przez krotki która jest przesunięcie w osi X i Y kierunkach:

moves = [(0, 1), (1, 0), (0, -1), (-1, 0)] 

aby ustawić pozycję startową w ośrodku:

grid_size = 11 
x = grid_size // 2 
y = grid_size // 2 

Store pozycja pijany i zaktualizuj go w każdym kroku symulacji. Coś takiego:

# Displacement: 
dx, dy = random.choice(moves) 

# Update position: 
x += dx 
y += dy 

To może nie być kodu poziom początkujący, ale zamiast sprawdzania granic z IF-oświadczenie, można spróbować zaktualizować licznik i obsłużyć wyjątek, który jest podniesiony, jeśli pozycja jest poza siecią:

try: 
    # Update counter. 
    times[x][y] += 1 
except IndexError: 
    # Exit the simulation loop. 
    break 

Mam nadzieję, że to pomoże.

EDIT - Uwagi na temat drugiej wersji:

Ponieważ chcesz wydrukować kierunek, w każdym kroku, można dodać, że na krotki:

moves = [(0, 1, 'up'), (1, 0, 'right'), (0, -1, 'down'), (-1, 0, 'left')] 

Następnie można zastąpić, jeśli -statement gdzie można wydrukować kierunek

dx, dy, direction = random.choice(moves) 
print('He moved', direction) 

Podczas korzystania spróbować z wyjątkiem jak w obecnym rozwiązaniu, nie trzeba by sprawdzić związany aries w instrukcji while. Możesz po prostu zrobić:

while True: 
    ... 

ponieważ przerwa w obsłudze wyjątków zakończy pętlę.

Moja ostatnia rada polega na zastąpieniu niektórych literałów liczbami zmiennymi. Rozmiar siatki np. pojawia się w więcej niż jednym miejscu. należy utworzyć zmienną i odwoływać się do niego w pozostałej części kodu:

grid_size = 11 
times = [0] * grid_size 
    for i in range(grid_size): 
     times[i] = [0] * grid_size 

Korzystanie zmienna zamiast liczby literałów oznacza, że ​​po prostu trzeba dokonać zmiany w jednym miejscu, jeśli chcesz uruchomić kod z inny rozmiar siatki.

+0

Świetne wytłumaczenie. – amindfv

+0

Dziękuję. Ale brakowało mi punktów. Jednym z nich jest to, że zgodnie z pytaniem pijany mężczyzna powinien zacząć w środku siatki. Mam na myśli 5x5. Jak możemy to ocenić?Potrzebuję też funkcji drukowania, aby uzyskać odpowiedzi na te pytania (Jak długo potrwa, dopóki nie wykaże końca chodnika i ile razy będzie stał na każdym kwadracie) Więc napisałem funkcję drukowania jest to prawo ? 'print ("Wykonał kilka kroków, aż dotarł do końca chodnika.". Format (steps = steps), "Stał na {1} x {2} kwadracie o {0} razy" .format (razy [i] [j], i + 1, j + 1)) " Miałem również dwie pętle for. – mustafaSarialp

+0

Zmieniłem początkowe wartości xiy, więc mój problem został rozwiązany (w środku siatki) x = 5 y = 5 move = [(1,0), (0,1), (-1,0), (0, -1)] , gdy x <= 10 lub y <= 10: ... Następnie mam jeszcze jedno pytanie do zadawania, Jak utworzyć funkcję drukowania zgodnie z tymi pytaniami (Jak długo to potrwa, dopóki nie dojdzie do końca bocznego spaceru i ile razy będzie stał na każdym kwadracie) – mustafaSarialp

1

Zrobiłem podobny programu losowego spacer co pozwoliło pijany mężczyzna chodzić w dowolnym kierunku w przestrzeni trójwymiarowej przy użyciu współrzędnych sferycznych.

import random 
import math 
def rw3(n,tries): 
    s = 0 
    for m in range(1,tries+1): 
     x = 0 
     y = 0 
     z = 0 
     pi = math.pi 
     for step in range(1,n+1): 
      t = random.uniform(0,2*pi) 
      f = random.uniform(0,2*pi) 
      p = 1 
      x += p*math.sin(f)*math.cos(t) 
      y += p*math.sin(f)*math.sin(t) 
      z += p*math.cos(f) 
     s += (x**2+y**2+z**2)**.5 
    return s/tries 
life = 42 
while life: 
    n = int(input("Please enter the number of steps: ")) 
    tries = int(input("How many times should I perform the experiment? ")) 
    print() 
    print(rw3(n,tries)) 
    print() 
Powiązane problemy