基于LSTM深度學習的電動汽車電池荷電狀態(SOC)預測

基于LSTM深度學習的電動汽車電池荷電狀態(SOC)預測

摘要

電動汽車(EV)的普及對電池管理系統(BMS)提出了極高的要求。電池荷電狀態(State of Charge, SOC)作為BMS最核心的參數之一,其精確估算對于提高電池利用率、防止過充過放、保障安全性和延長電池壽命至關重要。由于電池是一個復雜的非線性系統,其SOC受溫度、負載電流、內阻、老化程度等多種因素影響,傳統估算方法如安時積分法和開路電壓法存在累積誤差和實時性差等問題。本文深入探討了基于長短期記憶網絡(LSTM)的深度學習模型在電動汽車電池SOC預測中的應用。文章詳細闡述了SOC預測的挑戰、LSTM模型的原理、數據預處理、特征工程、模型構建、訓練與超參數調優,以及模型評估的完整流程,并提供了完整的Python代碼實現。實驗結果表明,LSTM模型能夠有效捕捉電池數據中的時序動態特性,實現高精度的SOC預測,為下一代智能BMS提供了有效的解決方案。

關鍵詞: 電動汽車;電池管理系統;荷電狀態;SOC預測;深度學習;長短期記憶網絡;LSTM;Python


1. 引言

1.1 研究背景與意義

隨著全球能源危機和環境污染問題日益嚴峻,電動汽車作為替代傳統燃油車的重要解決方案,迎來了飛速發展。動力電池是電動汽車的“心臟”,其性能直接決定了車輛的續航里程、安全性和可靠性。然而,電池是一個復雜的電化學系統,其內部狀態無法直接測量,只能通過外部特性(如電壓、電流、溫度)進行間接估算。

荷電狀態(SOC)定義為當前電池剩余容量與額定容量的百分比,是駕駛者了解剩余續航里程的主要依據,更是BMS進行能量分配、熱管理、均衡控制等功能的基礎。不準確的SOC估算可能導致:

  1. 續航焦慮: 駕駛員無法信任儀表盤顯示的剩余里程。
  2. 電池損傷: 可能導致電池過充或過放,加速電池老化,甚至引發熱失控等安全事故。
  3. 能量效率低下: BMS無法在最佳工作區間調度電池能量。

因此,開發一種高精度、高魯棒性且能適應復雜多變工況的SOC估算方法,具有重大的理論價值和現實意義。

1.2 傳統SOC估算方法及其局限性

  1. 開路電壓法(OCV):電池靜置足夠長時間后,其開路電壓與SOC存在一一對應的關系。該方法簡單且精度較高,但需要電池長時間靜置,在車輛行駛過程中無法使用,通常僅用于校準或車輛啟動時的初始SOC估計。
  2. 安時積分法(Ah-Counting):通過實時積分電流來計算充入或放出的電量。公式為:SOCt=SOC0?1Cn∫0tηi(τ)dτSOC_t = SOC_0 - \frac{1}{C_n} \int_0^t \eta i(\tau) d\tauSOCt?=SOC0??Cn?1?0t?ηi(τ)dτ,其中CnC_nCn?為額定容量,η\etaη為庫倫效率。該方法原理簡單,但嚴重依賴電流傳感器的精度,且存在累積誤差,需要定期用其他方法(如OCV法)進行校正。
  3. 等效電路模型(ECM)濾波法:建立電池的等效電路模型(如Rint、RC、Thevenin模型),結合卡爾曼濾波(KF)、擴展卡爾曼濾波(EKF)或無跡卡爾曼濾波(UKF)等算法進行狀態估計。該方法能有效處理噪聲和累積誤差,但精度高度依賴于所建立的電池模型的準確性。電池模型參數(如內阻、電容)會隨溫度、SOC、老化程度(SOH)而變化,在線辨識這些參數計算復雜,對BMS的算力要求高。

1.3 深度學習方法的優勢

