[PYTHON] Rolltreppensimulation

Einführung

Hallo, du machst einen dreijährigen Schüler. Dies ist mein erster Beitrag, und ich möchte eine Rolltreppensimulation vorstellen. Die Sprache ist Python3.

Über Rolltreppe

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.

Simulationsübersicht

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.

Quellcode / Beschreibung

Anschließend werden der Quellcode und die Erklärung dafür unten beschrieben.

Benutzerdefinition

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

Benutzergenerierung

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)

Bestimmen der Position (links und rechts) für die Fahrt auf der Rolltreppe

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

Stellen Sie den Benutzer auf die Rolltreppe

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

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

Bestätigung der Kollision / Verarbeitung zum Zeitpunkt der Kollision

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])

Verarbeitung nur für laufende Personen

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]

Ganzer Quellcode

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()

Simulationsergebnis

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.

Rolltreppenergebnisse

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

Vergleich der Begünstigung (Stress)

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

abschließend

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.

Recommended Posts

Rolltreppensimulation
Simulation der Gebotsoptimierung
Doppelpendelsimulation
Ambisonics Simulation Python
Python - Partikelbewegungssimulation
RC-Schaltungssimulation
Stromsimulation steigern