示例#1
0
    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
示例#2
0
    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
示例#3
0
    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)
示例#4
0
    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
示例#5
0
    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
示例#6
0
    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
示例#7
0
    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
示例#8
0
    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