近年來,深度學習在時序數據預測領域取得了巨大成功。基于數據驅動的方法,如LSTM,不需要精確的物理模型,而是通過大量歷史數據自動學習電池的動態特性與SOC之間的復雜非線性映射關系。其優勢在于:

  • 非線性映射能力強:能夠捕捉電壓、電流、溫度等外部測量值與SOC之間復雜的非線性關系。
  • 時序依賴性建模:LSTM天生為處理時序數據而設計,能夠記憶長期的依賴關系,這對于理解電池的弛豫效應和 hysteresis 效應至關重要。
  • 強魯棒性:對測量噪聲有一定的容忍度,且可以通過學習來自動適應不同工況和電池老化程度。
  • 端到端學習:無需復雜的特征工程和參數辨識,直接從原始數據或簡單處理后的數據中學習。

本文將聚焦于使用LSTM這一強大的深度學習模型來解決電動汽車電池SOC的實時預測問題。

2. 理論基礎

2.1 循環神經網絡(RNN)與梯度消失問題

循環神經網絡(RNN)是專門用于處理序列數據的神經網絡。它通過循環單元將之前步的信息傳遞到當前步,理論上可以捕捉任意長度的歷史信息。

其隱藏狀態更新公式為:ht=tanh?(Wxhxt+Whhht?1+bh)h_t = \tanh(W_{xh}x_t + W_{hh}h_{t-1} + b_h)ht?=tanh(Wxh?xt?+Whh?ht?1?+bh?)

然而,傳統的RNN在訓練過程中會遇到著名的梯度消失/爆炸問題。當序列較長時,誤差反向傳播時梯度會指數級地減小或增大,導致網絡無法學習到長距離的依賴關系。這對于需要長期記憶的電池SOC預測來說是致命的缺陷。

2.2 長短期記憶網絡(LSTM)

長短期記憶網絡(LSTM)是RNN的一種特殊變體,由Hochreiter & Schmidhuber于1997年提出,并被廣泛改進和普及。它通過引入精巧的“門控機制”來解決梯度消失問題,從而有效地學習長期依賴關系。

一個LSTM單元的核心是細胞狀態(Cell State) CtC_tCt?,它像一個傳送帶,在整個鏈上運行,只有一些輕微的線性交互,信息很容易不加改變地流過。LSTM通過三個門來精確控制細胞狀態:

  1. 遺忘門(Forget Gate):決定從細胞狀態中丟棄哪些信息。它查看當前輸入xtx_txt?和上一隱藏狀態ht?1h_{t-1}ht?1?,并輸出一個0到1之間的數給細胞狀態Ct?1C_{t-1}Ct?1?。1表示“完全保留”,0表示“完全丟棄”。
    ft=σ(Wf?[ht?1,xt]+bf)f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f)ft?=σ(Wf??[ht?1?,xt?]+bf?)

  2. 輸入門(Input Gate):決定將哪些新信息存入細胞狀態。它包含一個sigmoid層和一個tanh層。sigmoid層決定更新哪些值,tanh層創建一個新的候選值向量C~t\tilde{C}_tC~t?,這些值可能會被加入到細胞狀態中。
    it=σ(Wi?[ht?1,xt]+bi)i_t = \sigma(W_i \cdot [h_{t-1}, x_t] + b_i)it?=σ(Wi??[ht?1?,xt?]+bi?)
    C~t=tanh?(WC?[ht?1,xt]+bC)\tilde{C}_t = \tanh(W_C \cdot [h_{t-1}, x_t] + b_C)C~t?=tanh(WC??[ht?1?,xt?]+bC?)

  3. 更新細胞狀態:將舊的細胞狀態Ct?1C_{t-1}Ct?1?更新為新的細胞狀態CtC_tCt?。我們將舊狀態與ftf_tft?相乘,丟棄掉我們決定忘記的信息。然后加上it?C~ti_t * \tilde{C}_tit??C~t?,這是新的候選值,按我們決定更新的程度來縮放。
    Ct=ft?Ct?1+it?C~tC_t = f_t * C_{t-1} + i_t * \tilde{C}_tCt?=ft??Ct?1?+it??C~t?

  4. 輸出門(Output Gate):基于細胞狀態,決定輸出什么。首先運行一個sigmoid層來決定細胞狀態的哪些部分將輸出。然后,讓細胞狀態通過tanh(將值規范到-1和1之間)并將其與sigm門的輸出相乘,最終得到該單元的隱藏狀態輸出hth_tht?
    ot=σ(Wo?[ht?1,xt]+bo)o_t = \sigma(W_o \cdot [h_{t-1}, x_t] + b_o)ot?=σ(Wo??[ht?1?,xt?]+bo?)
    ht=ot?tanh?(Ct)h_t = o_t * \tanh(C_t)ht?=ot??tanh(Ct?)

