Ejemplo n.º 1
0
 def register_product_cfps(self,
                           p: int,
                           t: int,
                           profile: ConsumptionProfile,
                           sp=dict()):
     current_schedule = profile.schedule_at(t)
     product = self.products[p]
     awi: SCMLAWI = self.awi
     if current_schedule <= 0:
         awi.bb_remove(
             section="cfps",
             query={
                 "publisher": self.id,
                 "time": t,
                 "product_index": p
             },
         )
         return
     max_price = (ScheduleDrivenConsumer.RELATIVE_MAX_PRICE *
                  product.catalog_price if product.catalog_price is not None
                  else ScheduleDrivenConsumer.MAX_UNIT_PRICE)
     if sp.get(p) != None and sp[p] > product.catalog_price:
         max_price = ScheduleDrivenConsumer.RELATIVE_MAX_PRICE * sp[p]
     cfps = awi.bb_query(section="cfps",
                         query={
                             "publisher": self.id,
                             "time": t,
                             "product": p
                         })
     if cfps is not None and len(cfps) > 0:
         for _, cfp in cfps.items():
             if cfp.max_quantity != current_schedule:
                 cfp = CFP(
                     is_buy=True,
                     publisher=self.id,
                     product=p,
                     time=t,
                     unit_price=(0, max_price),
                     quantity=(1, current_schedule),
                 )
                 awi.bb_remove(
                     section="cfps",
                     query={
                         "publisher": self.id,
                         "time": t,
                         "product": p
                     },
                 )
                 awi.register_cfp(cfp)
                 break
     else:
         cfp = CFP(
             is_buy=True,
             publisher=self.id,
             product=p,
             time=t,
             unit_price=(0, max_price),
             quantity=(1, current_schedule),
         )
         awi.register_cfp(cfp)
Ejemplo n.º 2
0
 def register_cfp(self, cfp: CFP) -> None:
     """Registers a CFP"""
     self._world.n_new_cfps += 1
     cfp.money_resolution = self._world.money_resolution
     cfp.publisher = (
         self.agent.id
     )  # force the publisher to be the agent using this AWI.
     self.logdebug(f"{self.agent.name} registered CFP {str(cfp)}")
     self.bb_record(section="cfps", key=cfp.id, value=cfp)
Ejemplo n.º 3
0
    def step(self):
        self.maxdebt = max([0, 30 - 30 * self.awi.current_step/self.awi.n_steps])

        for key, item in self.cfp_records.items():
            if item.lastSigned < self.awi.current_step - 4 and item.retracted < self.awi.current_step - 4:
                if len(item.HistoryMin) > 1:
                    item.HistoryMin.remove(min(item.HistoryMin))
                    #item.HistoryMin.pop()
                if len(item.HistoryMax) > 1:
                    #item.HistoryMax.pop()
                    item.HistoryMax.remove(max(item.HistoryMax))
                self.recalculate_prices(key)
                item.retracted = self.awi.current_step



        #print("step: ", self.awi.current_step)
        for key, item in self.cfp_records.items():

            if item.transformable:
                stock = self.cfp_records[item.source_of].stock
                if key in self.awi.state.storage:
                    for i in range(min([10,self.awi.state.storage[key]])):
                        self.awi.schedule_production(self.lastLine, self.awi.current_step+1)
                        self.lastLine = (self.lastLine + 1) % 10
            else:
                stock = item.stock
            if item.id not in self.producing.keys() and stock <= item.minstock \
                    and (item.Asked < self.awi.current_step - 2) and self.awi.n_steps - 6 > self.awi.current_step:
                queries = 1
                if item.id in self.consuming.keys():
                    queries = 3

                for i in range(queries):
                    cfp = CFP(is_buy=True, publisher=self.id, product=item.id
                          , time= (self.awi.current_step + 4 +i, min([self.awi.current_step + 6+i, self.awi.n_steps-1]))
                          , unit_price=self.generate_price_ranges(0,
                                    self.products[item.id].catalog_price + self.products[item.id].catalog_price
                                    * self.cfp_records[item.id].BuyThreshold)
                          , quantity=3)

                    self.awi.register_cfp(cfp)
                item.Asked = self.awi.current_step

            if item.stock > 0 and item.id not in self.consuming.keys():
                for unit in range(item.stock):
                    unit_price = self.generate_price_ranges(item.MaxPrice - item.MaxPrice * item.BuyThreshold,
                                  item.MaxPrice + item.MaxPrice * item.SellThreshold)

                    cfp = CFP(is_buy=False, publisher=self.id, product=item.id
                              , time=max([2 + (2 * item.id), self.awi.current_step + 6]),
                              unit_price=unit_price, quantity=1)
                    self.awi.register_cfp(cfp)
                    item.Asked = self.awi.current_step
