cloudcost1 / environment.py
ankitxraj21's picture
Update environment.py
37fe9e3 verified
Raw
History Blame Contribute Delete
2 kB
import asyncio
import math
from models import State
class CloudCostEnv:
def __init__(self, task="medium"):
self.task = task
self.reset_vars()
def reset_vars(self):
self.steps = 0
self.servers = 5
self.is_spot = False
async def reset(self):
self.reset_vars()
return self.get_current_state()
def get_current_state(self):
if self.task == "easy":
load = 450
else:
load = int(500 + 350 * math.sin(self.steps / 5))
capacity = self.servers * 100
latency = max(20, (load / (capacity + 1)) * 150)
base_rate = 0.60
current_rate = base_rate * 0.25 if self.is_spot else base_rate
cost = self.servers * current_rate
return State(
cpu_usage=min(99.9, max(0.1, (load / (capacity + 1)) * 100)),
active_servers=self.servers,
hourly_burn_rate=round(cost, 2),
response_latency=round(latency, 2),
incoming_load=load
)
async def step(self, action_int):
if action_int == 1:
self.servers += 1
elif action_int == 2:
self.servers = max(1, self.servers - 1)
elif action_int == 3:
self.is_spot = not self.is_spot
self.steps += 1
state = self.get_current_state()
# Reward strictly between 0 and 1 — never exactly 0.0 or 1.0
reward = 0.95
if state.response_latency > 150:
reward -= 0.35
if state.response_latency > 100:
reward -= 0.15
if state.hourly_burn_rate > 5.0:
reward -= 0.25
if state.hourly_burn_rate > 3.0:
reward -= 0.10
# Clamp strictly between 0.01 and 0.99
reward = max(0.01, min(0.99, round(reward, 4)))
done = self.steps >= 20
return state, reward, done
async def state(self):
return self.get_current_state()
async def close(self):
pass