這種門控機制使得LSTM能夠有選擇地記住或忘記信息,從而有效地捕獲時間序列中的長期模式,非常適合用于電池SOC的時序預測。

3. 數據準備與預處理

本項目使用NASA Ames預測中心提供的公開電池數據集(Battery Data Set - B0005、B0006、B0007等)。該數據集記錄了18650鋰離子電池在多種溫度、不同工作 profiles(充放電電流變化)下的循環老化實驗數據。測量參數包括電壓、電流、溫度等,并通過專業設備記錄了真實的SOC值作為標簽。

3.1 數據加載與探索性分析(EDA)

首先,我們加載數據并查看其基本結構和統計信息。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout, Input
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
import warnings
warnings.filterwarnings('ignore')# 假設數據已加載到DataFrame `df` 中
# 這里我們用模擬數據的代碼來代替,實際應用中需要從CSV等文件加載
print("Simulating battery data structure...")
# 實際數據列可能包括:cycle, time, voltage, current, temperature, capacity, soc
np.random.seed(42)
time_steps = 1000
simulated_data = {'time': np.arange(time_steps),'voltage_measured': 3.7 + 0.3 * np.sin(np.arange(time_steps)/100) + np.random.normal(0, 0.01, time_steps),'current_measured': np.random.choice([-4, 0, 2], size=time_steps, p=[0.4, 0.2, 0.4]), # 放電為負,充電為正,零為靜置'temperature_measured': 25 + 5 * np.sin(np.arange(time_steps)/200) + np.random.normal(0, 0.2, time_steps),'soc': np.linspace(100, 20, time_steps) + np.random.normal(0, 0.5, time_steps) # 模擬SOC從100%線性下降到20%,帶有噪聲
}
df = pd.DataFrame(simulated_data)
df['soc'] = np.clip(df['soc'], 0, 100) # 確保SOC在0-100之間print("Simulated Data Overview:")
print(df.head())
print("\nData Info:")
print(df.info())
print("\nDescriptive Statistics:")
print(df.describe())# 繪制關鍵參數時序圖
plt.figure(figsize=(12, 10))
plt.subplot(3, 1, 1)
plt.plot(df['time'], df['voltage_measured'], label='Voltage (V)')
plt.ylabel('Voltage (V)')
plt.legend()plt.subplot(3, 1, 2)
plt.plot(df['time'], df['current_measured'], label='Current (A)', color='orange')
plt.ylabel('Current (A)')
plt.legend()plt.subplot(3, 1, 3)
plt.plot(df['time'], df['soc'], label='SOC (%)', color='green')
plt.xlabel('Time')
plt.ylabel('SOC (%)')
plt.legend()
plt.tight_layout()
plt.show()# 繪制相關性熱力圖
plt.figure(figsize=(8, 6))
corr_matrix = df[['voltage_measured', 'current_measured', 'temperature_measured', 'soc']].corr()
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('Feature Correlation Heatmap')
plt.show()