Ejemplo n.º 4
0
 def step(self):
     for product in self.awi.products:
         cfp = CFP(
             is_buy=False,
             publisher=self.id,
             product=product.id,
             time=(self.awi.current_step + 2, self.awi.current_step + 6),
             unit_price=0.0000893,
             quantity=(5, 10),
         )
         self.awi.register_cfp(cfp)
Ejemplo n.º 5
0
 def post_cfps_2(self):
     for step in range(10):
         my_cfp = CFP(is_buy=True,
                      product=self.raw_material_type,
                      publisher=self.id,
                      quantity=(1, 1 + random.randint(0, 10)),
                      time=random.randint(0, 15) + self.current_step,
                      unit_price=(0.5, self.get_target_price()),
                      money_resolution=0.1,
                      id="NORMAL : " + str(time),
                      penalty=10000)
         self.awi.register_cfp(my_cfp)
Ejemplo n.º 6
0
 def generateDecoyCFPs(self):
     for i in range(1, 100):
         decoyCFP = CFP(is_buy=True,
                        product=int(random.uniform(1, len(self.products))),
                        publisher=self.id,
                        signing_delay=int(random.uniform(1, 9)),
                        quantity=1,
                        time=int(random.uniform(1, 5)),
                        unit_price=(0, 100),
                        money_resolution=0.1,
                        id="DECOY : " + str(i))
         self.decoyCFPs.append(decoyCFP)
         self.awi.register_cfp(decoyCFP)
Ejemplo n.º 7
0
 def post_cfps(self):
     alpha = 16
     for step in range(15):
         my_cfp = CFP(is_buy=True,
                      product=self.raw_material_type,
                      publisher=self.id,
                      quantity=(1, step + alpha),
                      time=min(step + self.current_step,
                               self.awi.n_steps - 2),
                      unit_price=(0.5, self.get_target_price()),
                      money_resolution=0.1,
                      id="NORMAL : " + str(time),
                      penalty=10000)
         self.awi.register_cfp(my_cfp)
