import os from collections import defaultdict from typing import List, cast, Set import plotly.graph_objects as go from geniusweb.bidspace.pareto.GenericPareto import GenericPareto from geniusweb.bidspace.pareto.ParetoLinearAdditive import ParetoLinearAdditive from geniusweb.issuevalue.Bid import Bid from geniusweb.party.DefaultParty import DefaultParty from geniusweb.profile.utilityspace.LinearAdditive import LinearAdditive from geniusweb.profileconnection.ProfileConnectionFactory import ProfileConnectionFactory from geniusweb.profileconnection.ProfileInterface import ProfileInterface from uri.uri import URI def compute_pareto_frontier(settings_profiles: List[str]): profiles = dict() for profile_url in [f"file:{x}" for x in settings_profiles]: profileInt: ProfileInterface = ProfileConnectionFactory.create( URI(profile_url), DefaultParty.getReporter) profile: LinearAdditive = cast(LinearAdditive, profileInt.getProfile()) profiles[profile_url] = profile pareto: ParetoLinearAdditive = ParetoLinearAdditive(list(profiles.values())) pareto_points: Set[Bid] = pareto.getPoints() pareto_frontier = dict() for pareto_bid in pareto_points: pareto_frontier[pareto_bid] = dict() for profile_name, profile in profiles.items(): pareto_frontier[pareto_bid][profile_name] = float(profile.getUtility(pareto_bid)) return pareto_frontier def plot_pareto(results_trace: dict, pareto_frontier: dict, plot_file: str): utilities = defaultdict(lambda: {"x": [], "y": [], "bids": []}) profiles = results_trace["connections"] x_axis = profiles[0] x_label = "_".join(x_axis.split("_")[-2:]) y_axis = profiles[1] y_label = "_".join(y_axis.split("_")[-2:]) accept = {"x": [], "y": [], "bids": []} for action in results_trace["actions"]: if "Offer" in action: offer = action["Offer"] actor = offer["actor"] for agent, util in offer["utilities"].items(): if agent == x_axis: utilities[actor]["x"].append(util) else: utilities[actor]["y"].append(util) utilities[actor]["bids"].append(offer["bid"]["issuevalues"]) elif "Accept" in action: offer = action["Accept"] actor = offer["actor"] for agent, util in offer["utilities"].items(): if agent == x_axis: accept["x"].append(util) else: accept["y"].append(util) accept["bids"].append(offer["bid"]["issuevalues"]) fig = go.Figure() fig.add_trace( go.Scatter( mode="markers", x=accept["x"], y=accept["y"], name="agreement", marker={"color": "green", "size": 15}, hoverinfo="skip", ) ) color = {0: "red", 1: "blue"} for i, (agent, utility) in enumerate(utilities.items()): name = "_".join(agent.split("_")[-2:]) text = [] for bid, util_x, util_y in zip(utility["bids"], utility["x"], utility["y"]): text.append( "
".join( [x_label + f": {util_x:.3f}
"] + [y_label + f": {util_y:.3f}
"] + [f"{i}: {v}" for i, v in bid.items()] ) ) fig.add_trace( go.Scatter( x=utility["x"], y=utility["y"], marker={"color": color[i]}, name=f"{name}", hovertext = text, hoverinfo = "text" ) ) x_axis_profile = None y_axis_profile = None party_profiles = results_trace["partyprofiles"] for party_prof in party_profiles: if x_axis in party_prof: x_axis_profile = party_profiles[x_axis]["profile"] elif y_axis in party_prof: y_axis_profile = party_profiles[y_axis]["profile"] pareto_bids = {"x": [], "y": [], "bids": []} for bid, utilities in pareto_frontier.items(): for profile, util in utilities.items(): if profile == x_axis_profile: pareto_bids["x"].append(util) elif profile == y_axis_profile: pareto_bids["y"].append(util) pareto_bids["bids"].append(bid) fig.add_trace( go.Scatter( x=pareto_bids["x"], y=pareto_bids["y"], mode='markers', name='pareto frontier point' ) ) fig.update_layout( width=800, height=800, legend={ "yanchor": "bottom", "y": 1, "xanchor": "left", "x": 0, }, ) fig.update_layout(title_text='Negotiation traces', title_x=0.5) fig.update_xaxes(title_text="Utility of " + x_label, ticks="outside") fig.update_yaxes(title_text="Utility of " + y_label, ticks="outside") fig.write_html(f"{os.path.splitext(plot_file)[0]}.html")