ricky-tudjuka commited on
Commit
a6f3fc0
·
verified ·
1 Parent(s): 0e039f4

Upload 3 files

Browse files
Files changed (2) hide show
  1. app.py +144 -0
  2. requirements.txt +5 -0
app.py ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from scipy.optimize import differential_evolution
3
+ import pandas as pd
4
+ import joblib
5
+
6
+ # Load trained model
7
+ best_model = joblib.load("xgb_model.pkl")
8
+
9
+ # Predictor names and bounds
10
+ predictors = [
11
+ 'loaded_drv_time_percycle',
12
+ 'empty_drv_time_percycle',
13
+ 'Eng_Speed_Ave',
14
+ 'empty_stop_time_percycle',
15
+ 'loadingstoptime_percycle',
16
+ 'loaded_stop_time_percycle'
17
+ ]
18
+
19
+ bounds_dict = {
20
+ 'loaded_drv_time_percycle': (3, 60),
21
+ 'empty_drv_time_percycle': (2, 51),
22
+ 'Eng_Speed_Ave': (1051, 1596),
23
+ 'empty_stop_time_percycle': (0.2, 24.6),
24
+ 'loadingstoptime_percycle': (2, 18),
25
+ 'loaded_stop_time_percycle': (0.4, 9)
26
+ }
27
+
28
+ # Optimization function
29
+ def optimize_dynamic(
30
+ loaded_drv, empty_drv, eng_speed, empty_stop, loading_stop, loaded_stop,
31
+ fix_loaded_drv, fix_empty_drv, fix_eng_speed, fix_empty_stop, fix_loading_stop, fix_loaded_stop
32
+ ):
33
+ input_values = {
34
+ 'loaded_drv_time_percycle': loaded_drv,
35
+ 'empty_drv_time_percycle': empty_drv,
36
+ 'Eng_Speed_Ave': eng_speed,
37
+ 'empty_stop_time_percycle': empty_stop,
38
+ 'loadingstoptime_percycle': loading_stop,
39
+ 'loaded_stop_time_percycle': loaded_stop
40
+ }
41
+
42
+ fixed_flags = {
43
+ 'loaded_drv_time_percycle': fix_loaded_drv,
44
+ 'empty_drv_time_percycle': fix_empty_drv,
45
+ 'Eng_Speed_Ave': fix_eng_speed,
46
+ 'empty_stop_time_percycle': fix_empty_stop,
47
+ 'loadingstoptime_percycle': fix_loading_stop,
48
+ 'loaded_stop_time_percycle': fix_loaded_stop
49
+ }
50
+
51
+ bounds = []
52
+ variable_names = []
53
+ for name in predictors:
54
+ if not fixed_flags[name]:
55
+ bounds.append(bounds_dict[name])
56
+ variable_names.append(name)
57
+
58
+ if len(variable_names) == 0:
59
+ pred = best_model.predict(pd.DataFrame([input_values]))[0]
60
+ return f"✅ All inputs fixed.\nPredicted Fuel Rate: {pred:.2f} L/cycle"
61
+
62
+ def objective(x):
63
+ current_input = input_values.copy()
64
+ for i, name in enumerate(variable_names):
65
+ current_input[name] = x[i]
66
+ return best_model.predict(pd.DataFrame([current_input]))[0]
67
+
68
+ result = differential_evolution(objective, bounds=bounds, seed=42, maxiter=100)
69
+
70
+ final_input = input_values.copy()
71
+ for i, name in enumerate(variable_names):
72
+ final_input[name] = result.x[i]
73
+
74
+ changes = []
75
+ for name in variable_names:
76
+ original = input_values[name]
77
+ optimized = final_input[name]
78
+ if abs(original - optimized) > 0.01:
79
+ changes.append(f"{name}: {original:.2f} → {optimized:.2f}")
80
+ else:
81
+ changes.append(f"{name}: unchanged ({original:.2f})")
82
+
83
+ result_text = "\n".join([f"{k}: {v:.2f}" for k, v in final_input.items()])
84
+ result_text += "\n\n🔁 Optimized Inputs:\n" + "\n".join(changes)
85
+ result_text += f"\n\n⚡️ Predicted Fuel Rate: {result.fun:.2f} L/cycle"
86
+
87
+ # Sensitivity analysis for Engine Speed
88
+ sensitivity_lines = ["\n📊 Suggested RPM vs. Fuel Rate:"]
89
+ start_rpm = int(round(final_input['Eng_Speed_Ave'] / 50.0) * 50)
90
+ end_rpm = min(start_rpm + 300, bounds_dict['Eng_Speed_Ave'][1])
91
+ start_rpm = max(start_rpm, bounds_dict['Eng_Speed_Ave'][0])
92
+
93
+ for rpm in range(start_rpm, end_rpm + 1, 50):
94
+ temp_input = final_input.copy()
95
+ temp_input['Eng_Speed_Ave'] = rpm
96
+
97
+ temp_bounds = []
98
+ temp_names = []
99
+
100
+ for name in predictors:
101
+ if name != 'Eng_Speed_Ave' and not fixed_flags.get(name, False):
102
+ temp_bounds.append(bounds_dict[name])
103
+ temp_names.append(name)
104
+
105
+ def temp_objective(x):
106
+ t_input = temp_input.copy()
107
+ for i, name in enumerate(temp_names):
108
+ t_input[name] = x[i]
109
+ return best_model.predict(pd.DataFrame([t_input]))[0]
110
+
111
+ if temp_bounds:
112
+ temp_result = differential_evolution(temp_objective, bounds=temp_bounds, seed=42, maxiter=50)
113
+ fuel_rate = temp_result.fun
114
+ else:
115
+ fuel_rate = best_model.predict(pd.DataFrame([temp_input]))[0]
116
+
117
+ sensitivity_lines.append(f"RPM {rpm}: {fuel_rate:.2f} L/cycle")
118
+
119
+ result_text += "\n" + "\n".join(sensitivity_lines)
120
+ return result_text
121
+
122
+ # Gradio Interface (Interface-style)
123
+ interface = gr.Interface(
124
+ fn=optimize_dynamic,
125
+ inputs=[
126
+ gr.Slider(3, 60, value=30, label="Loaded Drive Time"),
127
+ gr.Slider(2, 51, value=23.8, label="Empty Drive Time"),
128
+ gr.Slider(1051, 1596, value=1300, label="Engine Speed"),
129
+ gr.Slider(0.2, 24.6, value=10.0, label="Empty Stop Time"),
130
+ gr.Slider(2, 18, value=2.0, label="Loading Stop Time"),
131
+ gr.Slider(0.4, 9, value=0.4, label="Loaded Stop Time"),
132
+ gr.Checkbox(label="Fix Loaded Drive"),
133
+ gr.Checkbox(label="Fix Empty Drive"),
134
+ gr.Checkbox(label="Fix Engine Speed"),
135
+ gr.Checkbox(label="Fix Empty Stop"),
136
+ gr.Checkbox(label="Fix Loading Stop"),
137
+ gr.Checkbox(label="Fix Loaded Stop"),
138
+ ],
139
+ outputs=gr.Textbox(label="Optimization Result", lines=16),
140
+ title="⚙️ Fuel Rate What-If Optimizer",
141
+ description="Perform global optimization of fuel rate with optional fixed inputs and sensitivity on engine RPM."
142
+ )
143
+
144
+ interface.launch()
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio
2
+ pandas
3
+ scipy
4
+ xgboost
5
+ joblib