File size: 5,707 Bytes
a6f3fc0
 
 
 
0504c60
a6f3fc0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d3d43d1
a6f3fc0
 
 
 
d3d43d1
 
 
a6f3fc0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d3d43d1
 
 
 
 
 
 
 
 
 
a6f3fc0
d3d43d1
 
 
 
 
 
a6f3fc0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d3d43d1
 
 
 
a6f3fc0
 
 
 
 
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import gradio as gr
from scipy.optimize import differential_evolution
import pandas as pd
import joblib
import matplotlib.pyplot as plt

# Load trained model
best_model = joblib.load("xgb_model.pkl")

# Predictor names and bounds
predictors = [
    'loaded_drv_time_percycle',
    'empty_drv_time_percycle',
    'Eng_Speed_Ave',
    'empty_stop_time_percycle',
    'loadingstoptime_percycle',
    'loaded_stop_time_percycle'
]

bounds_dict = {
    'loaded_drv_time_percycle': (3, 60),
    'empty_drv_time_percycle': (2, 51),
    'Eng_Speed_Ave': (1051, 1596),
    'empty_stop_time_percycle': (0.2, 24.6),
    'loadingstoptime_percycle': (2, 18),
    'loaded_stop_time_percycle': (0.4, 9)
}

# Optimization function
def optimize_dynamic(
    loaded_drv, empty_drv, eng_speed, empty_stop, loading_stop, loaded_stop,
    fix_loaded_drv, fix_empty_drv, fix_eng_speed, fix_empty_stop, fix_loading_stop, fix_loaded_stop
):
    input_values = {
        'loaded_drv_time_percycle': loaded_drv,
        'empty_drv_time_percycle': empty_drv,
        'Eng_Speed_Ave': eng_speed,
        'empty_stop_time_percycle': empty_stop,
        'loadingstoptime_percycle': loading_stop,
        'loaded_stop_time_percycle': loaded_stop
    }

    fixed_flags = {
        'loaded_drv_time_percycle': fix_loaded_drv,
        'empty_drv_time_percycle': fix_empty_drv,
        'Eng_Speed_Ave': fix_eng_speed,
        'empty_stop_time_percycle': fix_empty_stop,
        'loadingstoptime_percycle': fix_loading_stop,
        'loaded_stop_time_percycle': fix_loaded_stop
    }

    bounds = []
    variable_names = []
    for name in predictors:
        if not fixed_flags[name]:
            bounds.append(bounds_dict[name])
            variable_names.append(name)

    if len(variable_names) == 0:
        pred = best_model.predict(pd.DataFrame([input_values]))[0]
        return f"✅ All inputs fixed.\nPredicted Fuel Rate: {pred:.2f} L/cycle"

    def objective(x):
        current_input = input_values.copy()
        for i, name in enumerate(variable_names):
            current_input[name] = x[i]
        return best_model.predict(pd.DataFrame([current_input]))[0]

    result = differential_evolution(objective, bounds=bounds, seed=42, maxiter=100)

    final_input = input_values.copy()
    for i, name in enumerate(variable_names):
        final_input[name] = result.x[i]

    changes = []
    for name in variable_names:
        original = input_values[name]
        optimized = final_input[name]
        if abs(original - optimized) > 0.01:
            changes.append(f"{name}: {original:.2f}{optimized:.2f}")
        else:
            changes.append(f"{name}: unchanged ({original:.2f})")

    result_text = "\n".join([f"{k}: {v:.2f}" for k, v in final_input.items()])
    result_text += "\n\n🔁 Optimized Inputs:\n" + "\n".join(changes)
    result_text += f"\n\n⚡️ Predicted Fuel Rate: {result.fun:.2f} L/cycle"

    # Sensitivity analysis for Engine Speed
    # sensitivity_lines = ["\n📊 Suggested RPM vs. Fuel Rate:"]
    start_rpm = int(round(final_input['Eng_Speed_Ave'] / 50.0) * 50)
    end_rpm = min(start_rpm + 300, bounds_dict['Eng_Speed_Ave'][1])
    start_rpm = max(start_rpm, bounds_dict['Eng_Speed_Ave'][0])

    rpm_values = []
    fuel_rates = []

    for rpm in range(start_rpm, end_rpm + 1, 50):
        temp_input = final_input.copy()
        temp_input['Eng_Speed_Ave'] = rpm

        temp_bounds = []
        temp_names = []

        for name in predictors:
            if name != 'Eng_Speed_Ave' and not fixed_flags.get(name, False):
                temp_bounds.append(bounds_dict[name])
                temp_names.append(name)

        def temp_objective(x):
            t_input = temp_input.copy()
            for i, name in enumerate(temp_names):
                t_input[name] = x[i]
            return best_model.predict(pd.DataFrame([t_input]))[0]

        if temp_bounds:
            temp_result = differential_evolution(temp_objective, bounds=temp_bounds, seed=42, maxiter=50)
            fuel_rate = temp_result.fun
        else:
            fuel_rate = best_model.predict(pd.DataFrame([temp_input]))[0]

        rpm_values.append(rpm)
        fuel_rates.append(fuel_rate)

    # Create plot
    plt.figure(figsize=(6, 4))
    plt.plot(rpm_values, fuel_rates, marker='o')
    plt.title("Sensitivity of Fuel Rate to Engine Speed")
    plt.xlabel("Engine Speed (RPM)")
    plt.ylabel("Predicted Fuel Rate (L/cycle)")
    plt.grid(True)

    # Save and return plot image
    plot_path = "sensitivity_plot.png"
    plt.savefig(plot_path)
    plt.close()

    return result_text, plot_path

# Gradio Interface (Interface-style)
interface = gr.Interface(
    fn=optimize_dynamic,
    inputs=[
        gr.Slider(3, 60, value=30, label="Loaded Drive Time"),
        gr.Slider(2, 51, value=23.8, label="Empty Drive Time"),
        gr.Slider(1051, 1596, value=1300, label="Engine Speed"),
        gr.Slider(0.2, 24.6, value=10.0, label="Empty Stop Time"),
        gr.Slider(2, 18, value=2.0, label="Loading Stop Time"),
        gr.Slider(0.4, 9, value=0.4, label="Loaded Stop Time"),
        gr.Checkbox(label="Fix Loaded Drive"),
        gr.Checkbox(label="Fix Empty Drive"),
        gr.Checkbox(label="Fix Engine Speed"),
        gr.Checkbox(label="Fix Empty Stop"),
        gr.Checkbox(label="Fix Loading Stop"),
        gr.Checkbox(label="Fix Loaded Stop"),
    ],
        outputs=[
        gr.Textbox(label="Optimization Result"),
        gr.Image(type="filepath", label="Sensitivity Plot")
    ],
    title="⚙️ Fuel Rate What-If Optimizer",
    description="Perform global optimization of fuel rate with optional fixed inputs and sensitivity on engine RPM."
)

interface.launch()