SCML: Negotiate Your Way to Fornute

SCML has an online competition which allows you to compete against other participants before the official competition. Last year, this proved invaluable for improving agents and removing the worst of their bugs and unexpected behaviors by the time of the official competition.

Everything should be made as simple as possible, but no simpler, Albert Einstein.

The SCM world: See competition website
The SCM world: See competition website
profit = revenue - supply cost - production cost - shortfall penalty - disposal
cost
pip install scml
pip install scml-vis
SCML-OneShot example visualization charts using scml-vis
SCML-OneShot example visualization charts using scml-vis
class GreedyOneShotAgent(OneShotAgent):
"""A greedy agent based on OneShotAgent"""

def init(self):
self.secured = 0

def step(self):
self.secured = 0

def on_negotiation_success(self, contract, mechanism):
self.secured += contract.agreement["quantity"]

def propose(self, negotiator_id: str, state) -> "Outcome":
return self.best_offer(negotiator_id)

def respond(self, negotiator_id, state, offer):
my_needs = self._needed(negotiator_id)
if my_needs <= 0:
return ResponseType.END_NEGOTIATION
return (
ResponseType.ACCEPT_OFFER
if offer[QUANTITY] <= my_needs
else ResponseType.REJECT_OFFER
)

def best_offer(self, negotiator_id):
my_needs = self._needed(negotiator_id)
if my_needs <= 0:
return None
ami = self.get_ami(negotiator_id)
if not ami:
return None
quantity_issue = ami.issues[QUANTITY]
unit_price_issue = ami.issues[UNIT_PRICE]
offer = [-1] * 3
offer[QUANTITY] = max(
min(my_needs, quantity_issue.max_value),
quantity_issue.min_value
)
offer[TIME] = self.awi.current_step
if self._is_selling(ami):
offer[UNIT_PRICE] = unit_price_issue.max_value
else:
offer[UNIT_PRICE] = unit_price_issue.min_value
return tuple(offer)

def _needed(self, negotiator_id=None):
return self.awi.current_exogenous_input_quantity + \
self.awi.current_exogenous_output_quantity - \
self.secured

def _is_selling(self, ami):
return ami.annotation["product"] == self.awi.my_output_product

world, ascores, tscores = try_agent(GreedyOneShotAgent)
def init(self):
self.secured = 0

def step(self):
self.secured = 0

def on_negotiation_success(self, contract, mechanism):
self.secured += contract.agreement["quantity"]
def _needed(self):
return self.awi.current_exogenous_input_quantity + \
self.awi.current_exogenous_output_quantity - \
self.secured
def propose(self, negotiator_id: str, state) -> "Outcome":
return self.best_offer(negotiator_id)
my_needs = self._needed()
if my_needs <= 0:
return ResponseType.END_NEGOTIATION
return ResponseType.ACCEPT_OFFER if offer[QUANTITY] <= my_needs else ResponseType.REJECT_OFFER
my_needs = self._needed()
if my_needs <= 0:
return None
ami = self.get_ami(negotiator_id)
if not ami:
return None
quantity_issue = ami.issues[QUANTITY]
unit_price_issue = ami.issues[UNIT_PRICE]
offer = [-1] * 3
offer[TIME] = self.awi.current_step
offer[QUANTITY] = max(
min(my_needs, quantity_issue.max_value), quantity_issue.min_value
)
if self._is_selling(ami):
offer[UNIT_PRICE] = unit_price_issue.max_value
else:
offer[UNIT_PRICE] = unit_price_issue.min_value
return tuple(offer)

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store