Hallo, du machst einen dreijährigen Schüler. Dies ist mein erster Beitrag, und ich möchte eine Rolltreppensimulation vorstellen. Die Sprache ist Python3.
Rolltreppenbenutzer werden grob in zwei Typen unterteilt: diejenigen, die anhalten und diejenigen, die gehen. In Japan ist die Position zum Stoppen je nach Region unterschiedlich, z. B. Ostjapan links und Westjapan rechts, und das gleiche Phänomen ist in Übersee zu beobachten. Tatsächlich wird die Position, an der die Rolltreppe anhält, durch das Nash-Gleichgewicht in der Spieltheorie bestimmt. Menschen, die still stehen, fühlen sich gestresst, wenn sie von einer Person getroffen werden, die von hinten geht, und sie möchten ab dem nächsten Mal auf einer anderen Seite fahren.
In dieser Simulation wird die Hälfte der Personen, die anhalten, und die Hälfte der Personen, die gehen, generiert, und es wird zufällig festgelegt, ob die Anfangsposition links oder rechts ist. Darüber hinaus messen wir die Vorlieben aller Benutzer für die linke und rechte Position und bestimmen den nächsten Benutzer anhand der Größe des Werts. Durch diese Operationen werden die Position, die von der Person verwendet wird, die anhält, und die Position, die von der gehenden Person verwendet wird, auf einer Seite der Rolltreppe konvergiert.
Anschließend werden der Quellcode und die Erklärung dafür unten beschrieben.
Definieren Sie zunächst die Klassen der Person, die anhält (= StandHuman) und der Person, die geht (= WalkHuman). Der einzige Unterschied zwischen den beiden besteht darin, ob sie anhalten oder gehen (= aktiv) und die Geschwindigkeit (= v, ich denke, die Geschwindigkeit s ist physikalisch angemessener).
escalator.py
class StandHuman:
def __init__(self):
self.active = False
self.v = 0 #speed
self.x = 0 #position(left/right)
self.l_like = 0 #how much a human like to ride on the left
self.r_like = 0 #how much a human like to ride on the right
class WalkHuman:
def __init__(self):
self.active = True
self.v =1 #speed
self.x = 0 #position(left/right)
self.l_like = 0 #how much a human like to ride on the left
self.r_like = 0 #how much a human like to ride on the right
Anzahl der Personen, die aus 0 generiert werden sollen (= NUMBER_OF_HUMANS) Bereiten Sie eine Liste mit ganzzahligen Zeichenfolgen von -1 als Elemente vor, mischen Sie die Elemente der Liste und beurteilen Sie dann, ob die Elemente ungerade oder gerade sind, damit alle Benutzer sie verwenden können. Die Hälfte der Menschen hört auf und die Hälfte der Menschen geht, während sie in der Reihenfolge ihres Tuns Zufälligkeit geben.
escalator.py
def human_random():
odd_or_even = list(range(NUMBER_OF_HUMANS))
random.shuffle(odd_or_even)
for i in range(NUMBER_OF_HUMANS):
if odd_or_even[i] % 2 == 0:
human = StandHuman()
else:
human = WalkHuman()
human_list.append(human)
Die Position, auf der Rolltreppe zu fahren, wird basierend auf den Vorlieben für jede der linken und rechten Seiten zu diesem Zeitpunkt bestimmt. Wenn der linke Geschmack hoch ist, wird der linke bestimmt, wenn der rechte Geschmack hoch ist, wird der rechte bestimmt, und wenn der linke und der rechte Geschmack gleich sind, werden der linke und der rechte zufällig bestimmt. Da die Anfangswerte des linken und rechten Likes beide auf 0 gesetzt sind, werden der linke und der rechte bei der ersten Verwendung zufällig bestimmt.
escalator.py
def side_decision(human):
l = human.l_like
r = human.r_like
if l > r:
human.x = 0
elif l < r:
human.x = 1
else:
random_x = random.random()
if random_x <= 0.5:
human.x = 0
else:
human.x = 1
Die Funktion add_human versetzt den Benutzer nur auf die Rolltreppe. Der Einfachheit halber hat die Rolltreppe jedoch vier Reihen: (1) links für Personen, die anhalten, (2) links für Personen, die gehen, (3) rechts für Personen, die anhalten, und (4) rechts für Personen, die gehen.
escalator.py
def add_human(human):
if human.active == False:
if human.x == 0: #if left
escalator[0][0] = human
else: #if right
escalator[2][0] = human
else:
if human.x == 0: #if left
escalator[1][0] = human
else: #if right
escalator[3][0] = human
Bewegen Sie die Rolltreppe einen Schritt. Als eigentliches Programm Benutzer Es wird einen Schritt nach oben verschoben und im Fall des höchsten Schritts auf 0 (Anfangswert) zurückgesetzt.
escalator.py
def shift():
for i in range(STEPS-1):
escalator[0][STEPS-i-1] = escalator[0][STEPS-i-2]
escalator[1][STEPS-i-1] = escalator[1][STEPS-i-2]
escalator[2][STEPS-i-1] = escalator[2][STEPS-i-2]
escalator[3][STEPS-i-1] = escalator[3][STEPS-i-2]
escalator[0][0] = 0
escalator[1][0] = 0
escalator[2][0] = 0
escalator[3][0] = 0
Die Crash-Funktion behandelt den Fall einer Kollision. Hier wirkt sich die Position (Anzahl der Stufen) zum Zeitpunkt der Kollision auf die vom Benutzer empfundene Belastung aus. Je niedriger die Stufe, desto leichter ist es, die Belastung zu spüren. Darüber hinaus sind beide Prozesse getrennt, um die Zufälligkeit des Stresses aufrechtzuerhalten, den die Stehenden und die Gehenden empfinden. Der vom Benutzer empfundene Stress führt direkt zu einer Abnahme der Günstigkeit. Die Funktion crash_checker erkennt eine Kollision und übergibt den kollidierenden Benutzer an die Absturzfunktion.
escalator.py
def crash(front, front_position, behind):
x = random.random() * STEPS
if x <= 1-(front_position + 1)/STEPS:
if front.x == 0: #if left
front.l_like -= x
else: #if right
front.r_like -= x
y = random.random() * STEPS
if y <= 1-(front_position + 1)/STEPS:
if front.x == 0: #if left
behind.l_like -= y
else: #if right
behind.r_like -= y
def crash_checker():
for i in range(STEPS): #left
if escalator[0][i] != 0 and escalator[1][i] != 0:
crash(escalator[0][i], i, escalator[1][i])
for i in range(STEPS): #right
if escalator[2][i] != 0 and escalator[3][i] != 0:
crash(escalator[2][i], i, escalator[3][i])
Da eine gehende Person einen "gehenden" Prozess benötigt, wird zusätzlich zu der Schaltfunktion, die die Rolltreppe bewegt, eine neue Gehfunktion bereitgestellt.
escalator.py
def end_checker_for_walker():
escalator[1][STEPS-1] = 0
escalator[3][STEPS-1] = 0
def walk():
for i in range(STEPS):
l = escalator[1][i]
r = escalator[3][i]
if l != 0:
escalator[1][STEPS-i-1+(l.v)] = escalator[1][STEPS-i-1]
if r != 0:
escalator[3][STEPS-i-1+(r.v)] = escalator[3][STEPS-i-1]
Hier dreht sich alles um den Quellcode. Der gesamte Quellcode lautet wie folgt.
escalator.py
import random
import pandas as pd
NUMBER_OF_HUMANS = 100
TIME_END = 1000000
STEPS = 100
human_list = list()
escalator = [[0] * STEPS for i in range(4)] #[[sl], [wl], [sr], [wr]]
class StandHuman:
def __init__(self):
self.active = False
self.v = 0 #speed
self.x = 0 #position(left/right)
self.l_like = 0 #how much a human like to ride on the left
self.r_like = 0 #how much a human like to ride on the right
class WalkHuman:
def __init__(self):
self.active = True
self.v =1 #speed
self.x = 0 #position(left/right)
self.l_like = 0 #how much a human like to ride on the left
self.r_like = 0 #how much a human like to ride on the right
def human_random():
odd_or_even = list(range(NUMBER_OF_HUMANS))
random.shuffle(odd_or_even)
for i in range(NUMBER_OF_HUMANS):
if odd_or_even[i] % 2 == 0:
human = StandHuman()
else:
human = WalkHuman()
human_list.append(human)
def shift():
for i in range(STEPS-1):
escalator[0][STEPS-i-1] = escalator[0][STEPS-i-2]
escalator[1][STEPS-i-1] = escalator[1][STEPS-i-2]
escalator[2][STEPS-i-1] = escalator[2][STEPS-i-2]
escalator[3][STEPS-i-1] = escalator[3][STEPS-i-2]
escalator[0][0] = 0
escalator[1][0] = 0
escalator[2][0] = 0
escalator[3][0] = 0
def crash(front, front_position, behind):
x = random.random() * STEPS
if x <= 1-(front_position + 1)/STEPS:
if front.x == 0: #if left
front.l_like -= x
else: #if right
front.r_like -= x
y = random.random() * STEPS
if y <= 1-(front_position + 1)/STEPS:
if front.x == 0: #if left
behind.l_like -= y
else: #if right
behind.r_like -= y
def crash_checker():
for i in range(STEPS): #left
if escalator[0][i] != 0 and escalator[1][i] != 0:
crash(escalator[0][i], i, escalator[1][i])
for i in range(STEPS): #right
if escalator[2][i] != 0 and escalator[3][i] != 0:
crash(escalator[2][i], i, escalator[3][i])
def walk():
for i in range(STEPS):
l = escalator[1][i]
r = escalator[3][i]
if l != 0:
escalator[1][STEPS-i-1+(l.v)] = escalator[1][STEPS-i-1]
if r != 0:
escalator[3][STEPS-i-1+(r.v)] = escalator[3][STEPS-i-1]
def side_decision(human):
l = human.l_like
r = human.r_like
if l > r:
human.x = 0
elif l < r:
human.x = 1
else:
random_x = random.random()
if random_x <= 0.5:
human.x = 0
else:
human.x = 1
def add_human(human):
if human.active == False:
if human.x == 0: #if left
escalator[0][0] = human
else: #if right
escalator[2][0] = human
else:
if human.x == 0: #if left
escalator[1][0] = human
else: #if right
escalator[3][0] = human
def main():
for i in range(TIME_END):
shift()
crash_checker()
walk()
crash_checker()
h = human_list[i % NUMBER_OF_HUMANS]
side_decision(h)
add_human(h)
human_random()
main()
Dieses Mal wurde die Anzahl der Versuche auf 1 Million festgelegt, die Anzahl der Benutzer wurde auf 100 festgelegt (Stehen: 50, Schritte: 50) und die Anzahl der Rolltreppenstufen wurde auf 100 festgelegt. Wenn ich mir die Ergebnisse unten ansehe, habe ich den Eindruck, dass sie gut zusammengewachsen sind.
Unten finden Sie eine einfache Visualisierung der Rolltreppe, wenn die angegebene Anzahl von Versuchen erreicht ist. Wir geben auch die Gesamtzahl der Personen aus, die in der linken und rechten Spalte stehen und gehen, sowie das Verhältnis von beiden. (S: Menschen, die still stehen, w: Menschen, die gehen, 0: Frei)
| s 0 | 0 0 |
| 0 0 | 0 w |
| s 0 | 0 w |
| s 0 | 0 w |
| s 0 | 0 w |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| s 0 | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| 0 0 | 0 0 |
| 0 0 | 0 0 |
| 0 0 | 0 0 |
| 0 0 | 0 w |
| 0 0 | 0 w |
| s 0 | 0 w |
| 0 0 | 0 w |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| s 0 | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| 0 0 | 0 0 |
| 0 0 | 0 0 |
| s 0 | 0 w |
| s 0 | 0 w |
| s 0 | 0 w |
| s 0 | 0 w |
| s 0 | 0 0 |
| s 0 | 0 0 |
| s 0 | 0 0 |
| s 0 | 0 w |
| s 0 | 0 w |
| s 0 | 0 w |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| 0 0 | 0 w |
| s 0 | 0 0 |
| s 0 | 0 0 |
| s 0 | 0 w |
| 0 0 | 0 0 |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 w |
| 0 0 | 0 w |
| s 0 | 0 0 |
| s 0 | 0 w |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 w |
| 0 0 | 0 w |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| s 0 | 0 w |
| 0 0 | 0 0 |
| 0 0 | 0 w |
| s 0 | 0 0 |
| s 0 | 0 w |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 w |
| 0 w | 0 w |
| 0 0 | 0 w |
| 0 w | 0 0 |
| 0 w | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 w |
| 0 0 | 0 0 |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| s 0 | 0 w |
| 0 0 | 0 0 |
| 0 w | 0 0 |
| 0 0 | 0 w |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| 0 w | 0 w |
| s 0 | 0 0 |
| 0 0 | 0 0 |
| s 0 | 0 w |
| 0 0 | 0 0 |
| s 0 | 0 0 |
| 0 0 | 0 w |
#----------------------------------------------#
WalkHuman/StandHuman of left: 0.1 W:S= 5 50
WalkHuman/StandHuman of right: 34.0 W:S= 34 0
Alle Benutzer (die ersten 100 generierten Personen) verglichen die linke und rechte Seite der Rolltreppe in einer Tabelle (ob sie es nicht mögen).
Left Right
StandHuman 50 0
WalkHuman 5 45
Daher denke ich, dass es eine vernünftige Simulation war. Da dies meine erste Simulationserstellung war, denke ich, dass es viele lose Teile gibt, aber ich möchte mich so weit wie möglich weiter verbessern.