ritesh27gole commited on
Commit
d755709
·
1 Parent(s): 991b1dd

Initial commit

Browse files
factory_env/env.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ from typing import List
3
+ from factory_env.models import Observation, Action, Machine, Job
4
+
5
+ class FactoryEnv:
6
+ def __init__(self, task="easy"):
7
+ self.task = task
8
+ self.time = 0
9
+ self.max_steps = 20
10
+
11
+ async def reset(self):
12
+ random.seed(42)
13
+
14
+ self.time = 0
15
+
16
+ self.machines = [
17
+ Machine(id="M1", status="idle"),
18
+ Machine(id="M2", status="idle"),
19
+ ]
20
+
21
+ self.jobs = [
22
+ Job(id="J1", remaining_time=3, deadline=10),
23
+ Job(id="J2", remaining_time=2, deadline=8),
24
+ ]
25
+
26
+ return self._get_result(0.0, False)
27
+
28
+
29
+ async def step(self, action: Action):
30
+ reward = 0.0
31
+
32
+ # Apply action
33
+ if action.action_type == "assign_job":
34
+ job = self._find_job(action.job_id)
35
+ machine = self._find_machine(action.machine_id)
36
+
37
+ if job and machine and machine.status == "idle":
38
+ job.assigned_machine = machine.id
39
+ machine.status = "busy"
40
+ machine.current_job = job.id
41
+ reward += 0.2
42
+ else:
43
+ reward -= 0.2 # invalid action
44
+
45
+ # Simulate time
46
+ self.time += 1
47
+
48
+ for machine in self.machines:
49
+ if machine.status == "busy":
50
+ job = self._find_job(machine.current_job)
51
+ job.remaining_time -= 1
52
+
53
+ if job.remaining_time <= 0:
54
+ reward += 1.0
55
+ self.jobs.remove(job)
56
+ machine.status = "idle"
57
+ machine.current_job = None
58
+
59
+ # Penalty for idle machines
60
+ idle_count = sum(1 for m in self.machines if m.status == "idle")
61
+ reward -= idle_count * 0.05
62
+
63
+ done = self.time >= self.max_steps or len(self.jobs) == 0
64
+
65
+ return self._get_result(reward, done)
66
+
67
+
68
+ def state(self):
69
+ return self._get_observation()
70
+
71
+ def _get_observation(self):
72
+ return Observation(
73
+ machines=self.machines,
74
+ pending_jobs=self.jobs,
75
+ time=self.time,
76
+ )
77
+
78
+ def _get_result(self, reward, done):
79
+ return type("Result", (), {
80
+ "observation": self._get_observation(),
81
+ "reward": reward,
82
+ "done": done
83
+ })
84
+
85
+ def _find_job(self, job_id):
86
+ return next((j for j in self.jobs if j.id == job_id), None)
87
+
88
+ def _find_machine(self, machine_id):
89
+ return next((m for m in self.machines if m.id == machine_id), None)
90
+
91
+ async def close(self):
92
+ pass
93
+
factory_env/grader.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ def compute_score(total_reward, max_possible=20):
2
+ score = total_reward / max_possible
3
+ return max(0.0, min(1.0, score))
factory_env/models.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+ from typing import List, Optional
3
+
4
+ class Machine(BaseModel):
5
+ id: str
6
+ status: str # idle, busy, broken
7
+ current_job: Optional[str] = None
8
+
9
+ class Job(BaseModel):
10
+ id: str
11
+ remaining_time: int
12
+ deadline: int
13
+ assigned_machine: Optional[str] = None
14
+
15
+ class Observation(BaseModel):
16
+ machines: List[Machine]
17
+ pending_jobs: List[Job]
18
+ time: int
19
+
20
+ class Action(BaseModel):
21
+ action_type: str # assign_job, wait
22
+ job_id: Optional[str] = None
23
+ machine_id: Optional[str] = None
24
+
25
+ class Reward(BaseModel):
26
+ value: float
factory_env/tasks.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ TASKS = {
2
+ "easy": {
3
+ "machines": 2,
4
+ "jobs": 2,
5
+ "failures": False,
6
+ },
7
+ "medium": {
8
+ "machines": 3,
9
+ "jobs": 5,
10
+ "failures": True,
11
+ },
12
+ "hard": {
13
+ "machines": 5,
14
+ "jobs": 10,
15
+ "failures": True,
16
+ },
17
+ }
inference.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def parse_action(text):
2
+ parts = text.split()
3
+
4
+ if parts[0] == "assign_job":
5
+ return Action(
6
+ action_type="assign_job",
7
+ job_id=parts[1],
8
+ machine_id=parts[2],
9
+ )
10
+
11
+ return Action(action_type="wait")
openenv.yaml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ name: factory_env
2
+ description: Smart factory scheduling environment
3
+
4
+ tasks:
5
+ - name: easy
6
+ - name: medium
7
+ - name: hard
8
+
9
+ entry_point: factory_env.env:FactoryEnv
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ pydantic
2
+ openai
3
+ asyncio