Ejemplo n.º 8
0
 def _execute_schedule(self, schedule: ScheduleInfo,
                       contract: Contract) -> None:  ###contact
     if self.simulator is None:
         raise ValueError("No factory simulator is defined")
     awi: SCMLAWI = self.awi
     total = contract.agreement["unit_price"] * contract.agreement[
         "quantity"]
     product = contract.annotation["cfp"].product
     if contract.annotation["buyer"] == self.id:
         self.simulator.buy(
             product=product,
             quantity=contract.agreement["quantity"],
             price=total,
             t=contract.agreement["time"],
         )
         if total <= 0 or self.max_insurance_premium <= 0.0 or contract is None:
             return
         relative_premium = awi.evaluate_insurance(contract=contract)
         if relative_premium is None:
             return
         premium = relative_premium * total
         if relative_premium <= self.max_insurance_premium:
             self.awi.logdebug(
                 f"{self.name} buys insurance @ {premium:0.02} ({relative_premium:0.02%}) for {str(contract)}"
             )
             awi.buy_insurance(contract=contract)
             self.simulator.pay(premium, self.awi.current_step)
         return
     # I am a seller
     self.simulator.sell(
         product=product,
         quantity=contract.agreement["quantity"],
         price=total,
         t=contract.agreement["time"],
     )
     for job in schedule.jobs:
         if job.action == "run":
             awi.schedule_job(job, contract=contract)
         elif job.action == "stop":
             awi.stop_production(
                 line=job.line,
                 step=job.time,
                 contract=contract,
                 override=job.override,
             )
         else:
             awi.schedule_job(job, contract=contract)
         self.simulator.schedule(job=job, override=False)
     for need in schedule.needs:
         if need.quantity_to_buy <= 0:
             continue
         product_id = need.product
         # self.simulator.reserve(product=product_id, quantity=need.quantity_to_buy, t=need.step)
         if self.use_consumer:
             self.consumer.profiles[product_id].schedule[
                 need.step] += need.quantity_to_buy
             self.consumer.register_product_cfps(
                 p=product_id,
                 t=need.step,
                 profile=self.consumer.profiles[product_id],
                 sp=self.sold,  ###
             )
             continue
         #             logger.debug('seller')
         product = self.products[product_id]
         if product.catalog_price is None:
             if self.sold.get(product_id) == None:
                 price_range = (0.0, 100.0)
             else:
                 price_range = (0.5, 1.5 * self.sold(product_id))
         else:
             #                 logger.debug(product)
             #                 logger.debug(product.catalog_price)
             if self.sold.get(product_id) != None:
                 product_price = max(self.sold(product_id),
                                     product.catalog_price)
             price_range = (0.5, 1.5 * product_price)
         # @todo check this. This error is raised sometimes
         if need.step < awi.current_step:
             continue
             # raise ValueError(f'need {need} at {need.step} while running at step {awi.current_step}')
         time = (need.step if self.max_storage is not None else
                 (awi.current_step, need.step))
         cfp = CFP(
             is_buy=True,
             publisher=self.id,
             product=product_id,
             time=time,
             unit_price=price_range,
             quantity=(1, int(1.1 * need.quantity_to_buy)),
         )
         awi.register_cfp(cfp)
