Beispiel #1
0
    def __init__(self, *args, **kwargs):
        super(GasStation, self).__init__(*args, **kwargs)
        config = self.env.config
        self.add_connections('tanker_company')
        self.arrival_interval = config.get('gas_station.arrival_interval', 60)

        station_capacity = config.get('gas_station.capacity', 200)
        self.reservoir = Container(self.env,
                                   capacity=station_capacity,
                                   init=station_capacity)
        self.auto_probe('reservoir', log={})

        self.threshold_pct = config.get('gas_station.threshold_pct', 10)

        self.pump_rate = config.get('gas_station.pump_rate', 2)
        num_pumps = config.get('gas_station.pumps', 2)
        self.fuel_pumps = Resource(self.env, capacity=num_pumps)
        self.auto_probe('fuel_pumps', log={})

        self.car_capacity = config.get('car.capacity', 50)
        self.car_level_range = config.get('car.level', [5, 25])

        # A gas station has two persistent processes. One to monitor the
        # reservoir level and one that models the arrival of cars at the
        # station. Desmod starts these processes before simulation phase.
        self.add_processes(self._monitor_reservoir, self._traffic_generator)
Beispiel #2
0
    def run(self):
        wait = None
        taken_inf = []
        completed_flags = {}

        for action_id in self.action_tree.actions.keys():
            completed_flags[action_id] = Container(self.sim)

        for action in self.action_tree.actions.values():
            self.sim.process(
                self.execute(action, taken_inf, self.sim, completed_flags))

        for flag in completed_flags.values():
            if wait is None:
                wait = flag.get(1)
            else:
                wait = wait & flag.get(1)
        yield wait

        if self.aborted:
            for res in taken_inf:
                self.sim.put_res(res)

        taken_inf.clear()

        if len(taken_inf) != 0:
            raise Exception("Resources not free at end of task")

        self.sim.manager.activate()
Beispiel #3
0
    def __init__(self,
                 env,
                 name=None,
                 savings=0,
                 insurance=0,
                 credit=0,
                 write_story=False):
        """Initiate an Entity object

        Keyword Arguments:
        env -- Pointer to SimPy env environment.
        name -- A string indicating the entities name.
        savings -- Amount of entity savings in $ 
        insurance -- Hazard-specific insurance coverage: coverage / residence.value
        credit -- A FICO-like credit score
        write_story -- Boolean indicating whether to track an entity's story.
        
        Modified Attributes
        self.recovery_funds -- initiated with value of self.savings
        """
        self.env = env

        # Entity attributes
        self.name = name  # Name associated with occupant of the home %***%
        self.write_story = write_story  # Boolean. Whether to track the entity's story.
        self.insurance = insurance  # Hazard-specific insurance coverage: coverage / residence.value
        self.savings = savings  # Amount of entity savings in $
        self.credit = credit  # A FICO-like credit score

        # Entity outputs
        self.story = []  # The story of events for each entity
        self.claim_put = None  # Time put request in for insurance settlement
        self.claim_get = None  # Time get insurance claim settled
        self.claim_amount = 0.0  # Amount of insurance claim payout
        self.fema_put = None  # Time put request in for FEMA assistance
        self.fema_get = None  # Time get FEMA assistance
        self.fema_amount = 0.0  # Amount of assistance provided by FEMA
        self.sba_put = None  # Time put request for loan
        self.sba_get = None  # Time get requested loan
        self.sba_amount = 0.0  # Amount of loan received

        try:
            self.recovery_funds = Container(
                env, init=self.savings
            )  # Total funds available to entity to recover; must be > 0
        except:
            self.recovery_funds = Container(env, init=1)  # init must be > 0
def tank_truck(env: simpy.Environment,
               fuel_pump: simpy.Container) -> Generator:
    """Arrives at the gas station after a certain delay and refuels it."""
    yield env.timeout(TANK_TRUCK_TIME)
    print(f"Tank truck arriving at time {env.now:.1f}")
    ammount = fuel_pump.capacity - fuel_pump.level
    print(f"Tank truck refuelling {ammount:.1f} liters.")
    yield fuel_pump.put(ammount)
