From 81b0ad0124847f083990d574dc8d20961ec6e713 Mon Sep 17 00:00:00 2001
From: baoshiwei <baoshiwei@shlanbao.cn>
Date: 星期三, 01 四月 2026 14:12:55 +0800
Subject: [PATCH] feat(参数调节): 添加优化版挤出机参数调节页面

---
 app/pages/metered_weight_advanced.py        |    6 
 app/pages/metered_weight_correlation.py     |  448 ++++++++++++++++++++
 app/pages/optimized_parameter_adjustment.py |  811 ++++++++++++++++++++++++++++++++++++
 dashboard.py                                |   10 
 4 files changed, 1,271 insertions(+), 4 deletions(-)

diff --git a/app/pages/metered_weight_advanced.py b/app/pages/metered_weight_advanced.py
index 5a9dea8..3676644 100644
--- a/app/pages/metered_weight_advanced.py
+++ b/app/pages/metered_weight_advanced.py
@@ -141,11 +141,11 @@
     if 'ma_steady_window' not in st.session_state:
         st.session_state['ma_steady_window'] = 20
     if 'ma_steady_threshold' not in st.session_state:
-        st.session_state['ma_steady_threshold'] = 0.5
+        st.session_state['ma_steady_threshold'] = 1.5
         
     # 榛樿鐗瑰緛鍒楄〃锛堜笉鍐嶅厑璁哥敤鎴烽�夋嫨锛�
-    default_features = ['铻烘潌杞��', '鏈哄ご鍘嬪姏', '娴佺▼涓婚��', '铻烘潌娓╁害', 
-                       '鍚庢満绛掓俯搴�', '鍓嶆満绛掓俯搴�', '鏈哄ご娓╁害']
+    default_features = ['铻烘潌杞��', '鏈哄ご鍘嬪姏', '娴佺▼涓婚��', '鍚庢満绛掓俯搴�']
+    
 
     # 瀹氫箟鍥炶皟鍑芥暟
     def update_dates(qs):
diff --git a/app/pages/metered_weight_correlation.py b/app/pages/metered_weight_correlation.py
index 0afb421..d6d862f 100644
--- a/app/pages/metered_weight_correlation.py
+++ b/app/pages/metered_weight_correlation.py
@@ -6,6 +6,118 @@
 from datetime import datetime, timedelta
 from app.services.extruder_service import ExtruderService
 from app.services.main_process_service import MainProcessService
+from app.services.data_processing_service import DataProcessingService
+
+# 绋虫�佽瘑鍒被瀹氫箟
+class SteadyStateDetector:
+    def __init__(self):
+        self.data_processor = DataProcessingService()
+    
+    def preprocess_data(self, df, weight_col='metered_weight', window_size=20):
+        if df is None or df.empty:
+            return df
+        
+        df_processed = df.copy()
+        
+        df_processed[weight_col] = df_processed[weight_col].ffill().bfill()
+        df_processed['smoothed_weight'] = df_processed[weight_col]
+        df_processed['rolling_std'] = df_processed[weight_col].rolling(window=window_size, min_periods=1).std()
+        df_processed['rolling_mean'] = df_processed[weight_col].rolling(window=window_size, min_periods=1).mean()
+        
+        return df_processed
+    
+    def detect_steady_state(self, df, weight_col='smoothed_weight', window_size=20, std_threshold=0.5, duration_threshold=60):
+        if df is None or df.empty:
+            return df, []
+        
+        df['time'] = pd.to_datetime(df['time'])
+        df['time_diff'] = df['time'].diff().dt.total_seconds().fillna(0)
+        df['is_steady'] = 0
+        
+        df['window_std'] = df['smoothed_weight'].rolling(window=window_size, min_periods=5).std()
+        df['window_mean'] = df['smoothed_weight'].rolling(window=window_size, min_periods=5).mean()
+        df['fluctuation_range'] = (df['window_std'] / df['window_mean']) * 100
+        df['fluctuation_range'] = df['fluctuation_range'].fillna(0)
+        
+        df.loc[(df['fluctuation_range'] < std_threshold) & (df['smoothed_weight'] >= 0.1), 'is_steady'] = 1
+        
+        steady_segments = []
+        current_segment = {}
+        
+        for i, row in df.iterrows():
+            if row['is_steady'] == 1:
+                if not current_segment:
+                    current_segment = {
+                        'start_time': row['time'],
+                        'start_idx': i,
+                        'weights': [row['smoothed_weight']]
+                    }
+                else:
+                    current_segment['weights'].append(row['smoothed_weight'])
+            else:
+                if current_segment:
+                    current_segment['end_time'] = df.loc[i-1, 'time'] if i > 0 else df.loc[i, 'time']
+                    current_segment['end_idx'] = i-1
+                    duration = (current_segment['end_time'] - current_segment['start_time']).total_seconds()
+                    
+                    if duration >= duration_threshold:
+                        weights_array = np.array(current_segment['weights'])
+                        current_segment['duration'] = duration
+                        current_segment['mean_weight'] = np.mean(weights_array)
+                        current_segment['std_weight'] = np.std(weights_array)
+                        current_segment['min_weight'] = np.min(weights_array)
+                        current_segment['max_weight'] = np.max(weights_array)
+                        current_segment['fluctuation_range'] = (current_segment['std_weight'] / current_segment['mean_weight']) * 100
+                        
+                        confidence = 100 - (current_segment['fluctuation_range'] / std_threshold) * 50
+                        confidence = max(50, min(100, confidence))
+                        current_segment['confidence'] = confidence
+                        
+                        steady_segments.append(current_segment)
+                    
+                    current_segment = {}
+        
+        if current_segment:
+            current_segment['end_time'] = df['time'].iloc[-1]
+            current_segment['end_idx'] = len(df) - 1
+            duration = (current_segment['end_time'] - current_segment['start_time']).total_seconds()
+            
+            if duration >= duration_threshold:
+                weights_array = np.array(current_segment['weights'])
+                current_segment['duration'] = duration
+                current_segment['mean_weight'] = np.mean(weights_array)
+                current_segment['std_weight'] = np.std(weights_array)
+                current_segment['min_weight'] = np.min(weights_array)
+                current_segment['max_weight'] = np.max(weights_array)
+                current_segment['fluctuation_range'] = (current_segment['std_weight'] / current_segment['mean_weight']) * 100
+                
+                confidence = 100 - (current_segment['fluctuation_range'] / std_threshold) * 50
+                confidence = max(50, min(100, confidence))
+                current_segment['confidence'] = confidence
+                
+                steady_segments.append(current_segment)
+        
+        for segment in steady_segments:
+            df.loc[segment['start_idx']:segment['end_idx'], 'is_steady'] = 1
+        
+        return df, steady_segments
+    
+    def get_steady_state_metrics(self, steady_segments):
+        if not steady_segments:
+            return {}
+        
+        avg_duration = np.mean([seg['duration'] for seg in steady_segments])
+        avg_fluctuation = np.mean([seg['fluctuation_range'] for seg in steady_segments])
+        avg_confidence = np.mean([seg['confidence'] for seg in steady_segments])
+        total_steady_duration = sum([seg['duration'] for seg in steady_segments])
+        
+        return {
+            'total_steady_segments': len(steady_segments),
+            'average_steady_duration': avg_duration,
+            'average_fluctuation_range': avg_fluctuation,
+            'average_confidence': avg_confidence,
+            'total_steady_duration': total_steady_duration
+        }
 
 def show_metered_weight_correlation():
     # 鍒濆鍖栨湇鍔�
@@ -14,6 +126,11 @@
 
     # 椤甸潰鏍囬
     st.title("绫抽噸鐩稿叧鎬у垎鏋�")
+
+    # 鍒濆鍖栨湇鍔�
+    extruder_service = ExtruderService()
+    main_process_service = MainProcessService()
+    steady_state_detector = SteadyStateDetector()
 
     # 鍒濆鍖栦細璇濈姸鎬佺敤浜庢棩鏈熷悓姝�
     if 'mc_start_date' not in st.session_state:
@@ -24,6 +141,16 @@
         st.session_state['mc_quick_select'] = "鏈�杩�7澶�"
     if 'mc_time_offset' not in st.session_state:
         st.session_state['mc_time_offset'] = 0.0
+    
+    # 鍒濆鍖栫ǔ鎬佽瘑鍒浉鍏冲弬鏁�
+    if 'mc_ss_window_size' not in st.session_state:
+        st.session_state['mc_ss_window_size'] = 20
+    if 'mc_ss_std_threshold' not in st.session_state:
+        st.session_state['mc_ss_std_threshold'] = 1.5
+    if 'mc_ss_duration_threshold' not in st.session_state:
+        st.session_state['mc_ss_duration_threshold'] = 60
+    if 'mc_use_steady_only' not in st.session_state:
+        st.session_state['mc_use_steady_only'] = False
 
     # 瀹氫箟鍥炶皟鍑芥暟
     def update_dates(qs):