Ejemplo n.º 9
0
    def step(self):
        """Called at every production step by the world"""

        # Book keeping
        for p in range(0, self.num_intermediate_products + 2):
            self.storage_history[p].append(self.awi.state.storage[p])
        self.wallet_history.append(self.awi.state.wallet)

        # ---------------- MPNVM STUFF --------
        # Plan how many inputs to go for. We ask the brain for the number of inputs. If the brain could not find data, we go for a fixed number.
        plan_for_inputs = self.agent_brain.get_plan_for_inputs(self.current_step + 1, self.verbose) if self.agent_brain.there_is_data else [self.fixed_number_of_inputs]

        # Post a call for proposal to buy inputs using the plan computed before. We limit the call for buy stuff up to 15 steps before the end of game.
        # @todo There could be a further optimization problem here, as in, how many CFPs to post? At the moment we just post one.
        if self.current_step <= self.limit_post_cfps and self.storage_history[self.output_index][-1] <= self.limit_sign_storage:
            self.awi.register_cfp(CFP(is_buy=True,
                                      publisher=self.name,
                                      product=self.input_index,
                                      # @todo The time of negotiation matters a lot for longer chains. For chain of size 4, +5, +15 worked.
                                      time=(self.current_step + self.cfp_time_lower_bound, self.current_step + self.cfp_time_upper_bound),
                                      unit_price=(0.0, self.expected_catalog_prices[self.input_index]),
                                      quantity=(max(1, plan_for_inputs[0] - self.cfp_qtty_range_width), plan_for_inputs[0] + self.cfp_qtty_range_width)))

        # Send all inputs to production to get outputs. We always turn every input into output. We don't hold on to inputs.
        schedule_for_production = 0
        for l in range(0, 10):
            if self.storage_history[self.input_index][-1] > 0 and \
                    schedule_for_production <= self.storage_history[self.input_index][-1] and \
                    self.awi.current_step < self.awi.n_steps - 1:
                self.awi.schedule_production(l, self.awi.current_step)
                self.simulator.schedule(Job(profile=l, time=self.awi.current_step, line=-1, action='run', contract=None, override=False))
                schedule_for_production += 1

        # Read all the CFPs and engage in negotiations with agents that want to buy our output.
        the_cfps = self.awi.bb_query('cfps', None)
        if the_cfps:
            for i, c in the_cfps.items():
                c: CFP
                # Negotiate about outputs. It is highly unlikely the agent can have any output product ready before parameter self.start_sell_negotiation_bound
                if c.publisher != self.id and c.is_buy and c.product == self.output_index and c.min_time >= self.start_sell_negotiation_bound:
                    self.request_negotiation(cfp=c, negotiator=AspirationNegotiator(ufun=self.output_negotiator_ufun,
                                                                                    aspiration_type=self.agent_aspiration_type))
                # @todo Negotiate about inputs. This is currently not active, as in the case of inputs our agent is proactive. Should we activate it?
                # elif not c.is_buy and c.product == self.input_index:
                #    self.request_negotiation(cfp=c, negotiator=AspirationNegotiator(name="my-goog-buyer", ufun=self.input_negotiator_ufun))

        # ---------------- MIDDLE MAN STUFF --------
        # @todo Add parameters for the ranges over which we post CFPs for the middle man.
        if self.middle_man_active:
            # First, post CFP to buy and sell stuff, up to time given by parameter self.limit_post_cfps.
            if self.current_step <= self.limit_post_cfps:
                for p in self.middle_man_products:
                    # Post a CFP to buy stuff to be later resold
                    self.awi.register_cfp(CFP(is_buy=True,
                                              publisher=self.name,
                                              product=p,
                                              time=(self.current_step + self.cfp_time_lower_bound, self.current_step + self.cfp_time_upper_bound),
                                              unit_price=(0.0, self.expected_catalog_prices[p]),
                                              quantity=(1, 5)))
                    # Post a CFP to sell stuff
                    self.awi.register_cfp(CFP(is_buy=False,
                                              publisher=self.name,
                                              product=p,
                                              time=(self.current_step + self.cfp_time_lower_bound, self.current_step + self.cfp_time_upper_bound),
                                              unit_price=(3.5, 25.5),
                                              quantity=(1, 5)))
            if the_cfps:
                for i, c, in the_cfps.items():
                    c: CFP
                    # Make sure we don't respond to ourselves.
                    if c.publisher != self.id:
                        # Respond to CFPs when we try to buy stuff for the middle man
                        if c.product in self.middle_man_products and not c.is_buy:
                            # print(f'Responding to a cfp from {c.publisher} to buy {c.product}. Here it is: CFP = {c}')
                            self.request_negotiation(cfp=c, negotiator=AspirationNegotiator(ufun=self.input_negotiator_ufun, aspiration_type=self.agent_aspiration_type))
                        # Respond to CFPs when we try to sell stuff for the middle man
                        if c.product in self.middle_man_products and c.is_buy:
                            # print(f'Responding to a cfp to sell CFP for product {c.product} by {c.publisher},  CFP = {c}')
                            self.request_negotiation(cfp=c, negotiator=AspirationNegotiator(ufun=self.output_negotiator_ufun,
                                                                                            aspiration_type=self.agent_aspiration_type,
                                                                                            max_aspiration=0.95))

        # DEBUG INFO
        if self.verbose:
            # Print some debug info for development purposes.
            self.print_debug_info(plan_for_inputs, self.storage_history[self.input_index][-1], self.storage_history[self.output_index][-1])

        # Save results of the hyper-parameter optimization
        if self.current_step + 1 == self.awi.n_steps:
            if not os.path.exists('my_results'):
                os.makedirs('my_results')
            results_file_name = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
            with open(f'my_results/{results_file_name}.dat', 'w') as file:
                file.write(f'{self.marginal_calculation_on_sign_contract},'
                           f'{self.limit_sign_storage},'
                           f'{self.limit_number_buys_contracts_at_t},'
                           f'{self.limit_number_sales_contracts_at_t},'
                           f'{self.cfp_qtty_range_width},'
                           f'{self.input_index},{self.output_index},'
                           f'{self.num_intermediate_products},'
                           f'{self.wallet_history[-1]}')