3.2 數據清洗與特征工程

  1. 處理缺失值:檢查并處理數據中的缺失值(NASA數據集通常很完整,但實際數據可能需要插值或刪除)。
  2. 處理異常值:基于領域知識(如電壓超出正常范圍)或統計方法(如3σ原則)識別并處理異常值。
  3. 特征工程
    • 計算差分特征:例如,計算電壓和電流的變化率 dv/dt, di/dt,可以反映電池的動態響應。
    • 滑動窗口統計特征:例如,過去N個時間點的電流均值、方差等。
    • SOC變化量:有時將SOC的絕對值的預測改為SOC變化的預測會更穩定。
    • 時間相關特征:如自循環開始的時間,可能反映老化效應(但本示例暫不涉及老化)。
    • 庫倫計數:雖然安時積分法有缺陷,但其短期變化量作為一個輸入特征可能對模型有幫助。
# 示例:簡單的特征工程
df['current_chg'] = df['current_measured'].diff() # 電流變化率
df['voltage_chg'] = df['voltage_measured'].diff() # 電壓變化率
# 填充第一個值的NaN
df.fillna(method='bfill', inplace=True) # 定義特征和目標變量
features = ['voltage_measured', 'current_measured', 'temperature_measured', 'current_chg', 'voltage_chg']
target = 'soc'X = df[features].values
y = df[target].valuesprint(f"Feature matrix shape: {X.shape}")
print(f"Target vector shape: {y.shape}")

3.3 數據標準化與序列構建

深度學習模型對輸入數據的尺度非常敏感。我們將特征標準化為均值為0,方差為1。目標變量SOC在0-100之間,通常進行歸一化到[0,1]或[-1,1]區間。

最關鍵的一步是構建適用于LSTM的監督學習序列。LSTM的輸入是一個三維數組:[samples, timesteps, features]

  • samples:序列的數量。
  • timesteps:一個序列包含的時間步數(回溯窗口大小)。
  • features:在每個時間步上觀察到的特征數量。

我們使用滑動窗口方法將時間序列數據重構為樣本和對應的標簽。

# 數據標準化
scaler_X = StandardScaler()
scaler_y = MinMaxScaler(feature_range=(0, 1)) # 將SOC縮放到0-1之間X_scaled = scaler_X.fit_transform(X)
y_scaled = scaler_y.fit_transform(y.reshape(-1, 1)).flatten() # Flatten for later use# 定義時間窗口參數
lookback = 50  # 使用過去50個時間步來預測下一個時間步的SOC
forecast = 1   # 預測下一步(也可以預測多步,但SOC預測通常為一步預測)# 構建序列的函數
def create_dataset(X, y, lookback=1, forecast=1):Xs, ys = [], []for i in range(len(X) - lookback - forecast + 1):v = X[i:i+lookback]Xs.append(v)ys.append(y[i+lookback]) # 預測的是第i+lookback個點的SOCreturn np.array(Xs), np.array(ys)# 創建序列
X_seq, y_seq = create_dataset(X_scaled, y_scaled, lookback, forecast)# 檢查形狀
print(f"LSTM Input Shape (samples, timesteps, features): {X_seq.shape}")
print(f"Target Shape: {y_seq.shape}")# 劃分訓練集、驗證集和測試集 (e.g., 70%-15%-15%)
train_size = int(0.7 * len(X_seq))
val_size = int(0.15 * len(X_seq))X_train, X_val, X_test = X_seq[:train_size], X_seq[train_size:train_size+val_size], X_seq[train_size+val_size:]
y_train, y_val, y_test = y_seq[:train_size], y_seq[train_size:train_size+val_size], y_seq[train_size+val_size:]print(f"Train set: X={X_train.shape}, y={y_train.shape}")
print(f"Validation set: X={X_val.shape}, y={y_val.shape}")
print(f"Test set: X={X_test.shape}, y={y_test.shape}")

4. LSTM模型構建與訓練