@@ -114,6 +241,55 @@
             st.session_state['mc_time_offset'] = time_offset
         with offset_cols[2]:
             st.write(f"褰撳墠鍋忕Щ: {time_offset} 鍒嗛挓")
+        
+        # 绋虫�佸弬鏁伴厤缃�
+        st.markdown("---")
+        steady_state_cols = st.columns(4)
+        
+        with steady_state_cols[0]:
+            st.write("鈿欙笍 **绋虫�佸弬鏁伴厤缃�**")
+            window_size = st.slider(
+                "婊戝姩绐楀彛澶у皬 (绉�)",
+                min_value=5,
+                max_value=60,
+                value=st.session_state['mc_ss_window_size'],
+                step=5,
+                key="mc_ss_window_size",
+                help="鐢ㄤ簬骞虫粦鏁版嵁鍜岃绠楃粺璁$壒寰佺殑婊戝姩绐楀彛澶у皬"
+            )
+        
+        with steady_state_cols[1]:
+            st.write("馃搹 **娉㈠姩闃堝�奸厤缃�**")
+            std_threshold = st.slider(
+                "鏍囧噯宸槇鍊�",
+                min_value=0.1,
+                max_value=2.0,
+                value=st.session_state['mc_ss_std_threshold'],
+                step=0.1,
+                key="mc_ss_std_threshold",
+                help="绫抽噸娉㈠姩鐨勬爣鍑嗗樊闃堝�硷紝浣庝簬姝ゅ�艰涓虹ǔ鎬�"
+            )
+        
+        with steady_state_cols[2]:
+            st.write("鈴憋笍 **鎸佺画鏃堕棿閰嶇疆**")
+            duration_threshold = st.slider(
+                "绋虫�佹寔缁椂闂� (绉�)",
+                min_value=30,
+                max_value=300,
+                value=st.session_state['mc_ss_duration_threshold'],
+                step=10,
+                key="mc_ss_duration_threshold",
+                help="绋虫�佹寔缁殑鏈�灏忔椂闂达紝浣庝簬姝ゅ�间笉瑙嗕负绋虫�佹"
+            )
+        
+        with steady_state_cols[3]:
+            st.write("馃幆 **鍒嗘瀽鏁版嵁閫夋嫨**")
+            use_steady_only = st.checkbox(
+                "浠呬娇鐢ㄧǔ鎬佹暟鎹�",
+                value=st.session_state['mc_use_steady_only'],
+                key="mc_use_steady_only",
+                help="鍕鹃�夊悗锛岀浉鍏虫�у垎鏋愪粎浣跨敤璇嗗埆鍑虹殑绋虫�佹暟鎹�"
+            )
 
     # 杞崲涓篸atetime瀵硅薄
     start_dt = datetime.combine(start_date, datetime.min.time())
@@ -264,6 +440,32 @@
                 
                 return df_merged
 
+            # 鎵ц绋虫�佽瘑鍒�
+            df_extruder_steady, steady_segments = None, []
+            if df_extruder_filtered is not None and not df_extruder_filtered.empty:
+                # 鏁版嵁棰勫鐞�
+                df_processed = steady_state_detector.preprocess_data(
+                    df_extruder_filtered, 
+                    weight_col='metered_weight',
+                    window_size=st.session_state['mc_ss_window_size']
+                )
+                
+                # 绋虫�佹娴�
+                df_extruder_steady, steady_segments = steady_state_detector.detect_steady_state(
+                    df_processed,
+                    weight_col='smoothed_weight',
+                    window_size=st.session_state['mc_ss_window_size'],
+                    std_threshold=st.session_state['mc_ss_std_threshold'],
+                    duration_threshold=st.session_state['mc_ss_duration_threshold']
+                )
+                
+                # 灏嗙ǔ鎬佹爣璁版坊鍔犲埌df_extruder_filtered涓紝浠ヤ究鍦ㄨ秼鍔垮浘涓娇鐢�
+                df_extruder_filtered = df_extruder_filtered.merge(
+                    df_extruder_steady[['time', 'is_steady', 'smoothed_weight', 'fluctuation_range']],
+                    on='time',
+                    how='left'
+                )
+            
             # 鎵ц鏁版嵁鏁村悎
             df_analysis = integrate_data(df_extruder_filtered, df_main_speed, df_temp)
             
@@ -273,6 +475,26 @@
 
             # 閲嶅懡鍚嶇背閲嶅垪
             df_analysis.rename(columns={'metered_weight': '绫抽噸'}, inplace=True)
+            
+            # 濡傛灉閫夋嫨浠呬娇鐢ㄧǔ鎬佹暟鎹紝杩囨护鎺夐潪绋虫�佹暟鎹�
+            if st.session_state['mc_use_steady_only']:
+                # 纭繚df_analysis鍖呭惈is_steady鍒�
+                if 'is_steady' not in df_analysis.columns:
+                    # 灏嗙ǔ鎬佹爣璁板悎骞跺埌鍒嗘瀽鏁版嵁涓�
+                    df_analysis = df_analysis.merge(
+                        df_extruder_steady[['time', 'is_steady']],
+                        on='time',
+                        how='left'
+                    )
+                # 杩囨护绋虫�佹暟鎹�
+                df_analysis = df_analysis[df_analysis['is_steady'] == 1]
+                if df_analysis.empty:
+                    st.warning("鏈壘鍒扮ǔ鎬佹暟鎹紝璇疯皟鏁寸ǔ鎬佸弬鏁版垨鍙栨秷'浠呬娇鐢ㄧǔ鎬佹暟鎹�'閫夐」銆�")
+                    return
+            
+            # 缂撳瓨绋虫�佹暟鎹埌浼氳瘽鐘舵��
+            st.session_state['cached_steady_segments'] = steady_segments
+            st.session_state['cached_extruder_steady'] = df_extruder_steady
 
             # --- 鍘熷鏁版嵁瓒嬪娍鍥� ---
             st.subheader("馃搱 鍘熷鏁版嵁瓒嬪娍鍥�")
@@ -360,6 +582,24 @@
                     yaxis='y5'
                 ))
             
