yield / SimPy / Ergebnisse speichern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
hcshm
User
Beiträge: 48
Registriert: Dienstag 11. Februar 2020, 08:23

In nachfolgendem Programm möchte ich gern die aufsummierte charge_duration speichern. Kann mir bitte jemand einen Hinweis geben? Vielen Dank!

import simpy

def car(env, name, bcs, driving_time, charge_duration):

# Simulate driving to the BCS
yield env.timeout(driving_time)
# Request one of its charging spots
print('{} arriving at {}'.format(name, env.now))
req = bcs.request()
yield req

# Charge the battery
print('{} starting to charge at {}'.format(name, env.now))
yield env.timeout(charge_duration)
print('{} leaving the bcs at {}'.format(name, env.now))
bcs.release(req)

env = simpy.Environment()
bcs = simpy.Resource(env, capacity=2)

for i in range(4):
env.process(car(env, 'Car {}'.format(i), bcs, i*2, 5))

env.run()
Benutzeravatar
__blackjack__
User
Beiträge: 14051
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@hcshm: Man könnte den Ladestationen ein zusätzliches Attribut verpassen in dem man die Zeiten aufsummiert:

Code: Alles auswählen

#!/usr/bin/env python3
import simpy


class ChargingStations(simpy.Resource):
    def __init__(self, env, capacity):
        simpy.Resource.__init__(self, env, capacity)
        self.total_charge_time = 0


def car(env, name, charging_stations, driving_time, charge_duration):
    #
    # Simulate driving to the BCS.
    #
    yield env.timeout(driving_time)
    #
    # Request one of its charging spots.
    #
    print("{} arriving at {}".format(name, env.now))
    with charging_stations.request() as request:
        yield request
        #
        # Charge the battery.
        #
        print("{} starting to charge at {}".format(name, env.now))
        yield env.timeout(charge_duration)
        charging_stations.total_charge_time += charge_duration
        print("{} leaving the bcs at {}".format(name, env.now))


def main():
    env = simpy.Environment()
    charging_stations = ChargingStations(env, 2)

    for i in range(4):
        env.process(car(env, "Car {}".format(i), charging_stations, i * 2, 5))

    env.run()
    print(charging_stations.total_charge_time)


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
__blackjack__
User
Beiträge: 14051
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Macht vielleicht aus OOP-Sicht auch Sinn das Aufladen als Simpy-Prozess zu den Ladestationen zu verschieben:

Code: Alles auswählen

#!/usr/bin/env python3
import simpy


class ChargingStations(simpy.Resource):
    def __init__(self, env, capacity):
        simpy.Resource.__init__(self, env, capacity)
        self.total_charge_time = 0

    def charge(self, name, duration):
        with self.request() as request:
            yield request
            print("{} starting to charge at {}".format(name, self._env.now))
            yield self._env.timeout(duration)
            self.total_charge_time += duration
            print("{} leaving the bcs at {}".format(name, self._env.now))


def car(env, name, charging_stations, driving_time, charge_duration):
    yield env.timeout(driving_time)
    print("{} arriving at {}".format(name, env.now))
    yield env.process(charging_stations.charge(name, charge_duration))


def main():
    env = simpy.Environment()
    charging_stations = ChargingStations(env, 2)

    for i in range(4):
        env.process(car(env, "Car {}".format(i), charging_stations, i * 2, 5))

    env.run()
    print(charging_stations.total_charge_time)


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
hcshm
User
Beiträge: 48
Registriert: Dienstag 11. Februar 2020, 08:23

Ganz, ganz herzlichen Dank, __blackjack__ , ich habe als ziemlicher Neuling gestern und heute nacht durchgängig darüber gebrütet und immer wieder und immer weiter überall nachgeschlagen. Und dann erhalte ich innerhalb kürzester Zeit eine so was von qualifizierte und weiterführende Antwort! Erneut ganz herzlichen Dank!
Benutzeravatar
__blackjack__
User
Beiträge: 14051
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wenn es nur ein Wert ist, kann man das auch über Rückgabewerte lösen:

Code: Alles auswählen

#!/usr/bin/env python3
import simpy


def charge_car(env, name, charging_stations, driving_time, charge_duration):
    yield env.timeout(driving_time)
    print(f"{name} arriving at {env.now}")
    with charging_stations.request() as request:
        yield request
        print(f"{name} starting to charge at {env.now}")
        yield env.timeout(charge_duration)
    print(f"{name} leaving the bcs at {env.now}")
    return charge_duration


def main():
    env = simpy.Environment()
    charging_stations = simpy.Resource(env, 2)
    all_cars_charged = env.all_of(
        env.process(charge_car(env, f"Car {i}", charging_stations, i * 2, 5))
        for i in range(4)
    )
    print(sum(env.run(until=all_cars_charged).values()))


if __name__ == "__main__":
    main()
Wobei die Antwort hier natürlich auch komplett ohne Simulation berechnet werden kann wenn Anzahl der Autos und Ladezeit konstant sind, ist das immer 4·5=20.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten