mirror of
https://github.com/velocitatem/PHANTOM.git
synced 2026-05-31 08:33:36 +00:00
porting to better
This commit is contained in:
66
engine/engine.py
Normal file
66
engine/engine.py
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
from sys import platform
|
||||||
|
import numpy as np
|
||||||
|
from .lib.demand import generate_demand, estimate_demand
|
||||||
|
from .lib.behavior import sample_behavior
|
||||||
|
from logging import INFO, getLogger
|
||||||
|
logger = getLogger(__name__)
|
||||||
|
logger.setLevel(INFO)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MarketEngine():
|
||||||
|
def __init__(self,
|
||||||
|
alpha = 0.5,
|
||||||
|
N = 100,
|
||||||
|
demand_distribution = (50, 10),
|
||||||
|
demand_sampling_function = np.random.normal):
|
||||||
|
self.Nagents = int(N*alpha)
|
||||||
|
self.Nhumans = int(N*(1-alpha))
|
||||||
|
self.demand = (demand_sampling_function, demand_distribution)
|
||||||
|
|
||||||
|
def act(self, prices):
|
||||||
|
demand = generate_demand(prices, *self.demand)
|
||||||
|
sample_n = lambda n, human: [sample_behavior(demand, human=human) for _ in range(n)]
|
||||||
|
human_t, agent_t = sample_n(100, True), sample_n(100, False)
|
||||||
|
trajectories = human_t + agent_t
|
||||||
|
demand_estimate = estimate_demand(trajectories)
|
||||||
|
return demand_estimate
|
||||||
|
|
||||||
|
def measure(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class PricingEngine():
|
||||||
|
def __init__(self,
|
||||||
|
) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def act(self, demand):
|
||||||
|
return np.random.uniform(low=25, high=100, size=10)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Limbo():
|
||||||
|
def __init__(self,
|
||||||
|
platform,
|
||||||
|
market
|
||||||
|
) -> None:
|
||||||
|
self.platform_turn = True
|
||||||
|
self.platform = platform
|
||||||
|
self.market = market
|
||||||
|
self.output = None
|
||||||
|
|
||||||
|
def step(self):
|
||||||
|
# we could code golf this a little bit
|
||||||
|
if self.platform_turn:
|
||||||
|
self.output = self.platform.act(self.output)
|
||||||
|
else:
|
||||||
|
self.output = self.market.act(self.output)
|
||||||
|
print(self.output)
|
||||||
|
self.platform_turn = not self.platform_turn
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
platform = PricingEngine()
|
||||||
|
market = MarketEngine()
|
||||||
|
limbo = Limbo(platform, market)
|
||||||
|
for _ in range(10):
|
||||||
|
limbo.step()
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
|
import logging
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from logging import getLogger
|
||||||
|
logger = getLogger(__name__)
|
||||||
|
|
||||||
def generate_demand(prices):
|
def generate_demand(prices, distribution_method = np.random.normal, distribution_params = (50.0, 10.0)):
|
||||||
# assumption 1: each product has an intrinsic valuation drawn from a normal distribution centered at 50
|
# assumption 1: each product has an intrinsic valuation drawn from a normal distribution centered at 50
|
||||||
product_valuations = np.random.normal(loc=50.0, scale=10.0, size=len(prices))
|
product_valuations = distribution_method(*distribution_params, size=len(prices))
|
||||||
# assumption 2: demand decreases as price increases, following a simple linear model
|
# assumption 2: demand decreases as price increases, following a simple linear model
|
||||||
demand = np.maximum(0, product_valuations - prices) # demand cannot be negative
|
demand = np.maximum(0, product_valuations - prices) # demand cannot be negative
|
||||||
demand = demand / np.sum(demand) * 100 # normalize to total demand of 1000 units so demand output is within [0, 100]
|
demand = demand / np.sum(demand) * 100 # normalize to total demand of 1000 units so demand output is within [0, 100]
|
||||||
|
logger.info(f"Generated demand for prices {prices}: {demand} with valuations from distribution {distribution_params}")
|
||||||
return demand
|
return demand
|
||||||
|
|
||||||
def estimate_demand(trajectories):
|
def estimate_demand(trajectories):
|
||||||
|
|||||||
5
engine/wrapper.py
Normal file
5
engine/wrapper.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import gymnasium as gym
|
||||||
|
from gymnasium import spaces
|
||||||
|
from engine import Limbo
|
||||||
|
|
||||||
|
class PHANTOM(gym.Env, Limbo):
|
||||||
Reference in New Issue
Block a user