4.1 模型架構設計

我們將構建一個序列模型。常見的結構是堆疊多個LSTM層,中間加入Dropout層以防止過擬合,最后通過全連接層(Dense)輸出預測值。

# 清除之前的會話,保證模型從頭開始訓練
tf.keras.backend.clear_session()# 定義模型
model = Sequential()
# 第一層LSTM,需要指定input_shape并return_sequences=True以連接下一層LSTM
model.add(Input(shape=(X_train.shape[1], X_train.shape[2]))) # (lookback, n_features)
model.add(LSTM(units=64, return_sequences=True))
model.add(Dropout(0.2)) # 丟棄20%的單元# 第二層LSTM
model.add(LSTM(units=32, return_sequences=False)) # 最后一層LSTM不需要return_sequences
model.add(Dropout(0.2))# 全連接層
model.add(Dense(16, activation='relu'))
model.add(Dense(units=1)) # 輸出層,線性激活,預測一個連續的SOC值# 編譯模型
model.compile(optimizer='adam', loss='mse', metrics=['mae']) # 使用均方誤差損失和平均絕對誤差指標# 顯示模型結構
model.summary()

4.2 模型訓練與超參數調優

我們使用Early Stopping和Learning Rate Reduction回調來防止過擬合并優化訓練過程。

# 定義回調函數
early_stopper = EarlyStopping(monitor='val_loss', patience=15, verbose=1, restore_best_weights=True)
lr_reducer = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, verbose=1, min_lr=1e-6)callbacks = [early_stopper, lr_reducer]# 訓練模型
history = model.fit(X_train, y_train,epochs=100,batch_size=32,validation_data=(X_val, y_val),callbacks=callbacks,verbose=1,shuffle=False # 對于時序數據,通常不打亂順序
)# 繪制訓練歷史
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model Loss')
plt.ylabel('Loss (MSE)')
plt.xlabel('Epoch')
plt.legend()plt.subplot(1, 2, 2)
plt.plot(history.history['mae'], label='Training MAE')
plt.plot(history.history['val_mae'], label='Validation MAE')
plt.title('Model Mean Absolute Error')
plt.ylabel('MAE')
plt.xlabel('Epoch')
plt.legend()
plt.tight_layout()
plt.show()

4.3 模型評估與預測

在測試集上評估模型的最終性能,并使用各種指標來衡量預測精度。

# 在測試集上進行預測
y_pred_scaled = model.predict(X_test)# 將預測值和真實值反標準化/反歸一化回原始尺度
y_pred = scaler_y.inverse_transform(y_pred_scaled).flatten()
# 注意:y_test本身就是歸一化后的,也需要反歸一化
y_test_orig = scaler_y.inverse_transform(y_test.reshape(-1, 1)).flatten()# 計算評估指標
mae = mean_absolute_error(y_test_orig, y_pred)
rmse = np.sqrt(mean_squared_error(y_test_orig, y_pred))
r2 = r2_score(y_test_orig, y_pred)print(f'Test MAE: {mae:.3f}%')
print(f'Test RMSE: {rmse:.3f}%')
print(f'Test R2: {r2:.4f}')# 繪制預測結果與真實值的對比圖
plt.figure(figsize=(12, 6))
plt.plot(y_test_orig, label='True SOC', color='blue', alpha=0.6)
plt.plot(y_pred, label='Predicted SOC', color='red', alpha=0.8, linestyle='--')
plt.title('SOC Prediction on Test Set')
plt.ylabel('SOC (%)')
plt.xlabel('Time Step')
plt.legend()
plt.grid(True)
plt.show()# 繪制誤差分布圖
errors = y_test_orig - y_pred
plt.figure(figsize=(10, 4))
plt.hist(errors, bins=50, edgecolor='black')
plt.title('Distribution of Prediction Errors')
plt.xlabel('Prediction Error (%)')
plt.ylabel('Frequency')
plt.axvline(x=0, color='r', linestyle='--')
plt.show()# 繪制散點圖:真實值 vs 預測值
plt.figure(figsize=(8, 8))
plt.scatter(y_test_orig, y_pred, alpha=0.5)
plt.plot([y_test_orig.min(), y_test_orig.max()], [y_test_orig.min(), y_test_orig.max()], 'r--', lw=2)
plt.xlabel('True SOC (%)')
plt.ylabel('Predicted SOC (%)')
plt.title(f'True vs Predicted SOC (R2 = {r2:.4f})')
plt.grid(True)
plt.show()

