File size: 4,162 Bytes
48c47f7
 
61854d8
 
a9c1106
61854d8
 
 
3882ecb
a9c1106
48c47f7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61854d8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import io

# ============================================================
#  SLOTING OPTIMIZATION — PHASE 1
# ============================================================

def run_slotting_analysis(message, slotting_df):
    reasoning_steps = []

    df = slotting_df.copy()

    # ---------------------------------------------------------
    # 1️⃣ Convert velocity to numerical weight
    # ---------------------------------------------------------
    velocity_map = {
        "fast": 3,
        "medium": 2,
        "slow": 1
    }

    df["VelocityNorm"] = df["Velocity"].str.lower().map(velocity_map)
    reasoning_steps.append("Mapped velocity categories to numerical weights.")

    # ---------------------------------------------------------
    # 2️⃣ Normalize frequency (usage)
    # ---------------------------------------------------------
    df["FreqNorm"] = (df["Frequency"] - df["Frequency"].min()) / (
        df["Frequency"].max() - df["Frequency"].min() + 1e-8
    )
    reasoning_steps.append("Normalized frequency to 0–1 scale.")

    # ---------------------------------------------------------
    # 3️⃣ Compute Slotting Score
    # ---------------------------------------------------------
    df["Score"] = (0.6 * df["VelocityNorm"]) + (0.4 * df["FreqNorm"])
    reasoning_steps.append("Computed weighted slotting score (60% velocity, 40% frequency).")

    # ---------------------------------------------------------
    # 4️⃣ Assign Aisles and Racks based on score
    # ---------------------------------------------------------
    df = df.sort_values("Score", ascending=False).reset_index(drop=True)

    aisles = np.arange(1, len(df) + 1)
    racks = np.linspace(1, 20, len(df)).astype(int)

    df["Aisle"] = aisles
    df["Rack"] = racks
    reasoning_steps.append("Assigned optimal aisle & rack positions based on ranking.")

    explanation = (
        "### 📦 Slotting Optimization\n"
        "The SKUs were evaluated using a weighted model combining velocity and picking frequency.\n"
        "High-velocity & high-frequency items are placed closer to prime aisles.\n\n"
        "#### 🔍 Key Reasoning Steps:\n"
        + "\n".join([f"- {r}" for r in reasoning_steps])
    )

    return explanation, df


# ============================================================
#  PICKING ROUTE OPTIMIZATION — PHASE 1
# ============================================================

def run_picking_optimization(message, picking_df):
    reasoning_steps = []

    df = picking_df.copy()

    # ---------------------------------------------------------
    # 1️⃣ Convert Aisle–Rack to coordinates
    # ---------------------------------------------------------
    df["x"] = df["Aisle"]
    df["y"] = df["Rack"]
    reasoning_steps.append("Converted Aisle–Rack values into x–y coordinate grid.")

    # ---------------------------------------------------------
    # 2️⃣ Compute Manhattan distance
    # ---------------------------------------------------------
    df["Distance"] = df["x"].abs() + df["y"].abs()
    df = df.sort_values("Distance").reset_index(drop=True)
    reasoning_steps.append("Calculated Manhattan distance and sorted for optimal walk order.")

    # ---------------------------------------------------------
    # 3️⃣ Plot the route
    # ---------------------------------------------------------
    plt.figure(figsize=(6, 6))
    plt.plot(df["x"], df["y"], marker="o", linestyle="-")
    plt.title("Optimized Picking Route")
    plt.xlabel("Aisle")
    plt.ylabel("Rack")

    # Save image to BytesIO buffer
    buffer = io.BytesIO()
    plt.savefig(buffer, format="png")
    buffer.seek(0)
    plt.close()

    reasoning_steps.append("Generated optimized walking path visualization.")

    explanation = (
        "### 🚚 Picking Route Optimization\n"
        "Using Manhattan distance and spatial ordering, an optimal walking sequence was generated.\n\n"
        "#### 🔍 Key Reasoning Steps:\n"
        + "\n".join([f"- {r}" for r in reasoning_steps])
    )

    return explanation, buffer