porting to better

This commit is contained in:
2026-01-28 16:09:28 +01:00
parent 83d9bb2552
commit 6e06081d60
4 changed files with 77 additions and 2 deletions

66
engine/engine.py Normal file
View 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()

View File

@@ -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):

View File

5
engine/wrapper.py Normal file
View File

@@ -0,0 +1,5 @@
import gymnasium as gym
from gymnasium import spaces
from engine import Limbo
class PHANTOM(gym.Env, Limbo):