5. 高級主題與優化方向

5.1 超參數優化(HPO)

上述模型使用的是手動設置的超參數(如LSTM層數、單元數、lookback、dropout率等)。為了獲得最佳性能,可以使用自動化超參數優化技術:

  • Grid Search / Random Search:在預定義的超參數空間中進行搜索。
  • Bayesian Optimization:更高效的搜索方法,如使用Hyperopt、Optuna或Keras Tuner庫。
# 示例:使用Keras Tuner進行隨機搜索(偽代碼框架)
# import kerastuner as kt
# def build_model(hp):
#     model = Sequential()
#     model.add(Input(shape=(lookback, len(features))))
#     model.add(LSTM(units=hp.Int('units_1', min_value=32, max_value=128, step=32), return_sequences=True))
#     model.add(Dropout(hp.Float('dropout_1', 0.1, 0.5, step=0.1)))
#     ...
#     model.compile(optimizer='adam', loss='mse')
#     return model
#
# tuner = kt.RandomSearch(build_model, objective='val_loss', max_trials=10, executions_per_trial=2)
# tuner.search(X_train, y_train, epochs=50, validation_data=(X_val, y_val), callbacks=[early_stopper])
# best_model = tuner.get_best_models(num_models=1)[0]

5.2 考慮電池老化(SOH)的模型

電池的容量會隨著循環次數的增加而衰減(容量衰減)。這意味著同樣充入/放出的電量,對應的SOC變化會不同。一個更強大的模型應該將電池的健康狀態(State of Health, SOH)或循環次數作為額外輸入特征,使模型能夠自適應老化的影響。

5.3 seq2seq 與多步預測

本文實現的是“單步預測”,即用過去N個點預測下一個點的SOC。在某些應用場景下,可能需要預測未來多個時間步的SOC(多步預測)。這可以通過Seq2Seq架構(編碼器-解碼器)或直接多輸出模型來實現。

5.4 在線學習與模型更新

電池特性會隨時間變化。部署在真實車輛上的模型需要具備在線學習能力,能夠利用新的駕駛數據持續微調模型參數,以適應特定車輛和駕駛員的獨特使用模式以及電池的老化。

5.5 模型輕量化與部署

最終模型需要部署在資源受限的BMC硬件上。因此,需要進行模型剪枝量化等操作來減小模型體積和計算量,以滿足實時性的要求。TensorFlow Lite是完成這項任務的優秀工具。

6. 結論與展望

本文系統地介紹了基于LSTM深度學習模型的電動汽車電池SOC預測方法。通過理論分析、數據預處理、模型構建、訓練評估等一系列步驟,證明了LSTM模型能夠高效地學習電池充放電過程中的復雜非線性時序 dynamics,實現了比傳統方法更精確、更魯棒的SOC估算。

實驗結果表明,該模型在測試集上取得了較低的MAE和RMSE,以及較高的R2分數,預測曲線與真實值高度吻合。LSTM模型成功克服了安時積分法的累積誤差問題,且無需像等效電路模型那樣進行復雜的參數辨識。