Beispiel #5
0
def _attach_container_level(container: simpy.Container,
                            callbacks: ProbeCallbacks) -> None:
    def make_wrapper(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            old_level = container._level
            ret = func(*args, **kwargs)
            new_level = container._level
            if new_level != old_level:
                for callback in callbacks:
                    callback(new_level)
            return ret

        return wrapper

    container._do_get = make_wrapper(container._do_get)  # type: ignore
    container._do_put = make_wrapper(container._do_put)  # type: ignore
Beispiel #6
0
 def __init__(self, simulation):
     assert isinstance(simulation, Simulation.Simulation)
     self.sim = simulation
     self.type_map = {}
     self.event_queue = []
     self.sim.process(self.__auto_run__())
     self.activation = Container(self.sim, float('inf'), 0)
     self.last_active = -1
Beispiel #7
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.add_connections('grocery')
     self.add_process(self.generate_customers)
     self.active = Container(self.env)
     self.auto_probe('active', vcd={})
     if self.env.tracemgr.sqlite_tracer.enabled:
         self.db = self.env.tracemgr.sqlite_tracer.db
         self.db.execute('CREATE TABLE customers '
                         '(cust_id INTEGER PRIMARY KEY,'
                         ' num_items INTEGER,'
                         ' shop_time REAL,'
                         ' checkout_time REAL)')
     else:
         self.db = None
Beispiel #8
0
    def __init__(self, *args, **kwargs):
        super(TankerTruck, self).__init__(*args, **kwargs)
        self.pump_rate = self.env.config.get('tanker.pump_rate', 10)
        self.avg_travel = self.env.config.get('tanker.travel_time', 600)
        tank_capacity = self.env.config.get('tanker.capacity', 200)
        self.tank = Container(self.env, tank_capacity)

        # This auto_probe() call causes the self.tank Container to be
        # monkey-patched such that whenever it's level changes, the new level
        # is noted in the log.
        self.auto_probe('tank', log={})

        # The parent TankerCompany enqueues instructions to this queue.
        self._instructions = Queue(self.env)

        # Declare a persistant process to be started at simulation-time.
        self.add_process(self._dispatch_loop)
Beispiel #9
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.cashier = Cashier(self)

        self.customer_queue = Resource(self.env)
        self.auto_probe('customer_queue', trace_queue=True, vcd={'init': 0})

        feed_capacity = self.env.config['checkout.feed_capacity']
        self.feed_belt = Queue(self.env, capacity=feed_capacity)
        self.auto_probe('feed_belt', vcd={})

        bag_area_capacity = self.env.config['checkout.bag_area_capacity']
        self.bag_area = Queue(self.env, capacity=bag_area_capacity)
        self.auto_probe('bag_area', vcd={})

        self.baggers = Container(self.env)
        self.auto_probe('baggers', vcd={})
Beispiel #10
0
    def __init__(self, env, duration, staff=float('inf'), budget=float('inf')):
        """Initiate financial recovery program attributes.

        Keyword Arguments:
        env -- simpy.Envionment() object
        duration -- io.ProbabilityDistribution() object
        staff -- Integer, indicating number of staff assigned to the programs
        budget -- Integer or float, indicating the initial budget available from
                    the recovery program.

        Attribute Changes:
        self.staff -- A simpy.Resource() object with a capacity == staff arg
        self.budget -- A simpy.Container() object with a initial value == budget arg
        self.duration -- A function that is used to calculate random durations
                            for the program process
        """
        self.env = env
        self.staff = Resource(self.env, capacity=staff)
        self.budget = Container(self.env, init=budget)
        self.duration = duration
Beispiel #11
0
    def __init__(
        self,
        env: Environment,
        name: str,
        consumed_resource: str,
        coordinates_holder: CoordinatesHolder,
        consumed_per_product=1,
        block_capacity=1,
        xy: Tuple[int, int] = (0, 0),
        ways: Dict[str, List[Tuple[int, int]]] = {},
    ):
        super().__init__(env, name, block_capacity, xy, ways)

        self.coordinates_holder = coordinates_holder
        self.container = Container(
            self.env, float("inf"), init=0
        )  # (a limited capacity here can cause deadlocks due to impossible unloading of loaded resources)

        self.consumed_resource = consumed_resource

        self.location = self.name
        self.coordinates = cast(
            Tuple[float, float],
            self.coordinates_holder.get_coords(self.location))
        # slight offset to the right:
        self.text_coordinates = cast(
            Tuple[float,
                  float], (self.coordinates[0] + 80, self.coordinates[1] + 50))

        self.consumed_per_product = consumed_per_product

        self.tilemap_visualizer: Optional[TuggerTilemapVisualizer] = None

        self.do_on_enter_list.append(self.animate_entity_on_enter)

        # additional states for observation:
        self.waiting_for_material = False
        self.processing_a_product = False
Beispiel #12
0
    def __init__(self, env, id, area, perimeter, can_see, replenish_rate=0.1):
        """

        :param env:
        :type env: Environment
        :type id: int
        :param area:
        :type area: float
        :param perimeter:
        :type perimeter: float
        :param can_see:
        :type can_see: dict[int, float]
        """
        r_cap = int(area / 0.17384) + 1
        # r_cap = MAX_CAPACITY
        perimeter = int(perimeter * DEG_TO_KM) + 1

        self.env = env
        self.id = id
        self.area = area
        self.perimeter = perimeter
        self._can_see = can_see
        self.can_see, self.probs = self.normalise(can_see)
        self.replenish_rate = replenish_rate
        self.r = Resource(self.env, capacity=r_cap)
        self.c = Container(self.env, capacity=perimeter, init=perimeter)
        self.action = self.env.process(self.replenish())
        self._populations = set()

        self._pop = None
        self._pop_calc_time = None

        self._density = None
        self._density_calc_time = None

        self._capacity = None
        self._capacity_calc_time = None
def car(env: simpy.Environment, name: str, gas_station: simpy.Resource,
        fuel_pump: simpy.Container) -> Generator:
    """A car arrives at the gas station for refueling.

    It requests one of the gas station's fuel pumps and tries to get the
    desired amount of gas from it. If the stations reservoir is
    depleted, the car has to wait for the tank truck to arrive.

    """
    fuel_tank_level = random.randint(*FUEL_TANK_LEVEL)
    print(f"{name} arriving at gas station at {env.now:.1f}")
    with gas_station.request() as req:
        start = env.now
        # Request one of the gas pumps
        yield req

        # Get the required amount of fuel
        liters_required = FUEL_TANK_SIZE - fuel_tank_level
        yield fuel_pump.get(liters_required)

        # The "actual" refueling process takes some time
        yield env.timeout(liters_required / REFUELING_SPEED)

        print(f"{name} finished refueling in {env.now - start:.1f} seconds")
Beispiel #14
0
 def init(self, **kwargs):
     Container.__init__(self, **kwargs)
Beispiel #15
0
 def __init__(self, *args, **kwargs):
     super(Customers, self).__init__(*args, **kwargs)
     self.add_connections('grocery')
     self.add_process(self.generate_customers)
     self.active = Container(self.env)
     self.auto_probe('active', vcd={})
Beispiel #16
0
def population(env, name, islands, start_island, g, consumption_rate=1, move_propensity=1):
    """

    :param env:
    :type env: Environment
    :param name:
    :type name: int
    :param islands:
    :type islands: dict[int, abm.resources.Island]
    :param start_island:
    :type start_island: int
    :param consumption_rate:
    :type consumption_rate: int
    :param move_propensity:
    :type move_propensity: int
    """

    times_starved = 0
    dead = False
    # route = []
    island_containers = {}
    visited = {1630, 1957, 1766, 1771, 1737, 1802}
    backtrack = []
    global total_dead
    global in_australia

    def weighted_choice(islands, probs, visited):
        """
        :type islands: numpy.ndarray
        :type probs: numpy.ndarray
        :type visited: set[int]
        :rtype: int
        """
        mask = in1d(islands, list(visited), invert=True)
        m = islands[mask]
        p = probs[mask] / probs[mask].sum()
        if len(m) > 0:
            c = choice(m, size=1, p=p)
            if len(c) > 0:
                return c[0]

    current_island = start_island
    current_request = yield islands[current_island].r.request() | env.timeout(100)
    start = env.now
    i = islands[current_island]
    visited.add(i.id)
    logger.debug("%05d Population %s appears on %s at %s", env.now, name, start_island, start)
    yield env.timeout(TICK_SIZE)

    while i.id != FINISH_ISLAND:
        will_move = i.id == START_ISLAND or (island_containers[i.id].resource_level / island_containers[
            i.id].capacity) < random.expovariate(EXP_LAMBDA) * move_propensity
        if will_move:
            mt = weighted_choice(i.can_see, i.probs, visited)
            if mt is None:
                if len(backtrack) == 0:
                    logger.debug("POPULATION %s IS A FAILURE!!!!", name)
                    dead = True
                    total_dead += 1
                    break
                backtrack_island = islands[backtrack.pop(-1)]
                logger.debug('%05d Population %s is stuck on %s. Moving back to previous island %s', env.now, name, i,
                             backtrack_island)
                release_old = i.r.release(current_request)
                current_request = backtrack_island.r.request()
                yield release_old & current_request
                # route.append((env.now, i.id, backtrack_island.id))
                if 'traversals' not in g.edge[i.id][backtrack_island.id]:
                    g.edge[i.id][backtrack_island.id]['traversals'] = 1
                else:
                    g.edge[i.id][backtrack_island.id]['traversals'] += 1
                i = backtrack_island
            else:
                move_to = islands[mt]
                if move_to.r.capacity > move_to.r.count:
                    release_old = i.r.release(current_request)
                    current_request = move_to.r.request()
                    yield release_old & current_request
                    visited.add(move_to.id)
                    backtrack.append(i.id)
                    # route.append((env.now, i.id, move_to.id))
                    if 'traversals' not in g.edge[i.id][move_to.id]:
                        g.edge[i.id][move_to.id]['traversals'] = 1
                    else:
                        g.edge[i.id][move_to.id]['traversals'] += 1
                    logger.debug('%05d Population %s moved from %s to %s', env.now, name, i, move_to)
                    i = move_to
                else:
                    logger.info(
                        '%05d Population %s tried to move from %s to %s but were rebuffed by existing population',
                        env.now, name, i, move_to)
                    # else:
                    #     logger.debug('{:05d} Population {} is stuck on {} and will probably die'.format(env.now, name, i))
        if i.id not in island_containers:
            island_containers[i.id] = Container(env, capacity=i.perimeter, init=i.perimeter)
        if island_containers[i.id].resource_level >= consumption_rate * TICK_SIZE:
            yield island_containers[i.id].get(consumption_rate * TICK_SIZE)
            if times_starved:
                if times_starved > 1:
                    times_starved -= 1
                else:
                    times_starved = 0

            logger.debug("%05d Population %s consumed %sKM of %s (%0.1f/%0.1f) coastline",
                         env.now, name, consumption_rate * TICK_SIZE, i, island_containers[i.id].resource_level,
                         island_containers[i.id].capacity)
        else:
            to_consume = island_containers[i.id].resource_level
            if to_consume > 0:
                yield island_containers[i.id].get(to_consume)
            times_starved += min(1, (consumption_rate - to_consume))
            if times_starved >= DIE_AFTER_N_STARVATION:
                logger.info("%05d Population %s STARVED TO DEATH on %s", env.now, name, i)
                dead = True
                total_dead += 1
                n = g.node[i.id]
                if 'died' not in n:
                    n['died'] = 1
                else:
                    n['died'] += 1
                yield i.r.release(current_request)
                break
            logger.debug("%05d Population %s is STARVING and consumed %sKM of %s (%0.1f/%0.1f) coastline",
                         env.now, name, to_consume, i, island_containers[i.id].resource_level,
                         island_containers[i.id].capacity)
        yield env.timeout(TICK_SIZE)
    if not dead:
        logger.info("%05d Population %s MADE IT TO AUSTRALIA!!!", env.now, name)
        with open('times.txt', 'a') as nf:
            nf.write('{}\n'.format(env.now - start))
        in_australia += 1