Exemplo n.º 1
0
    def act(self, time, round_no, step_no):

        work_capacity = self.model.dt * self.model.productivity

        while work_capacity > 0:
            if self.state == "available":

                self.task = self.model.next_agent("task", "open")

                if self.task is not None:

                    self.state = "busy"
                    self.task.receive_instantaneous_event(
                        Event("task_started", self.id, self.task.id))
                else:
                    # no more open tasks
                    work_capacity = 0

            if self.state == "busy":

                # the actual progress we make on a task depends on the remaining effort

                work_done = min(work_capacity, self.task.remaining_effort)
                work_capacity -= work_done

                self.task.receive_instantaneous_event(
                    Event("task_progress", self.id, self.task.id,
                          {"progress": work_done}))

                if self.task.state == "closed":
                    self.state = "available"
                    self.task = None
Exemplo n.º 2
0
 def act(self, time, round_no, step_no):
     if self.state == "INFECTED_LIGHT":
             # or self.state == "INFECTED_HARD":
         infected_contacts = 0
         for i in range(0,self.model.contact_rate):
             if np.random.choice(["HEALTHY", "INFECTED"], p=[1-self.model.infectivity, self.model.infectivity]) \
                     == "INFECTED":
                 infected_contacts += 1
         self.infected = infected_contacts
         infected_light = round(0.8*infected_contacts)
         infected_hard = round(0.2*infected_contacts)
         event_factory_hard = lambda agent_id: Event("infection_hard", self.id, agent_id, data=None)
         event_factory_light = lambda agent_id: Event("infection_light", self.id, agent_id, data=None)
         self.model.random_events("person", infected_hard, event_factory_hard)
         self.model.random_events("person", infected_light, event_factory_light)
Exemplo n.º 3
0
    def act(self, time, sim_round, step):
        # take care of deliveries and orders
        self.deliver(time, sim_round, step)
        self.order(time, sim_round, step)
        # update the stocks
        self.incoming_orders += self.incoming_order
        self.outgoing_deliveries += self.outgoing_delivery
        self.incoming_deliveries += self.incoming_delivery
        self.outgoing_orders += self.outgoing_order
        # update the KPIs
        self.outstanding_orders = self.outgoing_orders - self.incoming_deliveries
        self.backorder = self.incoming_orders - self.outgoing_deliveries
        self.inventory += self.incoming_delivery - self.outgoing_delivery
        self.surplus = self.inventory - self.backorder
        self.order_balance = self.outgoing_orders - self.incoming_orders
        # cost kpi
        self.cost = self.backorder * self.model.backorder_item_cost + max(
            self.inventory * self.model.inventory_item_cost,
            self.model.minimum_inventory_cost)
        self.total_cost += self.cost
        # send the cost to the controller (in this round)

        self.model.next_agent("controlling",
                              "active").receive_instantaneous_event(
                                  Event("cost", self.id, 0,
                                        {"cost": self.cost}))
Exemplo n.º 4
0
 def order(self, time, sim_round, step):
     # this is the "typical" behaviour seen by users
     amount = self.calculate_order(time)
     self.model.broadcast_event(
         self.supplier, lambda agent_id: Event("order", self.id, agent_id,
                                               {"order": amount}))
     self.outgoing_order = amount
Exemplo n.º 5
0
 def deliver(self, time, sim_round, step):
     amount = min(self.inventory + self.incoming_delivery,
                  self.backorder + self.incoming_order)
     self.model.broadcast_event(
         self.customer, lambda agent_id: Event(
             "delivery", self.id, agent_id, {"delivery": amount}))
     self.outgoing_delivery = amount
Exemplo n.º 6
0
    def order(self, time, sim_round, step):
        amount = self.weekly_order if time > 1 else 100

        self.model.next_agent(self.supplier,
                              "active").receive_instantaneous_event(
                                  Event("order", self.id, 0,
                                        {"order": amount}))
        # self.model.broadcast_event(self.supplier, lambda agent_id: Event("order", self.id, agent_id, {"order": amount}))
        self.outgoing_order = amount