展望未來,該領域的研究方向包括:

  1. 多物理量融合:引入更多傳感器數據,如電池內部溫度、阻抗譜等,構建更全面的健康狀態畫像。
  2. 遷移學習:將在實驗室大量數據上訓練好的模型,遷移到個體車輛上,用少量數據快速適配,解決電池個體差異問題。
  3. 不確定性量化:讓模型不僅輸出SOC預測值,還輸出其置信區間,這對于安全攸關的BMS系統至關重要。
  4. 結合物理模型:開發混合模型,將數據驅動的深度學習與基于電化學原理的物理模型相結合,兼具兩者的優勢。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/96758.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/96758.shtml
英文地址,請注明出處:http://en.pswp.cn/web/96758.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Golang語言之數組、切片與子切片

一、數組先記住數組的核心特點:盒子大小一旦定了就改不了(長度固定),但盒子里的東西能換(元素值可變)。就像你買了個能裝 3 個蘋果的鐵皮盒,想多裝 1 個都不行,但里面的蘋果可以換成…

速通ACM省銅第四天 賦源碼(G-C-D, Unlucky!)

目錄 引言: G-C-D, Unlucky! 題意分析 邏輯梳理 代碼實現 結語: 引言: 因為今天打了個ICPC網絡賽,導致坐牢了一下午,沒什么時間打題目了,就打了一道題,所以,今天我們就只講一題了&…

數據鏈路層總結

