def sign_all_contracts(self, contracts: List[Contract]) -> List[Optional[str]]: # sort contracts by time and then put system contracts first within each time-step signatures = [None] * len(contracts) contracts = sorted( zip(contracts, range(len(contracts))), key=lambda x: ( x[0].agreement["unit_price"], x[0].agreement["time"], 0 if is_system_agent(x[0].annotation["seller"]) or is_system_agent(x[0].annotation["buyer"]) else 1, x[0].agreement["unit_price"], ), ) sold, bought = 0, 0 s = self.awi.current_step catalog_buy = self.awi.catalog_prices[self.awi.my_input_product] catalog_sell = self.awi.catalog_prices[self.awi.my_output_product] for contract, indx in contracts: is_seller = contract.annotation["seller"] == self.id q, u, t = ( contract.agreement["quantity"], contract.agreement["unit_price"], contract.agreement["time"], ) # check that the contract is executable in principle if t < s and len(contract.issues) == 3: continue if (is_seller and u < 0.75 * catalog_sell) or ( not is_seller and u > 1.25 * catalog_buy): continue if is_seller: trange = (s, t) secured, needed = (self.outputs_secured, self.outputs_needed) taken = sold else: trange = (t + 1, self.awi.n_steps - 1) secured, needed = (self.inputs_secured, self.inputs_needed) taken = bought # check that I can produce the required quantities even in principle steps, lines = self.awi.available_for_production(q, trange, ANY_LINE, override=False, method="all") if len(steps) - taken < q: continue if (secured[trange[0]:trange[1] + 1].sum() + q + taken <= needed[trange[0]:trange[1] + 1].sum()): signatures[indx] = self.id if is_seller: sold += q else: bought += q return signatures
def sign_all_contracts(self, contracts: List[Contract]) -> List[Optional[str]]: # sort contracts by time and then put system contracts first within each time-step signatures = [None] * len(contracts) max_price = max([x.agreement["unit_price"] for x in contracts]) contracts = sorted( zip(contracts, range(len(contracts))), key=lambda x: ( x[0].agreement["unit_price"] if x[0].annotation["buyer"] == self.id else max_price - x[0].agreement["unit_price"], x[0].agreement["time"], 0 if is_system_agent(x[0].annotation["seller"]) or is_system_agent(x[0].annotation["buyer"]) else 1, ), ) taken = 0 s = self.awi.current_step for contract, indx in contracts: q, u, t = ( contract.agreement["quantity"], contract.agreement["unit_price"], contract.agreement["time"], ) # check that the contract is executable in principle if t <= s and len(contract.issues) == 3: continue if contract.annotation["seller"] == self.id: trange = (s, t) secured, needed = (self.outputs_secured, self.outputs_needed) else: trange = (t + 1, self.awi.n_steps - 1) secured, needed = (self.inputs_secured, self.inputs_needed) # check that I can produce the required quantities even in principle steps, lines = self.awi.available_for_production( q, trange, ANY_LINE, override=False, method="all" ) if len(steps) - taken < q: continue if ( secured[trange[0] : trange[1] + 1].sum() + q + taken <= needed[trange[0] : trange[1] + 1].sum() ): signatures[indx] = self.id taken += self.predict_quantity(contract) return signatures
def from_contracts(self, contracts: Iterable[Contract], ignore_exogenous=True) -> float: """ Calculates the utility function given a list of contracts Args: contracts: A list/tuple of contracts ignore_exogenous: If given, any contracts with a system agent will be ignored. Remarks: - This method ignores any unsigned contracts passed to it. - We do not consider time at all so it is implicitly assumed that all contracts have the same delivery time value. - The reason for having the `ignore_exogenous` parameter is to avoid double counting exogenous contracts if their information is passed during construction of the ufun and they also exist in the list of `contracts` passed here. """ offers, outputs = [], [] output_product = self.output_product for c in contracts: if c.signed_at < 0: continue if ignore_exogenous and any( is_system_agent(_) for _ in c.partners): continue product = c.annotation["product"] is_output = product == output_product outputs.append(is_output) offers.append(self.outcome_as_tuple(c.agreement)) return self.from_offers(offers, outputs)
def sign_all_contracts(self, contracts: List[Contract]) -> List[Optional[str]]: signatures = [None] * len(contracts) contracts = sorted( zip(contracts, range(len(contracts))), key=lambda x: ( x[0].agreement["unit_price"], x[0].agreement["time"], 0 if is_system_agent(x[0].annotation["seller"]) or is_system_agent(x[0].annotation["buyer"]) else 1, x[0].agreement["unit_price"], ), ) sold, bought = 0, 0 # 今回のステップで販売(購入)した製品の数 s = self.awi.current_step for contract, indx in contracts: is_seller = contract.annotation["seller"] == self.id q, u, t = ( contract.agreement["quantity"], contract.agreement["unit_price"], contract.agreement["time"], ) # check that the contract is executable in principle if t < s and len(contract.issues) == 3: continue # check unit price不利益すぎる不当な契約はしない if is_seller and self.output_price[t] * (1 / 10) > u: continue elif self.input_cost[t] * 10 < u: continue agent_confidence = 1 if is_seller: agent_confidence = self.agent_confidence[ contract.annotation["buyer"]] else: agent_confidence = self.agent_confidence[ contract.annotation["seller"]] # 信頼度が低い場合,署名しない if agent_confidence < 0.4: continue if is_seller: trange = (s, t) secured, needed = (self.outputs_secured, self.outputs_needed) taken = sold else: trange = (t + 1, self.awi.n_steps - 1) secured, needed = (self.inputs_secured, self.inputs_needed) taken = bought # check that I can produce the required quantities even in principle steps, lines = self.awi.available_for_production(q, trange, ANY_LINE, override=False, method="all") # I cant produce product, so i dont sign this contract if len(steps) - taken < q: continue # 今回のステップで契約した量がニーズを超えていないか if (secured[trange[0]:trange[1] + 1].sum() + q + taken <= needed[trange[0]:trange[1] + 1].sum()): signatures[indx] = self.id if is_seller: sold += q else: bought += q return signatures
def sign_all_contracts(self, contracts: List[Contract]) -> List[Optional[str]]: super().sign_all_contracts(contracts) signatures = [None] * len(contracts) contracts = sorted( zip(contracts, range(len(contracts))), key=lambda x: ( x[0].agreement["unit_price"], x[0].agreement["time"], 0 if is_system_agent(x[0].annotation["seller"]) or is_system_agent(x[0].annotation["buyer"]) else 1, x[0].agreement["unit_price"], # x[0].agreement["time"], ), ) sold, bought = 0, 0 s = self.awi.current_step for contract, indx in contracts: is_seller = contract.annotation["seller"] == self.id q, u, t = ( contract.agreement["quantity"], contract.agreement["unit_price"], contract.agreement["time"], ) if t < s and len(contract.issues) == 3: continue if self.awi.my_suppliers == ["SELLER"]: if q > self.awi.n_lines: continue if is_seller: if t > self.awi.n_steps - 2: continue zaiko = 0 for zzaiko in self.outputs_needed: zaiko += zzaiko if zaiko < 1: if t < s + 3: continue sellprice = max( (self.awi.catalog_prices[self.awi.my_output_product] - self.awi.catalog_prices[self.awi.my_input_product] - self.awi.profile.costs[0, self.awi.my_input_product]) // 2 - 1, 0, ) if (u < self.awi.catalog_prices[self.awi.my_output_product] - sellprice): continue cansell = zaiko + (self.awi.n_lines - self.inputs_needed[t]) if q <= cansell: self.outputs_needed[t] -= q self.inputs_needed[t] += q else: continue else: wantbuy = 0 needtime = -1 for step in range(self.awi.n_steps): wantbuy += self.inputs_needed[step] if self.inputs_needed[step] > 0 and needtime == -1: needtime = step if wantbuy > 0: self.outputs_needed[t] += q self.inputs_needed[t] -= q else: continue elif self.awi.my_consumers == ["BUYER"]: if q > self.awi.n_lines: continue if is_seller: zaiko = 0 for zzaiko in self.outputs_needed: zaiko += zzaiko if zaiko < 1: if t < s + 2: continue cansell = zaiko if q <= cansell: self.outputs_needed[t] -= q self.inputs_needed[t] += q else: continue else: if t > s + 5: continue wantbuy = self.awi.n_lines - self.outputs_needed[t] if wantbuy > 0: self.outputs_needed[t] += q self.inputs_needed[t] -= q else: continue else: if q > self.awi.n_lines: continue if is_seller: if t > self.awi.n_steps - 2: continue zaiko = 0 for zzaiko in self.outputs_needed: zaiko += zzaiko if zaiko < q: if t < s + 2: continue sellprice = max( (self.awi.catalog_prices[self.awi.my_output_product] - self.awi.catalog_prices[self.awi.my_input_product] - self.awi.profile.costs[0, self.awi.my_input_product]) // 2 - 1, 0, ) if (u < self.awi.catalog_prices[self.awi.my_output_product] - sellprice): continue cansell = zaiko + (self.awi.n_lines - self.inputs_needed[t]) if q <= cansell: self.outputs_needed[t] -= q self.inputs_needed[t] += q else: continue else: if t < s: continue havetobuy = 0 needtime = s - 1 for step in range(self.awi.n_steps): havetobuy += self.inputs_needed[step] if self.inputs_needed[step] > 0 and needtime <= (s - 1): needtime = step if t >= needtime: continue if needtime == s + 1: if u < self.awi.catalog_prices[ self.awi.my_input_product]: continue elif needtime < s + 3: buyprice2 = max( (self.awi.catalog_prices[ self.awi.my_output_product] - self.awi. catalog_prices[self.awi.my_input_product]) // 2 - 1, 0, ) if (u < self.awi.catalog_prices[ self.awi.my_input_product] + buyprice2): continue else: buyprice = max( (self.awi.catalog_prices[ self.awi.my_output_product] - self.awi.catalog_prices[self.awi.my_input_product] - self.awi.profile.costs[ 0, self.awi.my_input_product]) // 2 - 1, 0, ) if (u < self.awi.catalog_prices[ self.awi.my_input_product] + buyprice): continue if havetobuy > 0: self.outputs_needed[t] += q self.inputs_needed[t] -= q else: continue signatures[indx] = self.id if is_seller: sold += q else: bought += q return signatures
def sign_all_contracts(self, contracts: List[Contract]) -> List[Optional[str]]: signatures = [None] * len(contracts) # sort contracts by goodness of price, time and then put system contracts first within each time-step contracts = sorted( zip(contracts, range(len(contracts))), key=lambda x: ( x[0].agreement["time"], (x[0].agreement["unit_price"] - self.output_price[x[ 0].agreement["time"]]) if x[0].annotation["seller"] == self.id else (self.input_cost[ x[0].agreement["time"]] - x[0].agreement["unit_price"]), 0 if is_system_agent(x[0].annotation["seller"]) or is_system_agent(x[0].annotation["buyer"]) else 1, ), ) sold, bought = 0, 0 s = self.awi.current_step for contract, indx in contracts: is_seller = contract.annotation["seller"] == self.id q, u, t = ( contract.agreement["quantity"], contract.agreement["unit_price"], contract.agreement["time"], ) # check that the contract is executable in principle. The second # condition checkes that the contract is negotiated and not exogenous if t < s and len(contract.issues) == 3: continue # catalog_buy = self.input_cost[t] # catalog_sell = self.output_price[t] # # check that the gontract has a good price # if (is_seller and u < 0.5 * catalog_sell) or ( # not is_seller and u > 1.5 * catalog_buy # ): # continue if is_seller: trange = (s, t - 1) secured, needed = (self.outputs_secured, self.outputs_needed) taken = sold else: trange = (t + 1, self.awi.n_steps - 1) secured, needed = (self.inputs_secured, self.inputs_needed) taken = bought # check that I can produce the required quantities even in principle steps, _ = self.awi.available_for_production(q, trange, ANY_LINE, override=False, method="all") if len(steps) - taken < q: continue if (secured[trange[0]:trange[1] + 1].sum() + q + taken <= needed[trange[0]:trange[1] + 1].sum()): signatures[indx] = self.id if is_seller: sold += q else: bought += q return signatures
def sign_all_contracts(self, contracts: List[Contract]) -> List[Optional[str]]: # sort contracts by time and then put system contracts first within each time-step signatures = [None] * len(contracts) contracts = sorted( zip(contracts, range(len(contracts))), key=lambda x: ( x[0].agreement["unit_price"], x[0].agreement["time"], 0 if is_system_agent(x[0].annotation["seller"]) or is_system_agent(x[0].annotation["buyer"]) else 1, x[0].agreement["unit_price"], ), ) sold, bought = 0, 0 # count the number of sold/bought products during the loop s = self.awi.current_step for contract, indx in contracts: is_seller = contract.annotation["seller"] == self.id q, u, t = ( contract.agreement["quantity"], contract.agreement["unit_price"], contract.agreement["time"], ) if t < s and len(contract.issues) == 3: continue if is_seller: # Sign the first contract when the final process is assigned if s == 0 and self.awi.my_output_product == (self.awi.n_products - 1): signatures[indx] = self.id # I don't sign contracts for less than the selling price if u < self.output_price[t]: continue est = 0 # Estimated number of products # Calculate the maximum production possible before delivery date for i in range(1, t - s + 1): est += min(self.inputs_secured[t - i], i * self.awi.n_lines) est = min(est, (t - s) * self.awi.n_lines) available = ( est + self.internal_state["_output_inventory"] - (self.outputs_secured[s:]).sum() ) # Add stock and sub contracted # Only sign contracts that ensure production is on time. if available - sold > q: signatures[indx] = self.id sold += q else: # I don't make contracts to buy at the end of the game. if t > self.awi.n_steps * 3 // 4: continue # I don't sign contracts over the buying price if u > self.input_cost[t]: continue needed = self.inputs_needed[ self.awi.n_steps - 1 ] # Maximum number of products that can be produced if needed - bought > q: signatures[indx] = self.id bought += q return signatures
def sign_all_contracts(self, contracts: List[Contract]) -> List[Optional[str]]: # sort contracts by time and then put system contracts first within each time-step # print("sign_all_contracts") signatures = [None] * len(contracts) contracts = sorted( zip(contracts, range(len(contracts))), key=lambda x: ( x[0].agreement["unit_price"], x[0].agreement["time"], 0 if is_system_agent(x[0].annotation["seller"]) or is_system_agent(x[0].annotation["buyer"]) else 1, x[0].agreement["quantity"] * -1, # 数の多い契約を優先してみる ), ) # for x in contracts: # print(x[1], x[0].agreement["unit_price"], x[0].agreement["time"], is_system_agent(x[0].annotation["seller"]) or is_system_agent(x[0].annotation["buyer"])) sold, bought = 0, 0 s = self.awi.current_step for contract, indx in contracts: is_seller = contract.annotation["seller"] == self.id q, u, t = ( contract.agreement["quantity"], contract.agreement["unit_price"], contract.agreement["time"], ) # check that the contract is executable in principle if t < s and len(contract.issues) == 3: continue if is_seller: trange = (s, t - 1) # 元はt secured, needed = (self.outputs_secured, self.outputs_needed) taken = sold else: trange = (t, self.awi.n_steps - 1) # 元はt+1 secured, needed = (self.inputs_secured, self.inputs_needed) taken = bought # check that I can produce the required quantities even in principle steps, lines = self.awi.available_for_production(q, trange, ANY_LINE, override=False, method="all") # print(q) # print(trange) # print(steps) # print(lines) # print(len(steps)) # print(taken, is_seller) # print() if len(steps) - taken < q: continue if (secured[trange[0]:trange[1] + 1].sum() + q + taken <= needed[trange[0]:trange[1] + 1].sum()): signatures[indx] = self.id if is_seller: sold += q else: bought += q # print("sign_all_contracts:end") return signatures
def sign_all_contracts(self, contracts: List[Contract]) -> List[Optional[str]]: # sort contracts by time and then put system contracts first within each time-step signatures = [None] * len(contracts) contracts = sorted( zip(contracts, range(len(contracts))), key=lambda x: ( x[0].agreement["unit_price"], x[0].agreement["time"], 0 if is_system_agent(x[0].annotation["seller"]) or is_system_agent(x[0].annotation["buyer"]) else 1, x[0].agreement["unit_price"], ), ) sold, bought = 0, 0 s = self.awi.current_step for contract, indx in contracts: is_seller = contract.annotation["seller"] == self.id q, u, t = ( contract.agreement["quantity"], contract.agreement["unit_price"], contract.agreement["time"], ) # check that the contract is executable in principle if t <= s and len(contract.issues) == 3: continue if contract.annotation["seller"] == self.id: trange = (s, t) secured, needed = (self.outputs_secured, self.outputs_needed) taken = sold else: trange = (t + 1, self.awi.n_steps - 1) secured, needed = (self.inputs_secured, self.inputs_needed) taken = bought if is_seller: if t < self.awi.n_steps - int(self.awi.n_steps / 10): factor = 1.5 else: factor = 1 else: factor = 1 if (factor * needed[t] < secured[t] + q + taken) and ( not self.is_good_price(u, t, is_seller) ): continue # check that I can produce the required quantities even in principle steps, lines = self.awi.available_for_production( q, trange, ANY_LINE, override=False, method="all" ) if len(steps) - sold < q: continue if ( secured[trange[0] : trange[1] + 1].sum() + q + taken <= needed[trange[0] : trange[1] + 1].sum() ): signatures[indx] = self.id if is_seller: sold += self.predict_quantity(contract) else: bought += self.predict_quantity(contract) return signatures