Exemplo n.º 7
0
    def end_round(self, time, sim_round, step):
        supply_chain_agents = {"brewery", "distributor", "wholesaler", "retailer"}
        controlling_agent = None
        total_reward = 0
        
        for agent in self.agents:
            if agent.agent_type == "controlling":
                controlling_agent = agent

        for agent in self.agents:
            reward = 0
            if agent.agent_type in supply_chain_agents and not self.game_over:
                if (agent.order_balance < 0  or agent.order_balance > 1400):
                    self.game_over = True
                    self.game_over_round = time + 1 # run one more round to pickup the rewards, then stop
                    reward = -10000
                elif agent.outgoing_order < agent.incoming_order:
                    reward = -10000
                else:
                    if time == 3:
                        if 750 >= agent.order_balance >= 600:
                            reward += 2000
                    if time == 5:
                        if 900 >= agent.order_balance >= 700:
                            reward += 2000      
                    if time == 10:
                        if 1150 >= agent.order_balance >= 1000:
                            reward += 2000      
                    if time == 15:
                        if 1250 >= agent.order_balance >= 1100:
                            reward += 2000
                    if time == 20:
                        if 1250 >= agent.order_balance >= 1150:
                            reward += 2000
                    if time == self.stoptime - 1: # penultimate round, to ensure rewards are handled in final round
                        if agent.total_cost < 10000:
                            reward += 10000
                        if controlling_agent.supply_chain_cost < 40000:
                            reward += 20000
                total_reward += reward
                agent.receive_instantaneous_event(Event("reward", None, agent.id, {"reward": reward}))
        controlling_agent.receive_instantaneous_event(Event("supply_chain_reward", None, None, {"supply_chain_reward": total_reward}))
Exemplo n.º 8
0
    def act(self, time, round_no, step_no):
        if self.state == "HEALTHY":
            self.move()
        elif self.state == "DEAD":
            pass
        elif self.
        if self.state == "INFECTED_LIGHT":
            # or self.state == "INFECTED_HARD":
            infected_contacts = 0
            for i in range(0, self.model.contact_rate):
                if np.random.choice(["HEALTHY", "INFECTED"], p=[1 - self.model.infectivity, self.model.infectivity]) \
                        == "INFECTED":
                    infected_contacts += 1
            self.infected = infected_contacts
            infected_light = round(0.8 * infected_contacts)
            infected_hard = round(0.2 * infected_contacts)
            event_factory_hard = lambda agent_id: Event("infection_hard", self.id, agent_id, data=None)
            event_factory_light = lambda agent_id: Event("infection_light", self.id, agent_id, data=None)
            self.model.random_events("person", infected_hard, event_factory_hard)
            self.model.random_events("person", infected_light, event_factory_light)

    def move(self):
        position_found = 0
        found = False
        while not found:
            indices = [i for i in range(0, len(self.MOVING_LIST))]
            moving = self.MOVING_LIST[np.random.choice(indices)]
            position_found = (self.position[0]+moving[0], self.position[1]+moving[1])
            if position_found[0] >= 0 and position_found[0]<=20 and \
                position_found[1] >= 0 and position_found[1] <=20:
                found = True
                break

        self.position = position_found

    def find_neighbors(self):
         position = 0
         neighbors_list = []
         for moving_element in self.MOVING_LIST:
             position = (self.position[0]+moving_element[0], self.position[1]+moving_element[1])
             for agent in self.model.agents:
                 if agent == self:
                     continue
                 if agent.position == position:
                     neighbors_list.append(agent.position)
         return neighbors_list

    def check_infected(self, neighbors):
         for agent in self.model.agents:
             if agent == self:
                 continue
             if agent.position in neighbors:
                 if agent.state == "INFECTED":
                     self.state = "INFECTED"
                     self.model.infected += 1
                     print("Waaah I got infected")
                     self.infected =  1
                     break

    def infect_neighbors(self,neighbors):
        for agent in self.model.agents:
            if agent == self:
                continue
            if agent.position in neighbors:
                agent.state = "INFECTED"