目錄 (一)以太網(IEEE 802.3) (1)以太網的幀格式 (2)幀協議類型字段 ①ARP協議 (橫跨網絡層和數據鏈路層的協議) ②RARP協議 (二&#xff…

Scala 新手實戰三案例:從循環到條件,搞定基礎編程場景

Scala 新手實戰三案例:從循環到條件,搞定基礎編程場景 對 Scala 新手來說,單純記語法容易 “學完就忘”,而通過小而精的實戰案例鞏固知識點,是掌握語言的關鍵。本文精選三個高頻基礎場景 ——9 乘 9 乘法口訣表、成績等…

java學習筆記----標識符與變量

1.什么是標識符?Java中變量、方法、類等要素命名時使用的字符序列,稱為標識符。 技巧:凡是自己可以起名字的地方都叫標識符。 比如:類名、方法名、變量名、包名、常量名等 2.標識符的命名規則由26個英文字母大小寫,0-9,或$組成 數字不可以開…

AI產品經理面試寶典第93天:Embedding技術選型與場景化應用指南

1. Embedding技術演進全景解析 1.1 稀疏向量:關鍵詞匹配的基石 1.1.1 問:請說明稀疏向量的適用場景及技術特點 答:稀疏向量適用于關鍵詞精確匹配場景,典型實現包括TF-IDF、BM25和SPLADE。其技術特征表現為50,000+高維向量且95%以上位置為零值,通過余弦或點積計算相似度…

【Mermaid.js】從入門到精通:完美處理節點中的空格、括號和特殊字符

文章標簽: Mermaid, Markdown, 前端開發, 數據可視化, 流程圖 文章摘要: 你是否在使用 Mermaid.js 繪制流程圖時,僅僅因為節點文本里加了一個空格或括號,整個圖就渲染失敗了?別擔心,這幾乎是每個 Mermaid 新…

多技術融合提升環境生態水文、土地土壤、農業大氣等領域的數據分析與項目科研水平

一:空間數據獲取與制圖1.1 軟件安裝與應用1.2 空間數據介紹1.3海量空間數據下載1.4 ArcGIS軟件快速入門1.5 Geodatabase地理數據庫二:ArcGIS專題地圖制作2.1專題地圖制作規范2.2 空間數據的準備與處理2.3 空間數據可視化:地圖符號與注記2.4 研…

【音視頻】Android NDK 與.so庫適配

一、名詞解析 名詞全稱核心說明Android NDKNative Development Kit在SDK基礎上增加“原生”開發能力,支持使用C/C編寫代碼,用于開發需要調用底層能力的模塊(如音視頻、加密算法等).so庫Shared Object即共享庫,由NDK編…

SpringBoot 輕量級一站式日志可視化與JVM監控

一、項目初衷Java 應用開發的同學都知道,項目上線后,日志的可視化查詢與 JVM 的可視化監控是一件非常重要的事。 市面上成熟方案一般是采用 ELK/EFK 實現日志可視化,采用 Actuator Prometheus Grafana 實現 JVM 監控。 這兩套都是非常優秀的…

【Leetcode hot 100】101.對稱二叉樹

問題鏈接 101.對稱二叉樹 問題描述 給你一個二叉樹的根節點 root , 檢查它是否軸對稱。 示例 1: 輸入:root [1,2,2,3,4,4,3] 輸出:true 示例 2: 輸入:root [1,2,2,null,3,null,3] 輸出:…

Zynq開發實踐(FPGA之選擇開發板)

【 聲明:版權所有,歡迎轉載,請勿用于商業用途。 聯系信箱:feixiaoxing 163.com】我們之所以選用zynq開發板,就在于它支持arm軟件開發,也支持fpga開發,甚至可以運行linux,這是之前沒有…

Flutter Riverpod 3.0 發布,大規模重構下的全新狀態管理框架

在之前的 《注解模式下的 Riverpod 有什么特別之處》我們聊過 Riverpod 2.x 的設計和使用原理,同時當時我們就聊到作者已經在開始探索 3.0 的重構方式,而現在隨著 Riverpod 3.0 的發布,riverpod 帶來了許多細節性的變化。 當然,這…

Xcode 上傳 ipa 全流程詳解 App Store 上架流程、uni-app 生成 ipa 文件上傳與審核指南

對于 iOS 開發者而言,應用開發完成后最重要的一步就是將應用打包為 ipa 文件,并上傳至 App Store Connect 進行分發或上架。 其中,Xcode 上傳 ipa 是最常見的方法,但很多開發者在實際操作中常常遇到卡住、上傳失敗或簽名錯誤等問題…

快速選中對象

圖片要求 圖片背景單純,對象邊緣比較清晰 對象選擇工具 選擇對象選擇工具后,畫出大致區域,系統將自動分析圖片內容,從而實現快速選擇圖片中的一個惑多個對象他有兩種模式,分別是舉行與套索模式。使用時可以先選中對象的…

點到點鏈路上的OSPF動態路由(2025年9月10日)

一、前言前面我們已經分享過了靜態路由、缺省路由、浮動靜態路由這些靜態路由的配置。接下來將會 陸陸續續開始分享動態路由以及其他路由配置。博主這里是一個新人,了解這些路由配置不是自上而下的,而是自下而上的,也就是說通過實驗去理解原理…

技術視界 | 末端執行器:機器人的“手”,如何賦予機器以生命?

在現代自動化系統中,末端執行器(End Effector)作為機器人與物理世界交互的“手”,發揮著至關重要的作用。它直接安裝在機械臂末端,不僅是機器人實現“抓取、感知和操作”三大核心功能的關鍵部件,更是整個自…

滑動窗口概述

滑動窗口算法簡介滑動窗口是一種用于處理數組或字符串子區間問題的高效算法。它通過維護一個動態窗口(通常由兩個指針表示)來避免重復計算,將時間復雜度從O(n)優化到O(n)。基本實現步驟初始化窗口指針:通常使用left和right指針表示…

AI 創建學生管理系統

使用騰訊元寶創建,整體效果不錯。修正2個bug跑起來,達到了需要的功能先上效果圖:按鈕分類別配色,界面清爽。喜歡這布局創建過程:prompt: 使用最新穩定vue版,使用pinia存儲,基于typescript, 樣式…

ASP.NET Core 中的簡單授權

ASP.NET Core 中的授權通過 [Authorize] 屬性及其各種參數控制。 在其最基本的形式中,通過向控制器、操作或 [Authorize] Page 應用 Razor 屬性,可限制為僅允許經過身份驗證的用戶訪問該組件。 使用 [Authorize] 屬性 以下代碼限制為僅允許經過身份驗證…