+            # 娣诲姞绋虫�佸尯鍩熸爣璁�
+            for segment in steady_segments:
+                # 鑾峰彇绫抽噸鏁版嵁鐨剏杞磋寖鍥达紝鐢ㄤ簬纭畾鐭╁舰楂樺害
+                y_min = df_extruder_filtered['metered_weight'].min() * 0.95
+                y_max = df_extruder_filtered['metered_weight'].max() * 1.05
+                
+                fig_trend.add_shape(
+                    type="rect",
+                    x0=segment['start_time'],
+                    y0=y_min,
+                    x1=segment['end_time'],
+                    y1=y_max,
+                    fillcolor="rgba(0, 255, 0, 0.2)",
+                    line=dict(color="rgba(0, 200, 0, 0.5)", width=1),
+                    name="绋虫�佸尯鍩�",
+                    layer="below"
+                )
+            
             # 閰嶇疆瓒嬪娍鍥惧竷灞�
             fig_trend.update_layout(
                 title=f'鍘熷鏁版嵁瓒嬪娍 (绫抽噸鍚戝墠鍋忕Щ {st.session_state["mc_time_offset"]} 鍒嗛挓)',
@@ -423,6 +663,214 @@
             # 鏄剧ず瓒嬪娍鍥�
             selection = st.plotly_chart(fig_trend, width='stretch', config={'scrollZoom': True}, on_select='rerun' )
 
+            # 绋虫�佺粺璁℃寚鏍�
+            st.subheader("馃搳 绋虫�佽瘑鍒粺璁�")
+            steady_metrics = steady_state_detector.get_steady_state_metrics(steady_segments)
+            metrics_cols = st.columns(5)
+            
+            with metrics_cols[0]:
+                st.metric(
+                    "绋虫�佹鎬绘暟",
+                    steady_metrics.get('total_steady_segments', 0),
+                    help="璇嗗埆鍒扮殑绋虫�佹鏁伴噺"
+                )
+            
+            with metrics_cols[1]:
+                st.metric(
+                    "骞冲潎绋虫�佹椂闀�",
+                    f"{steady_metrics.get('average_steady_duration', 0):.2f} 绉�",
+                    help="鎵�鏈夌ǔ鎬佹鐨勫钩鍧囨寔缁椂闂�"
+                )
+            
+            with metrics_cols[2]:
+                st.metric(
+                    "骞冲潎娉㈠姩鑼冨洿",
+                    f"{steady_metrics.get('average_fluctuation_range', 0):.2f}%",
+                    help="绋虫�佹鍐呯背閲嶇殑骞冲潎娉㈠姩鑼冨洿锛堢浉瀵逛簬鍧囧�肩殑鐧惧垎姣旓級"
+                )
+            
+            with metrics_cols[3]:
+                st.metric(
+                    "骞冲潎缃俊搴�",
+                    f"{steady_metrics.get('average_confidence', 0):.1f}%",
+                    help="绋虫�佽瘑鍒粨鏋滅殑骞冲潎缃俊搴�"
+                )
+            
+            with metrics_cols[4]:
+                st.metric(
+                    "鎬荤ǔ鎬佹椂闀�",
+                    f"{steady_metrics.get('total_steady_duration', 0)/60:.2f} 鍒嗛挓",
+                    help="鎵�鏈夌ǔ鎬佹鐨勬�绘寔缁椂闂�"
+                )
+
+            # --- 绋虫�佹暟鎹秼鍔垮浘 --- 
+            st.subheader("馃搳 绋虫�佹暟鎹秼鍔垮浘")
+            
+            # 鍒涘缓绋虫�佹暟鎹秼鍔垮浘
+            if df_extruder_steady is not None and not df_extruder_steady.empty:
+                fig_steady = go.Figure()
+                
+                # 娣诲姞鍘熷绫抽噸鏁版嵁
+                fig_steady.add_trace(go.Scatter(
+                    x=df_extruder_steady['time'],
+                    y=df_extruder_steady['metered_weight'],
+                    name='鍘熷绫抽噸',
+                    mode='lines',
+                    opacity=0.6,
+                    line=dict(color='lightblue', width=1)
+                ))
+                
+                # 娣诲姞骞虫粦鍚庣殑绫抽噸鏁版嵁
+                fig_steady.add_trace(go.Scatter(
+                    x=df_extruder_steady['time'],
+                    y=df_extruder_steady['smoothed_weight'],
+                    name='骞虫粦绫抽噸',
+                    mode='lines',
+                    line=dict(color='blue', width=2)
+                ))
+                
+                # 娣诲姞娉㈠姩鑼冨洿锛堜綔涓洪潰绉浘锛�
+                fig_steady.add_trace(go.Scatter(
+                    x=df_extruder_steady['time'],
+                    y=df_extruder_steady['metered_weight'] + df_extruder_steady['rolling_std'],
+                    name='娉㈠姩涓婇檺',
+                    mode='lines',
+                    line=dict(color='rgba(255,0,0,0)'),
+                    showlegend=True
+                ))
+                
+                fig_steady.add_trace(go.Scatter(
+                    x=df_extruder_steady['time'],
+                    y=df_extruder_steady['metered_weight'] - df_extruder_steady['rolling_std'],
+                    name='娉㈠姩涓嬮檺',
+                    mode='lines',
+                    line=dict(color='rgba(255,0,0,0)'),
+                    fill='tonexty',
+                    fillcolor='rgba(255,0,0,0.1)'
+                ))
+                
+                # 娣诲姞绋虫�佹爣璁�
+                fig_steady.add_trace(go.Scatter(
+                    x=df_extruder_steady['time'],
+                    y=df_extruder_steady['is_steady'] * (df_extruder_steady['metered_weight'].max() * 1.1),
+                    name='绋虫�佹爣璁�',
+                    mode='lines',
+                    line=dict(color='green', width=1, dash='dash')
+                ))
+                
+                # 閰嶇疆绋虫�佹暟鎹秼鍔垮浘甯冨眬
+                fig_steady.update_layout(
+                    title="绋虫�佹暟鎹秼鍔垮垎鏋�",
+                    xaxis=dict(
+                        title='鏃堕棿',
+                        rangeslider=dict(visible=True),
+                        type='date'
+                    ),
+                    yaxis=dict(
+                        title='绫抽噸 (Kg/m)',
+                        title_font=dict(color='blue'),
+                        tickfont=dict(color='blue')
+                    ),
+                    yaxis2=dict(
+                        title='绋虫�佹爣璁�',
+                        title_font=dict(color='green'),
+                        tickfont=dict(color='green'),
+                        overlaying='y',
+                        side='right',
+                        range=[-0.1, 1.1],
+                        showgrid=False
+                    ),
+                    legend=dict(
+                        orientation="h",
+                        yanchor="bottom",
+                        y=1.02,
+                        xanchor="right",
+                        x=1
+                    ),
+                    height=500,
+                    margin=dict(l=100, r=100, t=100, b=100),
+                    hovermode='x unified'
+                )
+                
+                # 鏄剧ず绋虫�佹暟鎹秼鍔垮浘
+                st.plotly_chart(fig_steady, width='stretch', config={'scrollZoom': True})
+            
+            # --- 绋虫�佸弬鏁扮浉鍏虫�ц秼鍔垮浘 --- 
+            st.subheader("馃搱 绋虫�佸弬鏁扮浉鍏虫�ц秼鍔垮浘")
+            
+            if df_analysis is not None and not df_analysis.empty:
+                # 鍒涘缓绋虫�佸弬鏁扮浉鍏虫�ц秼鍔垮浘
+                fig_steady_corr = go.Figure()
+                
+                # 閫夋嫨鐩稿叧绯绘暟鏈�楂樼殑鍓�3涓弬鏁�
+                if '绫抽噸' in df_analysis.columns:
+                    # 璁$畻鍚勫弬鏁颁笌绫抽噸鐨勭浉鍏崇郴鏁�
+                    corr_with_weight = df_analysis.corr()[['绫抽噸']].sort_values('绫抽噸', ascending=False)
+                    top_params = corr_with_weight.index[1:4]  # 鎺掗櫎绫抽噸鏈韩锛屽彇鍓�3涓�
+                    
+                    # 娣诲姞绫抽噸鏁版嵁
+                    fig_steady_corr.add_trace(go.Scatter(
+                        x=df_analysis['time'],
+                        y=df_analysis['绫抽噸'],
+                        name='绫抽噸',
+                        mode='lines',
+                        line=dict(color='blue', width=2),
+                        yaxis='y'
+                    ))
+                    
+                    # 娣诲姞鐩稿叧鍙傛暟鏁版嵁
+                    colors = ['red', 'green', 'orange']
+                    for i, param in enumerate(top_params):
+                        if param in df_analysis.columns:
+                            fig_steady_corr.add_trace(go.Scatter(
+                                x=df_analysis['time'],
+                                y=df_analysis[param],
+                                name=param,
+                                mode='lines',
+                                line=dict(color=colors[i], width=1.5),
+                                yaxis=f'y{i+2}'
+                            ))
+                    
+                    # 閰嶇疆鍥捐〃甯冨眬
+                    layout = {
+                        'title': f'绫抽噸涓庣浉鍏冲弬鏁拌秼鍔匡紙鍓�3涓浉鍏冲弬鏁帮級',
+                        'xaxis': {
+                            'title': '鏃堕棿',
+                            'rangeslider': dict(visible=True),
+                            'type': 'date'
+                        },
+                        'yaxis': {
+                            'title': '绫抽噸 (Kg/m)',
+                            'title_font': dict(color='blue'),
+                            'tickfont': dict(color='blue')
+                        },
+                        'legend': {
+                            'orientation': "h",
+                            'yanchor': "bottom",
+                            'y': 1.02,
+                            'xanchor': "right",
+                            'x': 1
+                        },
+                        'height': 600,
+                        'margin': dict(l=100, r=200, t=100, b=100),
+                        'hovermode': 'x unified'
+                    }
+                    
+                    # 娣诲姞棰濆鐨剏杞撮厤缃�
+                    for i, param in enumerate(top_params):
+                        layout[f'yaxis{i+2}'] = {
+                            'title': param,
+                            'title_font': dict(color=colors[i]),
+                            'tickfont': dict(color=colors[i]),
+                            'overlaying': 'y',
+                            'side': 'right',
+                            'anchor': 'free',
+                            'position': 1 - (i+1)*0.15
+                        }
+                    
+                    fig_steady_corr.update_layout(layout)
+                    st.plotly_chart(fig_steady_corr, width='stretch', config={'scrollZoom': True})
+
             # 璋冭瘯杈撳嚭
           #  st.write("鍘熷 selection 瀵硅薄:", selection)
 
diff --git a/app/pages/optimized_parameter_adjustment.py b/app/pages/optimized_parameter_adjustment.py
new file mode 100644
index 0000000..750de02
--- /dev/null
+++ b/app/pages/optimized_parameter_adjustment.py
@@ -0,0 +1,811 @@
+import streamlit as st
+import plotly.express as px
+import plotly.graph_objects as go
+import pandas as pd
+import numpy as np
+import joblib
+import os
+from datetime import datetime
+from sklearn.preprocessing import MinMaxScaler
+
+# 椤甸潰鍑芥暟瀹氫箟
+def show_optimized_parameter_adjustment():
+    # 椤甸潰鏍囬
+    st.title("浼樺寲鐗堟尋鍑烘満鍙傛暟璋冭妭寤鸿")
+    
+    # 娣诲姞鎿嶄綔鎸囧紩
+    with st.expander("馃摉 鎿嶄綔鎸囧紩", expanded=True):
+        st.markdown("""
+        娆㈣繋浣跨敤浼樺寲鐗堟尋鍑烘満鍙傛暟璋冭妭寤鸿鍔熻兘锛佹湰鍔熻兘鍩轰簬澶氱洰鏍囦紭鍖栫畻娉曪紝鏍规嵁鎮ㄨ緭鍏ョ殑绫抽噸鏁版嵁鍜屽綋鍓嶅弬鏁帮紝涓烘偍鎻愪緵绉戝鍚堢悊鐨勫弬鏁拌皟鏁村缓璁��
+        
+        **鎿嶄綔姝ラ锛�**
+        1. 閫夋嫨涓�涓凡璁粌濂界殑妯″瀷
+        2. 杈撳叆绫抽噸鏍囧噯鍊笺�佷笂涓嬮檺鍜屽綋鍓嶆尋鍑烘満鍙傛暟
+        3. 杈撳叆褰撳墠瀹為檯绫抽噸娴嬮噺鍊�
+        4. 璋冩暣浼樺寲鍙傛暟锛堝彲閫夛級
+        5. 鐐瑰嚮"璁$畻浼樺寲璋冭妭寤鸿"鎸夐挳
+        6. 鏌ョ湅绯荤粺鐢熸垚鐨勫弬鏁拌皟鏁村缓璁�
+        
+        **娉ㄦ剰浜嬮」锛�**
+        - 璇风‘淇濊緭鍏ョ殑鍙傛暟鍊煎湪璁惧鍏佽鐨勮寖鍥村唴
+        - 浼樺寲绠楁硶浼氬钩琛$背閲嶅亸宸拰璋冩暣骞呭害
+        - 鍘嗗彶璋冭妭璁板綍鍙湪椤甸潰搴曢儴鏌ョ湅
+        """)
+    
+    # 鍒濆鍖栦細璇濈姸鎬�
+    if 'optimized_adjustment_history' not in st.session_state:
+        st.session_state['optimized_adjustment_history'] = []
+    
+    # 1. 妯″瀷閫夋嫨鍖哄煙
+    with st.expander("馃攳 妯″瀷閫夋嫨", expanded=True):
+        # 鍒涘缓妯″瀷鐩綍锛堝鏋滀笉瀛樺湪锛�
+        model_dir = "saved_models"
+        os.makedirs(model_dir, exist_ok=True)
+        
+        # 鑾峰彇鎵�鏈夊凡淇濆瓨鐨勬ā鍨嬫枃浠�
+        model_files = [f for f in os.listdir(model_dir) if f.endswith('.joblib')]
+        model_files.sort(reverse=True)  # 鏈�鏂扮殑妯″瀷鎺掑湪鍓嶉潰
+        
+        if not model_files:
+            st.warning("灏氭湭淇濆瓨浠讳綍妯″瀷锛岃鍏堣缁冩ā鍨嬪苟淇濆瓨銆�")
+            return
+        
+        # 妯″瀷閫夋嫨涓嬫媺妗�
+        selected_model_file = st.selectbox(
+            "閫夋嫨宸蹭繚瀛樼殑妯″瀷",
+            options=model_files,
+            help="閫夋嫨瑕佺敤浜庨娴嬬殑妯″瀷鏂囦欢"
+        )
+        
+        # 鍔犺浇骞舵樉绀烘ā鍨嬩俊鎭�
+        if selected_model_file:
+            model_path = os.path.join(model_dir, selected_model_file)
+            model_info = joblib.load(model_path)
+            
+            # 鏄剧ず妯″瀷鍩烘湰淇℃伅
+            st.subheader("馃搳 妯″瀷淇℃伅")
+            info_cols = st.columns(2)
+            
+            with info_cols[0]:
+                st.metric("妯″瀷绫诲瀷", model_info['model_type'])
+                st.metric("鍒涘缓鏃堕棿", model_info['created_at'].strftime('%Y-%m-%d %H:%M:%S'))
+                st.metric("浣跨敤绋虫�佹暟鎹�", "鏄�" if model_info.get('use_steady_data', False) else "鍚�")
+            
+            with info_cols[1]:
+                st.metric("R虏 寰楀垎", f"{model_info['r2_score']:.4f}")
+                st.metric("鍧囨柟璇樊 (MSE)", f"{model_info['mse']:.6f}")
+                st.metric("鍧囨柟鏍硅宸� (RMSE)", f"{model_info['rmse']:.6f}")
+            
+            # 鏄剧ず妯″瀷鐗瑰緛
+            st.write("馃攽 妯″瀷浣跨敤鐨勭壒寰�:")
+            st.code(", ".join(model_info['features']))
+            
+            # 濡傛灉鏄繁搴﹀涔犳ā鍨嬶紝鏄剧ず搴忓垪闀垮害
+            if 'sequence_length' in model_info:
+                st.metric("搴忓垪闀垮害", model_info['sequence_length'])
+            
+            # 淇濆瓨妯″瀷淇℃伅鍒颁細璇濈姸鎬�
+            st.session_state['selected_model'] = model_info
+            st.session_state['selected_model_file'] = selected_model_file
+    
+    # 2. 鍙傛暟杈撳叆鍖哄煙
+    st.subheader("馃摑 鍙傛暟杈撳叆")
+    
+    # 2.1 绫抽噸鏍囧噯鍊笺�佷笂涓嬮檺杈撳叆
+    with st.expander("鈿栵笍 绫抽噸鏍囧噯涓庝笂涓嬮檺", expanded=True):
+        weight_cols = st.columns(3)
+        
+        with weight_cols[0]:
+            standard_weight = st.number_input(
+                "鏍囧噯绫抽噸",
+                key="standard_weight",
+                value=5.20,
+                min_value=0.01,
+                max_value=10.0,
+                step=0.0001,
+                format="%.4f",
+                help="杈撳叆鐩爣绫抽噸鏍囧噯鍊�"
+            )
+            st.caption("鍗曚綅: Kg/m")
+        
+        with weight_cols[1]:
+            upper_limit = st.number_input(
+                "绫抽噸涓婇檺",
+                key="upper_limit",
+                value=5.46,
+                min_value=standard_weight,
+                max_value=10.0,
+                step=0.0001,
+                format="%.4f",
+                help="杈撳叆绫抽噸鍏佽鐨勪笂闄愬��"
+            )
+            st.caption("鍗曚綅: Kg/m")
+        
+        with weight_cols[2]:
+            lower_limit = st.number_input(
+                "绫抽噸涓嬮檺",
+                key="lower_limit",
+                value=5.02,
+                min_value=0.01,
+                max_value=standard_weight,
+                step=0.0001,
+                format="%.4f",
+                help="杈撳叆绫抽噸鍏佽鐨勪笅闄愬��"
+            )
+            st.caption("鍗曚綅: Kg/m")
+    
+    # 2.2 鎸ゅ嚭鏈哄綋鍓嶅弬鏁拌緭鍏�
+    with st.expander("馃敡 鎸ゅ嚭鏈哄綋鍓嶅弬鏁�", expanded=True):
+        param_cols = st.columns(3)
+        
+        with param_cols[0]:
+            current_screw_speed = st.number_input(
+                "铻烘潌杞��",
+                key="current_screw_speed",
+                value=230.0,
+                min_value=0.0,
+                max_value=500.0,
+                step=0.1,
+                help="杈撳叆褰撳墠铻烘潌杞��"
+            )
+            st.caption("鍗曚綅: rpm")
+            
+            current_head_pressure = st.number_input(
+                "鏈哄ご鍘嬪姏",
+                key="current_head_pressure",
+                value=0.26,
+                min_value=0.0,
+                max_value=500.0,
+                format="%.4f",
+                step=1.0,
+                help="杈撳叆褰撳墠鏈哄ご鍘嬪姏"
+            )
+            st.caption("鍗曚綅: bar")
+            
+            current_process_speed = st.number_input(
+                "娴佺▼涓婚��",
+                key="current_process_speed",
+                value=6.6,
+                min_value=0.0,
+                max_value=300.0,
+                step=0.1,
+                help="杈撳叆褰撳墠娴佺▼涓婚��"
+            )
+            st.caption("鍗曚綅: m/min")
+        
+        with param_cols[1]:
+            current_screw_temperature = st.number_input(
+                "铻烘潌娓╁害",
+                key="current_screw_temperature",
+                value=79.9,
+                min_value=0.0,
+                max_value=300.0,
+                step=1.0,
+                help="杈撳叆褰撳墠铻烘潌娓╁害"
+            )
+            st.caption("鍗曚綅: 掳C")
+            
+            current_rear_barrel_temperature = st.number_input(
+                "鍚庢満绛掓俯搴�",
+                key="current_rear_barrel_temperature",
+                value=79.9,
+                min_value=0.0,
+                max_value=300.0,
+                step=1.0,
+                help="杈撳叆褰撳墠鍚庢満绛掓俯搴�"
+            )
+            st.caption("鍗曚綅: 掳C")
+        
+        with param_cols[2]:
+            current_front_barrel_temperature = st.number_input(
+                "鍓嶆満绛掓俯搴�",
+                key="current_front_barrel_temperature",
+                value=80.1,
+                min_value=0.0,
+                max_value=300.0,
+                step=1.0,
+                help="杈撳叆褰撳墠鍓嶆満绛掓俯搴�"
+            )
+            st.caption("鍗曚綅: 掳C")
+            
+            current_head_temperature = st.number_input(
+                "鏈哄ご娓╁害",
+                key="current_head_temperature",
+                value=95.1,
+                min_value=0.0,
+                max_value=300.0,
+                step=1.0,
+                help="杈撳叆褰撳墠鏈哄ご娓╁害"
+            )
+            st.caption("鍗曚綅: 掳C")
+    
+    # 2.3 褰撳墠瀹為檯绫抽噸娴嬮噺鍊艰緭鍏�
+    with st.expander("馃搹 褰撳墠瀹為檯绫抽噸", expanded=True):
+        actual_weight = st.number_input(
+            "褰撳墠瀹為檯绫抽噸",
+            key="actual_weight",
+            value=5.115,
+            min_value=0.01,
+            max_value=10.0,
+            step=0.0001,
+            format="%.4f",
+            help="杈撳叆褰撳墠瀹為檯娴嬮噺鐨勭背閲嶅��"
+        )
+        st.caption("鍗曚綅: Kg/m")
+    
+    # 3. 浼樺寲鍙傛暟璁剧疆
+    st.subheader("鈿欙笍 浼樺寲鍙傛暟璁剧疆")
+    
+    with st.expander("馃幆 澶氱洰鏍囦紭鍖栧弬鏁�", expanded=True):
+        # 鐩爣鏉冮噸璁剧疆
+        st.write("### 鐩爣鏉冮噸")
+        st.markdown("璋冩暣浠ヤ笅鏉冮噸鏉ュ钩琛$背閲嶅亸宸拰璋冩暣骞呭害鐨勯噸瑕佹�э細")
+        weight_cols = st.columns(2)
+        
+        with weight_cols[0]:
+            weight_deviation = st.slider(
+                "绫抽噸鍋忓樊鏉冮噸",
+                min_value=0.1,
+                max_value=1.0,
+                value=0.8,
+                step=0.1,
+                help="鏉冮噸瓒婇珮锛岃秺浼樺厛鑰冭檻鍑忓皯绫抽噸鍋忓樊"
+            )
+        
+        with weight_cols[1]:
+            weight_adjustment = st.slider(
+                "璋冩暣骞呭害鏉冮噸",
+                min_value=0.1,
+                max_value=1.0,
+                value=0.2,
+                step=0.1,
+                help="鏉冮噸瓒婇珮锛岃秺浼樺厛鑰冭檻鍑忓皯璋冩暣骞呭害"
+            )
+        
+        # 璋冩暣鏉冮噸锛岀‘淇濇�诲拰涓�1
+        total_weight = weight_deviation + weight_adjustment
+        weight_deviation = weight_deviation / total_weight
+        weight_adjustment = weight_adjustment / total_weight
+        
+        st.write(f"### 璋冩暣鍚庢潈閲嶏紙鎬诲拰涓�1锛�")
+        st.write(f"- 绫抽噸鍋忓樊鏉冮噸: {weight_deviation:.2f}")
+        st.write(f"- 璋冩暣骞呭害鏉冮噸: {weight_adjustment:.2f}")
+        
+        # 鍙傛暟璋冩暣绾︽潫
+        st.write("### 鍙傛暟璋冩暣绾︽潫")
+        constraint_cols = st.columns(2)
+        
+        with constraint_cols[0]:
+            max_screw_speed_adjust = st.slider(
+                "铻烘潌杞�熸渶澶ц皟鏁村箙搴�(%)",
+                min_value=5.0,
+                max_value=20.0,
+                value=15.0,
+                step=1.0,
+                help="鍗曟璋冩暣鐨勬渶澶х櫨鍒嗘瘮"
+            )
+        
+        with constraint_cols[1]:
+            max_process_speed_adjust = st.slider(
+                "娴佺▼涓婚�熸渶澶ц皟鏁村箙搴�(%)",
+                min_value=3.0,
+                max_value=15.0,
+                value=10.0,
+                step=1.0,
+                help="鍗曟璋冩暣鐨勬渶澶х櫨鍒嗘瘮"
+            )
+    
+    # 4. 璁$畻浼樺寲璋冭妭寤鸿
+    st.subheader("馃殌 璁$畻浼樺寲璋冭妭寤鸿")
+    
+    if st.button("馃搳 璁$畻浼樺寲璋冭妭寤鸿", key="calculate_optimized_adjustment"):
+        # 鍙傛暟楠岃瘉
+        validation_errors = []
+        
+        if standard_weight <= 0:
+            validation_errors.append("鏍囧噯绫抽噸蹇呴』澶т簬0")
+        
+        if upper_limit <= standard_weight:
+            validation_errors.append("绫抽噸涓婇檺蹇呴』澶т簬鏍囧噯绫抽噸")
+        
+        if lower_limit >= standard_weight:
+            validation_errors.append("绫抽噸涓嬮檺蹇呴』灏忎簬鏍囧噯绫抽噸")
+        
+        if current_screw_speed <= 0:
+            validation_errors.append("铻烘潌杞�熷繀椤诲ぇ浜�0")
+        
+        if current_process_speed <= 0:
+            validation_errors.append("娴佺▼涓婚�熷繀椤诲ぇ浜�0")
+        
+        if actual_weight <= 0:
+            validation_errors.append("瀹為檯绫抽噸蹇呴』澶т簬0")
+        
+        if validation_errors:
+            st.error("鍙傛暟杈撳叆閿欒锛�")
+            for error in validation_errors:
+                st.error(f"- {error}")
+        else:
+            with st.spinner("姝e湪璁$畻浼樺寲璋冭妭寤鸿..."):
+                # 鑾峰彇閫変腑鐨勬ā鍨�
+                if 'selected_model' not in st.session_state:
+                    st.error("璇峰厛閫夋嫨涓�涓ā鍨�")
+                    return
+                
+                model_info = st.session_state['selected_model']
+                model = model_info['model']
+                
+                # 妫�鏌ユ槸鍚︽湁缂╂斁鍣�
+                has_scalers = ('scaler_X' in model_info and model_info['scaler_X'] is not None and 
+                              'scaler_y' in model_info and model_info['scaler_y'] is not None)
+                if has_scalers:
+                    scaler_X = model_info['scaler_X']
+                    scaler_y = model_info['scaler_y']
+                
+                features = model_info['features']
+                
+                # 澶氱洰鏍囦紭鍖栫畻娉� - 绮掑瓙缇や紭鍖�
+                def predict_weight(screw_speed, process_speed):
+                    """浣跨敤妯″瀷棰勬祴绫抽噸"""
+                    # 鍑嗗杈撳叆鏁版嵁
+                    input_data = {
+                        '铻烘潌杞��': screw_speed,
+                        '鏈哄ご鍘嬪姏': current_head_pressure,
+                        '娴佺▼涓婚��': process_speed,
+                        '铻烘潌娓╁害': current_screw_temperature,
+                        '鍚庢満绛掓俯搴�': current_rear_barrel_temperature,
+                        '鍓嶆満绛掓俯搴�': current_front_barrel_temperature,
+                        '鏈哄ご娓╁害': current_head_temperature
+                    }
+                    
+                    # 鏍规嵁妯″瀷鐗瑰緛鍒涘缓杈撳叆DataFrame
+                    input_df = pd.DataFrame([input_data])[features]
+                    
+                    if model_info['model_type'] in ['LSTM', 'GRU', 'BiLSTM']:
+                        # 娣卞害瀛︿範妯″瀷澶勭悊閫昏緫
+                        import torch
+                        
+                        # 妫�鏌ユ槸鍚︽湁缂╂斁鍣�
+                        if has_scalers:
+                            scaled_input = scaler_X.transform(input_df)
+                        else:
+                            scaled_input = input_df.values
+                        
+                        # 鑾峰彇搴忓垪闀垮害
+                        sequence_length = model_info.get('sequence_length', 10)
+                        
+                        # 鍒涘缓搴忓垪鏁版嵁
+                        input_seq = np.tile(scaled_input, (sequence_length, 1)).reshape(1, sequence_length, -1)
+                        
+                        # 杞崲涓篜yTorch寮犻噺
+                        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
+                        input_tensor = torch.tensor(input_seq, dtype=torch.float32).to(device)
+                        
+                        # 棰勬祴
+                        model.eval()
+                        with torch.no_grad():
+                            y_pred_scaled_tensor = model(input_tensor)
+                            y_pred_scaled = y_pred_scaled_tensor.cpu().numpy().ravel()[0]
+                            
+                            if has_scalers:
+                                # 鍙嶇缉鏀鹃娴嬬粨鏋�
+                                predicted_weight = scaler_y.inverse_transform(np.array([[y_pred_scaled]]))[0][0]
+                            else:
+                                predicted_weight = y_pred_scaled
+                    
+                    elif has_scalers:
+                        # 鐗瑰緛缂╂斁
+                        scaled_input = scaler_X.transform(input_df)
+                        
+                        # 妯″瀷棰勬祴
+                        scaled_prediction = model.predict(scaled_input)[0]
+                        
+                        # 鍙嶇缉鏀鹃娴嬬粨鏋�
+                        predicted_weight = scaler_y.inverse_transform(np.array([[scaled_prediction]]))[0][0]
+                    
+                    else:
+                        # 鐩存帴棰勬祴锛屼笉浣跨敤缂╂斁鍣�
+                        predicted_weight = model.predict(input_df)[0]
+                    
+                    return predicted_weight
+                
+                def objective_function(params):
+                    """澶氱洰鏍囩洰鏍囧嚱鏁�"""
+                    screw_speed_val, process_speed_val = params
+                    
+                    # 棰勬祴绫抽噸
+                    predicted_weight_val = predict_weight(screw_speed_val, process_speed_val)
+                    
+                    # 璁$畻鐩爣1锛氱背閲嶅亸宸�
+                    deviation_val = abs(predicted_weight_val - standard_weight)
+                    deviation_percent_val = abs((predicted_weight_val - standard_weight) / standard_weight * 100)
+                    
+                    # 璁$畻鐩爣2锛氳皟鏁村箙搴�
+                    screw_speed_adjustment_val = abs(screw_speed_val - current_screw_speed)
+                    process_speed_adjustment_val = abs(process_speed_val - current_process_speed)
+                    
+                    screw_speed_adjustment_percent_val = abs((screw_speed_val - current_screw_speed) / current_screw_speed * 100)
+                    process_speed_adjustment_percent_val = abs((process_speed_val - current_process_speed) / current_process_speed * 100)
+                    
+                    # 鍔犳潈鐩爣鍑芥暟
+                    objective_val = (weight_deviation * deviation_percent_val + 
+                                    weight_adjustment * (screw_speed_adjustment_percent_val + process_speed_adjustment_percent_val) / 2)
+                    
+                    return objective_val, predicted_weight_val, deviation_percent_val, \
+                           screw_speed_adjustment_percent_val, process_speed_adjustment_percent_val
+                
+                # 鍙傛暟绾︽潫
+                def is_within_constraints(params):
+                    """妫�鏌ュ弬鏁版槸鍚﹀湪绾︽潫鑼冨洿鍐�"""
+                    screw_speed, process_speed = params
+                    
+                    # 铻烘潌杞�熺害鏉�
+                    if not (30 <= screw_speed <= 500):
+                        return False
+                    
+                    # 娴佺▼涓婚�熺害鏉�
+                    if not (0 <= process_speed <= 200):
+                        return False
+                    
+                    # 鍗曟璋冩暣骞呭害绾︽潫
+                    screw_speed_adjustment_percent = abs((screw_speed - current_screw_speed) / current_screw_speed * 100)
+                    if screw_speed_adjustment_percent > max_screw_speed_adjust:
+                        return False
+                    
+                    process_speed_adjustment_percent = abs((process_speed - current_process_speed) / current_process_speed * 100)
+                    if process_speed_adjustment_percent > max_process_speed_adjust:
+                        return False
+                    
+                    return True
+                
+                # 绮掑瓙缇や紭鍖栫畻娉�
+                def particle_swarm_optimization(objective, constraints, bounds, n_particles=30, n_iterations=50):
+                    """绮掑瓙缇や紭鍖栫畻娉�"""
+                    # 鍒濆鍖栫矑瀛�
+                    particles = []
+                    velocities = []
+                    best_positions = []
+                    best_scores = []
+                    
+                    # 杈圭晫
+                    (screw_speed_min, screw_speed_max), (process_speed_min, process_speed_max) = bounds
+                    
+                    for _ in range(n_particles):
+                        # 闅忔満鍒濆鍖栦綅缃�
+                        while True:
+                            screw_speed = np.random.uniform(screw_speed_min, screw_speed_max)
+                            process_speed = np.random.uniform(process_speed_min, process_speed_max)
+                            pos = [screw_speed, process_speed]
+                            if constraints(pos):
+                                break
+                        
+                        particles.append(pos)
+                        velocities.append([0.0, 0.0])
+                        best_positions.append(pos.copy())
+                        
+                        # 璁$畻鍒濆寰楀垎
+                        score, _, _, _, _ = objective(pos)
+                        best_scores.append(score)
+                    
+                    # 鍏ㄥ眬鏈�浼�
+                    global_best_idx = np.argmin(best_scores)
+                    global_best_position = best_positions[global_best_idx].copy()
+                    global_best_score = best_scores[global_best_idx]
+                    
+                    # PSO鍙傛暟
+                    w = 0.5  # 鎯�ф潈閲�
+                    c1 = 1.5  # 璁ょ煡绯绘暟
+                    c2 = 1.5  # 绀句細绯绘暟
+                    
+                    # 杩唬浼樺寲
+                    for _ in range(n_iterations):
+                        for i in range(n_particles):
+                            # 鏇存柊閫熷害
+                            r1, r2 = np.random.rand(), np.random.rand()
+                            velocities[i][0] = (w * velocities[i][0] +
+                                              c1 * r1 * (best_positions[i][0] - particles[i][0]) +
+                                              c2 * r2 * (global_best_position[0] - particles[i][0]))
+                            velocities[i][1] = (w * velocities[i][1] +
+                                              c1 * r1 * (best_positions[i][1] - particles[i][1]) +
+                                              c2 * r2 * (global_best_position[1] - particles[i][1]))
+                            
+                            # 鏇存柊浣嶇疆
+                            new_pos = [
+                                particles[i][0] + velocities[i][0],
+                                particles[i][1] + velocities[i][1]
+                            ]
+                            
+                            # 妫�鏌ョ害鏉�
+                            if constraints(new_pos):
+                                particles[i] = new_pos
+                                
+                                # 鏇存柊涓綋鏈�浼�
+                                current_score, _, _, _, _ = objective(new_pos)
+                                if current_score < best_scores[i]:
+                                    best_scores[i] = current_score
+                                    best_positions[i] = new_pos.copy()
+                                    
+                                    # 鏇存柊鍏ㄥ眬鏈�浼�
+                                    if current_score < global_best_score:
+                                        global_best_score = current_score
+                                        global_best_position = new_pos.copy()
+                    
+                    return global_best_position, global_best_score
+                
+                # 璁剧疆鍙傛暟杈圭晫
+                screw_speed_bounds = [
+                    current_screw_speed * (1 - max_screw_speed_adjust / 100),
+                    current_screw_speed * (1 + max_screw_speed_adjust / 100)
+                ]
+                
+                process_speed_bounds = [
+                    current_process_speed * (1 - max_process_speed_adjust / 100),
+                    current_process_speed * (1 + max_process_speed_adjust / 100)
+                ]
+                
+                # 鎵ц浼樺寲
+                best_params, best_score = particle_swarm_optimization(
+                    objective_function,
+                    is_within_constraints,
+                    [(screw_speed_bounds[0], screw_speed_bounds[1]), 
+                     (process_speed_bounds[0], process_speed_bounds[1])]
+                )
+                
+                # 鑾峰彇鏈�浼樺弬鏁扮殑璇︾粏淇℃伅
+                best_screw_speed, best_process_speed = best_params
+                best_objective, best_predicted_weight, best_deviation_percent, \
+                best_screw_adjust_percent, best_process_adjust_percent = objective_function(best_params)
+                
+                # 璁$畻褰撳墠鍙傛暟鐨勯娴嬬粨鏋�
+                current_predicted_weight = predict_weight(current_screw_speed, current_process_speed)
+                current_deviation_percent = abs((current_predicted_weight - standard_weight) / standard_weight * 100)
+                
+                # 鐢熸垚璋冩暣寤鸿鏂囨湰
+                def generate_recommendation():
+                    """鐢熸垚璋冩暣寤鸿鏂囨湰"""
+                    screw_speed_change = "鎻愰珮" if best_screw_speed > current_screw_speed else "闄嶄綆"
+                    process_speed_change = "鎻愰珮" if best_process_speed > current_process_speed else "闄嶄綆"
+                    
+                    recommendation = f"绫抽噸鍋忓樊 {current_deviation_percent:.2f}%锛屽缓璁皟鏁达細\n"
+                    recommendation += f"1. 灏嗚灪鏉嗚浆閫熶粠 {current_screw_speed:.1f} rpm {screw_speed_change} 鑷� {best_screw_speed:.1f} rpm "
+                    recommendation += f"( {screw_speed_change} {abs(best_screw_adjust_percent):.2f}% )\n"
+                    recommendation += f"2. 灏嗘祦绋嬩富閫熶粠 {current_process_speed:.1f} m/min {process_speed_change} 鑷� {best_process_speed:.1f} m/min "
+                    recommendation += f"( {process_speed_change} {abs(best_process_adjust_percent):.2f}% )\n"
+                    recommendation += f"\n棰勬湡鏁堟灉锛氱背閲嶅亸宸皢闄嶈嚦 {best_deviation_percent:.2f}%"
+                    
+                    return recommendation
+                
+                recommendation = generate_recommendation()
+                
+                # 鏋勫缓璋冩暣缁撴灉
+                adjustment_result = {
+                    'status': '姝e父鑼冨洿' if best_predicted_weight >= lower_limit and best_predicted_weight <= upper_limit else \
+                              '瓒呬笂闄�' if best_predicted_weight > upper_limit else '瓒呬笅闄�',
+                    'real_time_weight': actual_weight,
+                    'standard_weight': standard_weight,
+                    'upper_limit': upper_limit,
+                    'lower_limit': lower_limit,
+                    'current_screw_speed': current_screw_speed,
+                    'current_process_speed': current_process_speed,
+                    'new_screw_speed': best_screw_speed,
+                    'new_process_speed': best_process_speed,
+                    'predicted_weight': best_predicted_weight,
+                    'current_predicted_weight': current_predicted_weight,
+                    'deviation_percentage': (actual_weight - standard_weight) / standard_weight * 100,
+                    'current_predicted_deviation_percent': current_deviation_percent,
+                    'predicted_deviation_percent': best_deviation_percent,
+                    'screw_speed_adjustment': best_screw_speed - current_screw_speed,
+                    'process_speed_adjustment': best_process_speed - current_process_speed,
+                    'screw_speed_adjust_percent': best_screw_adjust_percent,
+                    'process_speed_adjust_percent': best_process_adjust_percent,
+                    'recommendation': recommendation,
+                    'weight_deviation': weight_deviation,
+                    'weight_adjustment': weight_adjustment,
+                    'best_objective_score': best_score
+                }
+                
+                # 淇濆瓨鍒板巻鍙茶褰�
+                history_record = {
+                    'timestamp': datetime.now(),
+                    'model_file': st.session_state.get('selected_model_file', '鏈煡妯″瀷'),
+                    'standard_weight': standard_weight,
+                    'upper_limit': upper_limit,
+                    'lower_limit': lower_limit,
+                    'actual_weight': actual_weight,
+                    'current_screw_speed': current_screw_speed,
+                    'current_process_speed': current_process_speed,
+                    'adjustment_result': adjustment_result
+                }
+                
+                # 娣诲姞鍒颁細璇濈姸鎬佺殑鍘嗗彶璁板綍
+                st.session_state['optimized_adjustment_history'].append(history_record)
+                
+                # 闄愬埗鍘嗗彶璁板綍鏁伴噺
+                if len(st.session_state['optimized_adjustment_history']) > 100:
+                    st.session_state['optimized_adjustment_history'] = st.session_state['optimized_adjustment_history'][-100:]
+                
+                # 5. 缁撴灉灞曠ず
+                st.success("浼樺寲璋冭妭寤鸿璁$畻瀹屾垚锛�")
+                
+                st.subheader("馃搵 浼樺寲璋冭妭寤鸿缁撴灉")
+                
+                # 5.1 绫抽噸鐘舵��
+                if adjustment_result['status'] == "姝e父鑼冨洿":
+                    st.success(f"绫抽噸鐘舵��: {adjustment_result['status']}")
+                else:
+                    st.warning(f"绫抽噸鐘舵��: {adjustment_result['status']}")
+                
+                # 5.2 鍋忓樊淇℃伅
+                st.markdown("### 馃搳 鍋忓樊淇℃伅")
+                info_cols = st.columns(3)
+                info_cols[0].metric("瀹炴椂绫抽噸", f"{adjustment_result['real_time_weight']:.4f} Kg/m")
+                info_cols[1].metric("鏍囧噯绫抽噸", f"{adjustment_result['standard_weight']:.4f} Kg/m")
+                info_cols[2].metric("鍋忓樊鐧惧垎姣�", f"{adjustment_result['deviation_percentage']:.2f}%")
+                
+                # 5.3 棰勬祴缁撴灉瀵规瘮
+                st.markdown("### 馃搱 棰勬祴缁撴灉瀵规瘮")
+                pred_cols = st.columns(3)
+                pred_cols[0].metric("褰撳墠鍙傛暟棰勬祴绫抽噸", f"{adjustment_result['current_predicted_weight']:.4f} Kg/m")
+                pred_cols[1].metric("浼樺寲鍚庨娴嬬背閲�", f"{adjustment_result['predicted_weight']:.4f} Kg/m")
+                pred_cols[2].metric("棰勬祴鍋忓樊鏀瑰杽", f"{adjustment_result['current_predicted_deviation_percent'] - adjustment_result['predicted_deviation_percent']:.2f}%")
+                
+                # 5.4 鍏抽敭璋冩暣寤鸿
+                st.markdown("### 馃攽 鍏抽敭璋冩暣寤鸿")
+                st.info(adjustment_result['recommendation'])
+                
+                # 5.5 鍙傛暟璋冩暣瀵规瘮
+                st.markdown("### 馃搳 鍙傛暟璋冩暣瀵规瘮")
+                
+                param_compare_df = pd.DataFrame({
+                    '鍙傛暟鍚嶇О': ['铻烘潌杞��', '娴佺▼涓婚��'],
+                    '褰撳墠鍊�': [adjustment_result['current_screw_speed'], adjustment_result['current_process_speed']],
+                    '浼樺寲寤鸿鍊�': [adjustment_result['new_screw_speed'], adjustment_result['new_process_speed']],
+                    '璋冩暣骞呭害': [f"{adjustment_result['screw_speed_adjust_percent']:.2f}%",
+                               f"{adjustment_result['process_speed_adjust_percent']:.2f}%"]
+                })
+                
+                # 楂樹寒鏄剧ず璋冩暣骞呭害
+                def highlight_adjustment(val):
+                    if isinstance(val, str) and '%' in val:
+                        try:
+                            percent = float(val.strip('%'))
+                            if percent > 0:
+                                return 'background-color: #90EE90'  # 缁胯壊琛ㄧず澧炲姞
+                            elif percent < 0:
+                                return 'background-color: #FFB6C1'  # 绾㈣壊琛ㄧず鍑忓皯
+                        except:
+                            pass
+                    return ''
+                
+                styled_df = param_compare_df.style.applymap(highlight_adjustment, subset=['璋冩暣骞呭害'])
+                st.dataframe(styled_df, use_container_width=True, hide_index=True)
+                
+                # 5.6 鍙鍖栧姣�
+                fig = go.Figure()
+                fig.add_trace(go.Bar(
+                    x=param_compare_df['鍙傛暟鍚嶇О'],
+                    y=param_compare_df['褰撳墠鍊�'],
+                    name='褰撳墠鍊�',
+                    marker_color='blue'
+                ))
+                fig.add_trace(go.Bar(
+                    x=param_compare_df['鍙傛暟鍚嶇О'],
+                    y=param_compare_df['浼樺寲寤鸿鍊�'],
+                    name='浼樺寲寤鸿鍊�',
+                    marker_color='green'
+                ))
+                
+                fig.update_layout(
+                    barmode='group',
+                    title='鍙傛暟璋冩暣瀵规瘮',
+                    yaxis_title='鏁板��',
+                    height=400
+                )
+                
+                st.plotly_chart(fig, use_container_width=True)
+                
+                # 5.7 浼樺寲鏁堟灉鍙鍖�
+                st.markdown("### 馃搲 浼樺寲鏁堟灉")
+                
+                # 鐩爣鍑芥暟鍊煎姣�
+                fig_objective = go.Figure()
+                fig_objective.add_trace(go.Bar(
+                    x=['褰撳墠鍙傛暟', '浼樺寲鍚庡弬鏁�'],
+                    y=[
+                        weight_deviation * current_deviation_percent + weight_adjustment * 0,
+                        weight_deviation * best_deviation_percent + weight_adjustment * \
+                        (abs(best_screw_adjust_percent) + abs(best_process_adjust_percent)) / 2
+                    ],
+                    marker_color=['red', 'green']
+                ))
+                fig_objective.update_layout(
+                    title='澶氱洰鏍囦紭鍖栧嚱鏁板�煎姣�',
+                    yaxis_title='鐩爣鍑芥暟鍊硷紙瓒婂皬瓒婂ソ锛�',
+                    height=300
+                )
+                st.plotly_chart(fig_objective, use_container_width=True)
+    
+    # 6. 鍘嗗彶璁板綍灞曠ず
+    st.subheader("馃摎 鍘嗗彶璋冭妭璁板綍")
+    
+    if 'optimized_adjustment_history' in st.session_state and st.session_state['optimized_adjustment_history']:
+        # 鏄剧ず鍘嗗彶璁板綍鏁伴噺
+        st.write(f"鍏� {len(st.session_state['optimized_adjustment_history'])} 鏉″巻鍙茶褰�")
+        
+        # 鍒嗛〉鏄剧ず
+        page_size = 10
+        total_pages = (len(st.session_state['optimized_adjustment_history']) + page_size - 1) // page_size
+        
+        page = st.selectbox(
+            "閫夋嫨椤电爜",
+            options=range(1, total_pages + 1),
+            key="history_page"
+        )
+        
+        start_idx = (page - 1) * page_size
+        end_idx = start_idx + page_size
+        paginated_history = st.session_state['optimized_adjustment_history'][start_idx:end_idx]
+        
+        # 鍙嶅悜鏄剧ず锛屾渶鏂拌褰曞湪鍓嶉潰
+        for record in reversed(paginated_history):
+            with st.expander(f"璁板綍鏃堕棿: {record['timestamp'].strftime('%Y-%m-%d %H:%M:%S')} | 妯″瀷: {record['model_file']}"):
+                history_cols = st.columns(3)
+                
+                with history_cols[0]:
+                    st.write("**绫抽噸鍙傛暟**")
+                    st.write(f"- 鏍囧噯绫抽噸: {record['standard_weight']:.4f} Kg/m")
+                    st.write(f"- 绫抽噸涓婇檺: {record['upper_limit']:.4f} Kg/m")
+                    st.write(f"- 绫抽噸涓嬮檺: {record['lower_limit']:.4f} Kg/m")
+                    st.write(f"- 瀹為檯绫抽噸: {record['actual_weight']:.4f} Kg/m")
+                
+                with history_cols[1]:
+                    st.write("**閫熷害鍙傛暟**")
+                    st.write(f"- 褰撳墠铻烘潌杞��: {record['current_screw_speed']:.1f} rpm")
+                    st.write(f"- 褰撳墠娴佺▼涓婚��: {record['current_process_speed']:.1f} m/min")
+                    st.write(f"- 寤鸿铻烘潌杞��: {record['adjustment_result']['new_screw_speed']:.1f} rpm")
+                    st.write(f"- 寤鸿娴佺▼涓婚��: {record['adjustment_result']['new_process_speed']:.1f} m/min")
+                
+                with history_cols[2]:
+                    st.write("**棰勬祴缁撴灉**")
+                    st.write(f"- 褰撳墠棰勬祴绫抽噸: {record['adjustment_result']['current_predicted_weight']:.4f} Kg/m")
+                    st.write(f"- 浼樺寲鍚庨娴嬬背閲�: {record['adjustment_result']['predicted_weight']:.4f} Kg/m")
+                    st.write(f"- 褰撳墠棰勬祴鍋忓樊: {record['adjustment_result']['current_predicted_deviation_percent']:.2f}%")
+                    st.write(f"- 浼樺寲鍚庨娴嬪亸宸�: {record['adjustment_result']['predicted_deviation_percent']:.2f}%")
+                
+                st.write("**璋冩暣寤鸿**")
+                st.write(record['adjustment_result']['recommendation'])
+    else:
+        st.info("鏆傛棤鍘嗗彶璋冭妭璁板綍")
+    
+    # 7. 甯姪璇存槑
+    with st.expander("鉂� 甯姪璇存槑"):
+        st.markdown("""
+        ### 鍔熻兘璇存槑
+        鏈姛鑳芥ā鍧楀熀浜庡鐩爣浼樺寲绠楁硶锛屾牴鎹綋鍓嶇背閲嶆祴閲忓�煎拰鎸ゅ嚭鏈哄弬鏁帮紝涓虹敤鎴锋彁渚涚瀛﹀悎鐞嗙殑鍙傛暟璋冩暣寤鸿銆�
+        
+        ### 浼樺寲绠楁硶
+        - **绠楁硶绫诲瀷**: 绮掑瓙缇や紭鍖栫畻娉曪紙PSO锛�
+        - **浼樺寲鐩爣**: 
+          1. 鏈�灏忓寲绫抽噸鍋忓樊
+          2. 鏈�灏忓寲鍙傛暟璋冩暣骞呭害
+        - **绾︽潫鏉′欢**: 
+          - 铻烘潌杞�熷拰娴佺▼涓婚�熶笂涓嬮檺
+          - 鍗曟鏈�澶ц皟鏁村箙搴�
+        
+        ### 缁撴灉瑙h
+        - **绫抽噸鐘舵��**: 鏄剧ず浼樺寲鍚庨娴嬬背閲嶆槸鍚﹀湪鍏佽鑼冨洿鍐�
+        - **鍋忓樊淇℃伅**: 褰撳墠绫抽噸涓庢爣鍑嗙背閲嶇殑鍋忓樊
+        - **棰勬祴缁撴灉瀵规瘮**: 褰撳墠鍙傛暟鍜屼紭鍖栧悗鍙傛暟鐨勯娴嬬背閲嶅姣�
+        - **璋冩暣寤鸿**: 璇︾粏鐨勫弬鏁拌皟鏁村缓璁�
+        - **鍙傛暟瀵规瘮**: 鐩磋灞曠ず鍙傛暟璋冩暣骞呭害
+        - **浼樺寲鏁堟灉**: 澶氱洰鏍囦紭鍖栧嚱鏁板�煎姣�
+        
+        ### 娉ㄦ剰浜嬮」
+        1. 璇风‘淇濊緭鍏ョ殑鍙傛暟鍊煎噯纭弽鏄犺澶囧綋鍓嶇姸鎬�
+        2. 浼樺寲寤鸿浠呬緵鍙傝�冿紝瀹為檯鎿嶄綔鏃惰缁撳悎鐜板満缁忛獙
+        3. 寤鸿鍦ㄨ皟鏁村弬鏁板悗瀵嗗垏瑙傚療绫抽噸鍙樺寲
+        4. 瀹氭湡鏇存柊妯″瀷浠ユ彁楂樺缓璁殑鍑嗙‘鎬�
+        """)
+
+# 椤甸潰鍏ュ彛
+if __name__ == "__main__":
+    show_optimized_parameter_adjustment()
\ No newline at end of file
diff --git a/dashboard.py b/dashboard.py
index 77f0e99..d602522 100644
--- a/dashboard.py
+++ b/dashboard.py
@@ -12,6 +12,7 @@
 from app.pages.metered_weight_prediction import show_metered_weight_prediction
 from app.pages.metered_weight_forecast import show_metered_weight_forecast
 from app.pages.extruder_parameter_adjustment import show_extruder_parameter_adjustment
+from app.pages.optimized_parameter_adjustment import show_optimized_parameter_adjustment
 
 # 璁剧疆椤甸潰閰嶇疆
 st.set_page_config(
@@ -112,6 +113,13 @@
     url_path="extruder_parameter_adjustment"
 )
 
+optimized_parameter_adjustment_page = st.Page(
+    show_optimized_parameter_adjustment,
+    title="浼樺寲鐗堟尋鍑烘満鍙傛暟璋冭妭",
+    icon="馃殌",
+    url_path="optimized_parameter_adjustment"
+)
+
 # 渚ц竟鏍忛〉鑴氫俊鎭�
 def show_footer():
     st.sidebar.markdown("---")
@@ -119,7 +127,7 @@
 
 # 瀵艰埅閰嶇疆
 pg = st.navigation({
-    "缁煎悎鍒嗘瀽": [comprehensive_page, metered_weight_page, metered_weight_correlation_page, metered_weight_regression_page, metered_weight_advanced_page, metered_weight_deep_learning_page, metered_weight_steady_state_page, metered_weight_prediction_page, metered_weight_forecast_page, extruder_parameter_adjustment_page],
+    "缁煎悎鍒嗘瀽": [comprehensive_page, metered_weight_page, metered_weight_correlation_page, metered_weight_regression_page, metered_weight_advanced_page, metered_weight_deep_learning_page, metered_weight_steady_state_page, metered_weight_prediction_page, metered_weight_forecast_page, extruder_parameter_adjustment_page, optimized_parameter_adjustment_page],
     "鍒嗛」鍒嗘瀽": [sorting_page, extruder_page, main_process_page]
 })
 

--
Gitblit v1.9.3