MBG0903 commited on
Commit
48c47f7
·
verified ·
1 Parent(s): 2fcbbcc

Update agents/reasoner.py

Browse files
Files changed (1) hide show
  1. agents/reasoner.py +55 -104
agents/reasoner.py CHANGED
@@ -1,107 +1,58 @@
1
- import matplotlib.pyplot as plt
2
- import io
3
- from matplotlib.figure import Figure
4
 
5
- # -------------------------------------------------------------
6
- # UTILITY: Convert Matplotlib Figure → PNG bytes (Gradio compatible)
7
- # -------------------------------------------------------------
8
- def fig_to_png_bytes(fig: Figure):
9
- """Convert a matplotlib figure to PNG bytes for Gradio Image()."""
10
- buf = io.BytesIO()
11
- fig.savefig(buf, format="png", dpi=120, bbox_inches="tight")
12
- buf.seek(0)
13
- return buf.getvalue()
14
 
15
-
16
- # -------------------------------------------------------------
17
- # SLOTING ANALYSIS
18
- # -------------------------------------------------------------
19
  def run_slotting_analysis(message, slotting_df):
20
- reasoning = []
21
- reasoning.append("Interpreting slotting optimization request.")
22
-
23
- # Example strategy:
24
- strategy = "Move slow movers outward to free prime space"
25
- reasoning.append(f"Selected strategy: {strategy}")
26
-
27
- # Generate a mock optimized slotting table:
28
- optimized = slotting_df.copy()
29
- optimized["Aisle"] = [1, 11, 20] # example optimized aisles
30
- optimized["Rack"] = [18, 17, 7] # example optimized racks
31
-
32
- reasoning.append("Generated optimized slotting plan.")
33
-
34
- explanation = " ".join(reasoning)
35
-
36
- return explanation, optimized
37
-
38
-
39
-
40
- # -------------------------------------------------------------
41
- # PICKING ROUTE OPTIMIZATION (WITH PNG OUTPUT)
42
- # -------------------------------------------------------------
43
- def run_picking_optimization(message, picking_df):
44
- reasoning = []
45
- reasoning.append("Analyzing picking request…")
46
-
47
- # Convert to integer pairs
48
- coords = list(zip(
49
- picking_df["Aisle"].astype(int).tolist(),
50
- picking_df["Rack"].astype(int).tolist()
51
- ))
52
-
53
- # --- Nearest neighbour route selection ---
54
- ordered = [coords.pop(0)]
55
- while coords:
56
- last = ordered[-1]
57
- next_point = min(coords, key=lambda c: abs(c[0] - last[0]) + abs(c[1] - last[1]))
58
- ordered.append(next_point)
59
- coords.remove(next_point)
60
-
61
- # --- Build matplotlib figure ---
62
- fig, ax = plt.subplots(figsize=(5, 5))
63
- xs = [x for x, _ in ordered]
64
- ys = [y for _, y in ordered]
65
- ax.plot(xs, ys, marker="o")
66
- ax.set_title("Optimized Picking Route")
67
- ax.set_xlabel("Aisle")
68
- ax.set_ylabel("Rack")
69
-
70
- reasoning.append("Generated optimized picking route.")
71
-
72
- explanation = " ".join(reasoning)
73
-
74
- # Convert FIG → PNG bytes
75
- png_bytes = fig_to_png_bytes(fig)
76
-
77
- # return explanation + PNG bytes (NO slotting table)
78
- return explanation, png_bytes
79
-
80
-
81
-
82
- # -------------------------------------------------------------
83
- # FULL WAREHOUSE REPORT (WITH GRAPH + TABLE)
84
- # -------------------------------------------------------------
85
- def run_full_report(message, slotting_df, picking_df):
86
- reasoning = []
87
- reasoning.append("Building unified warehouse operations report…")
88
-
89
- # Summary counts
90
- fast = (slotting_df["Velocity"] == "Fast").sum()
91
- med = (slotting_df["Velocity"] == "Medium").sum()
92
- slow = (slotting_df["Velocity"] == "Slow").sum()
93
-
94
- summary = f"""
95
- Warehouse Summary:
96
- - Fast movers: {fast}
97
- - Medium movers: {med}
98
- - Slow movers: {slow}
99
- """
100
-
101
- explanation = " ".join(reasoning) + "\n" + summary
102
-
103
- # Include picking graph in the full report
104
- _, fig_bytes = run_picking_optimization(message, picking_df)
105
-
106
- # Return: explanation, PNG route graph, AND slotting table
107
- return explanation, fig_bytes, slotting_df.copy()
 
1
+ import pandas as pd
2
+ import numpy as np
 
3
 
 
 
 
 
 
 
 
 
 
4
 
 
 
 
 
5
  def run_slotting_analysis(message, slotting_df):
6
+ reasoning_steps = []
7
+
8
+ df = slotting_df.copy()
9
+
10
+ # ---------------------------------------------------------
11
+ # 1️⃣ Convert velocity to numerical weight
12
+ # ---------------------------------------------------------
13
+ velocity_map = {
14
+ "fast": 3,
15
+ "medium": 2,
16
+ "slow": 1
17
+ }
18
+
19
+ df["VelocityNorm"] = df["Velocity"].str.lower().map(velocity_map)
20
+ reasoning_steps.append("Mapped velocity categories to numerical weights.")
21
+
22
+ # ---------------------------------------------------------
23
+ # 2️⃣ Normalize frequency (usage)
24
+ # ---------------------------------------------------------
25
+ df["FreqNorm"] = (df["Frequency"] - df["Frequency"].min()) / (
26
+ df["Frequency"].max() - df["Frequency"].min() + 1e-8
27
+ )
28
+ reasoning_steps.append("Normalized frequency to 0–1 scale.")
29
+
30
+ # ---------------------------------------------------------
31
+ # 3️⃣ Compute Slotting Score
32
+ # ---------------------------------------------------------
33
+ # Weighted: 60% velocity + 40% frequency
34
+ df["Score"] = (0.6 * df["VelocityNorm"]) + (0.4 * df["FreqNorm"])
35
+ reasoning_steps.append("Computed weighted slotting score (60% velocity, 40% frequency).")
36
+
37
+ # ---------------------------------------------------------
38
+ # 4️⃣ Assign Aisles and Racks based on score
39
+ # ---------------------------------------------------------
40
+ df = df.sort_values("Score", ascending=False).reset_index(drop=True)
41
+
42
+ # Prime aisles 1–5 → best locations
43
+ aisles = np.arange(1, len(df) + 1)
44
+ racks = np.linspace(1, 20, len(df)).astype(int)
45
+
46
+ df["Aisle"] = aisles
47
+ df["Rack"] = racks
48
+ reasoning_steps.append("Assigned optimal aisle & rack positions based on ranking.")
49
+
50
+ explanation = (
51
+ "### 📦 Slotting Optimization\n"
52
+ "The SKUs were evaluated using a weighted model combining velocity and picking frequency.\n"
53
+ "High-velocity & high-frequency items are placed closer to prime aisles.\n\n"
54
+ "#### 🔍 Key Reasoning Steps:\n"
55
+ + "\n".join([f"- {r}" for r in reasoning_steps])
56
+ )
57
+
58
+ return explanation, df