2025年电工杯数学建模竞赛 选题分析&解题思路

2025年电工杯数学建模竞赛 选题分析

A题 光伏电站发电功率日前预测问题

A题聚焦光伏电站发电功率的日前预测问题,要求基于历史功率数据和数值天气预报(NWP)信息,建立不同复杂度的预测模型。题目从基础特性分析逐步深入到多因素融合预测,最终探讨气象数据空间降尺度对预测精度的影响。该问题结合了时间序列分析、机器学习、气象学等多学科知识,强调数据驱动建模和预测精度优化。

选题分析

  1. 对时间序列预测和机器学习有扎实基础,熟悉LSTM、XGBoost等算法;
  2. 能够处理多源异构数据(气象数据、功率数据等)的融合与特征工程;

B题 城市垃圾分类运输的路径优化与调度

B题针对城市垃圾分类运输的路径优化问题,从单一车辆类型的基础路径规划,扩展到多车型协同调度,最终结合中转站选址和时间窗口约束形成综合优化模型。题目涉及车辆路径问题(VRP)的多种变体,要求考虑载重约束、时间窗口、碳排放等多目标优化,具有鲜明的运筹学特色。

选题分析

  1. 熟悉组合优化和路径规划算法,如节约算法、遗传算法等;
  2. 能够处理复杂约束条件下的数学建模,擅长线性/整数规划;
  3. 对物流调度或城市管理问题感兴趣,具备空间分析能力;

综合建议:

  • 偏好数据分析和预测建模的团队更适合选择A题,该题侧重算法选择和模型优化。
  • 擅长数学建模和组合优化的团队更适合选择B题,该题侧重约束处理和路径规划。

2025年电工杯数学建模竞赛A题

赛题分析

问题1:基于历史功率的光伏电站发电特性分析

  • 目标:分析光伏电站的长周期(季节性)和短周期(日内)发电特性
  • 关键点:理论可发功率计算、实际与理论功率偏差分析
  • 数据需求:历史发电功率数据、地理位置信息、时间序列数据

问题2:基于历史功率的日前发电功率预测模型

  • 目标:仅使用历史功率数据建立预测模型
  • 关键点:时间序列预测方法选择、模型训练与评估
  • 数据需求:历史发电功率数据

问题3:融入NWP信息的日前发电功率预测模型

  • 目标:结合数值天气预报(NWP)信息提高预测精度
  • 关键点:多变量时间序列预测、NWP信息融合、场景划分
  • 数据需求:历史发电功率数据+NWP数据

问题4:NWP空间降尺度对预测精度的影响

  • 目标:研究更高分辨率气象数据对预测的影响
  • 关键点:空间降尺度方法、精度对比分析
  • 数据需求:不同分辨率的NWP数据

求解思路与模型

问题1求解思路

  1. 理论功率计算:基于地理位置和太阳位置模型计算理论辐照
  2. 季节性分析:按月/季节聚合功率数据,分析趋势
  3. 日内波动分析:按小时分析功率波动模式
  4. 偏差分析:计算实际功率与理论功率的偏差

Python代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pvlib import solarposition, irradiance

# 1. 理论功率计算
def calculate_theoretical_power(lat, lon, times, tilt=30, azimuth=180):
    solpos = solarposition.get_solarposition(times, lat, lon)
    dni_extra = irradiance.get_extra_radiation(times)
    airmass = irradiance.get_relative_airmass(solpos['apparent_zenith'])
    poa_irrad = irradiance.get_total_irradiance(
        tilt, azimuth,
        solpos['apparent_zenith'], solpos['azimuth'],
        dni=1000, ghi=800, dhi=200, dni_extra=dni_extra,
        airmass=airmass)
    return poa_irrad['poa_global']  # 假设与功率成正比

# 2. 季节性分析
def seasonal_analysis(power_data):
    monthly = power_data.resample('M').mean()
    monthly.plot(title='Monthly Average Power')
    plt.show()

# 3. 日内波动分析
def diurnal_analysis(power_data):
    hourly = power_data.groupby(power_data.index.hour).mean()
    hourly.plot(title='Hourly Average Power')
    plt.show()

# 4. 偏差分析
def deviation_analysis(actual, theoretical):
    deviation = actual - theoretical
    deviation.resample('D').mean().plot(title='Daily Deviation')
    plt.show()

MATLAB代码

% 1. 理论功率计算
function theoretical_power = calculate_theoretical_power(lat, lon, times)
    % 使用Solar Position Algorithm计算太阳位置
    [zenith, azimuth] = solarPosition(lat, lon, times);

    % 计算理论辐照度 (简化模型)
    dni = 1000; ghi = 800; dhi = 200;
    tilt = 30; surface_azimuth = 180;
    poa_global = pvl_perez(tilt, surface_azimuth, zenith, azimuth, dni, ghi, dhi);

    theoretical_power = poa_global; % 假设与功率成正比
end

% 2. 季节性分析
function seasonal_analysis(power_data)
    monthly_mean = retime(power_data, 'monthly', 'mean');
    figure;
    plot(monthly_mean.Time, monthly_mean.Power);
    title('Monthly Average Power');
end

% 3. 日内波动分析
function diurnal_analysis(power_data)
    hours = hour(power_data.Time);
    hourly_mean = groupsummary(power_data, hours, 'mean');
    figure;
    plot(hourly_mean.GroupCount, hourly_mean.mean_Power);
    title('Hourly Average Power');
end

问题2求解思路

  1. 数据预处理:处理缺失值、异常值
  2. 特征工程:创建时间特征(小时、日、月等)
  3. 模型选择:LSTM、XGBoost、Prophet等时间序列模型
  4. 模型评估:使用MAE、RMSE等指标评估

Python代码 (LSTM模型)

import tensorflow as tf
from sklearn.preprocessing import MinMaxScaler

def lstm_model(X_train, y_train):
    model = tf.keras.Sequential([
        tf.keras.layers.LSTM(64, input_shape=(X_train.shape[1], X_train.shape[2])),
        tf.keras.layers.Dense(1)
    ])
    model.compile(optimizer='adam', loss='mse')
    history = model.fit(X_train, y_train, epochs=50, batch_size=32, validation_split=0.2)
    return model

def prepare_data(data, n_steps=24*4):  # 24小时(15分钟间隔)
    X, y = [], []
    for i in range(len(data)-n_steps):
        X.append(data[i:i+n_steps])
        y.append(data[i+n_steps])
    return np.array(X), np.array(y)

# 数据预处理
scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(data[['power']].values)
X, y = prepare_data(scaled_data)
X = X.reshape((X.shape[0], X.shape[1], 1))

# 划分训练测试集
split = int(0.8 * len(X))
X_train, X_test = X[:split], X[split:]
y_train, y_test = y[:split], y[split:]

# 训练模型
model = lstm_model(X_train, y_train)

MATLAB代码 (LSTM模型)

% 准备LSTM网络
numFeatures = 1;
numHiddenUnits = 64;
layers = [ ...
    sequenceInputLayer(numFeatures)
    lstmLayer(numHiddenUnits)
    fullyConnectedLayer(1)
    regressionLayer];

options = trainingOptions('adam', ...
    'MaxEpochs',50, ...
    'MiniBatchSize',32, ...
    'ValidationData',{XVal,YVal}, ...
    'Plots','training-progress');

% 训练网络
net = trainNetwork(XTrain,YTrain,layers,options);

% 预测
YPred = predict(net,XTest);

问题3求解思路

  1. 数据融合:将NWP数据与历史功率数据对齐
  2. 特征选择:选择相关性高的气象特征
  3. 多变量模型:构建考虑NWP的预测模型
  4. 场景划分:按季节/天气类型划分场景分别建模

Python代码 (XGBoost模型)

import xgboost as xgb
from sklearn.model_selection import train_test_split

def prepare_nwp_data(power_data, nwp_data):
    # 对齐时间戳并合并数据
    merged = power_data.join(nwp_data, how='inner')
    # 创建时间特征
    merged['hour'] = merged.index.hour
    merged['month'] = merged.index.month
    return merged

# 准备数据
features = prepare_nwp_data(power_data, nwp_data)
X = features.drop('power', axis=1)
y = features['power']

# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

# 训练XGBoost模型
model = xgb.XGBRegressor(n_estimators=100, learning_rate=0.1)
model.fit(X_train, y_train)

# 场景划分 (按季节)
seasons = features.index.month%12 // 3 + 1
for season in range(1,5):
    season_data = features[seasons == season]
    # 为每个季节训练单独模型...

MATLAB代码 (随机森林模型)

% 准备数据
features = prepareNWPData(powerData, nwpData);
X = features(:, 1:end-1);
Y = features(:, end);

% 训练随机森林模型
mdl = TreeBagger(100, X, Y, 'Method', 'regression');

% 场景划分 (按天气类型)
clearWeather = features.CloudCover < 0.3;
cloudyWeather = (features.CloudCover >= 0.3) & (features.CloudCover < 0.7);
overcastWeather = features.CloudCover >= 0.7;

% 为每种天气训练单独模型
mdlClear = TreeBagger(100, X(clearWeather,:), Y(clearWeather));
mdlCloudy = TreeBagger(100, X(cloudyWeather,:), Y(cloudyWeather));
mdlOvercast = TreeBagger(100, X(overcastWeather,:), Y(overcastWeather));

问题4求解思路

  1. 空间降尺度方法
    • 机器学习方法:使用高分辨率地理数据训练降尺度模型
    • 空间插值:Kriging、IDW等
  2. 精度对比:比较降尺度前后NWP数据的预测精度
  3. 原因分析:分析降尺度对局部气象特征的捕捉能力

Python代码 (Kriging降尺度)

from pykrige.ok import OrdinaryKriging
from sklearn.metrics import mean_squared_error

def kriging_downscale(coarse_data, fine_locs):
    # coarse_data: 粗分辨率NWP数据
    # fine_locs: 细分辨率位置坐标

    # 准备Kriging模型
    OK = OrdinaryKriging(
        coarse_data.lon, coarse_data.lat, coarse_data.value,
        variogram_model='linear'
    )

    # 在细分辨率位置插值
    fine_values, _ = OK.execute('points', fine_locs.lon, fine_locs.lat)
    return fine_values

# 比较预测精度
def compare_accuracy(coarse_pred, fine_pred, actual):
    coarse_rmse = mean_squared_error(actual, coarse_pred, squared=False)
    fine_rmse = mean_squared_error(actual, fine_pred, squared=False)
    print(f"Coarse RMSE: {coarse_rmse}, Fine RMSE: {fine_rmse}")
    return fine_rmse - coarse_rmse

MATLAB代码 (IDW降尺度)

% 反距离加权插值
function fineData = idw_downscale(coarseLon, coarseLat, coarseData, fineLon, fineLat)
    F = scatteredInterpolant(coarseLon, coarseLat, coarseData, 'natural');
    fineData = F(fineLon, fineLat);
end

% 比较预测精度
function rmseDiff = compare_accuracy(coarsePred, finePred, actual)
    coarseRMSE = sqrt(mean((actual - coarsePred).^2));
    fineRMSE = sqrt(mean((actual - finePred).^2));
    rmseDiff = fineRMSE - coarseRMSE;
end

模型建议

  1. 基础模型
    • 时间序列模型:LSTM、GRU、TCN
    • 传统机器学习:XGBoost、随机森林、SVR
  2. 进阶模型
    • 多任务学习:同时预测多个时间点
    • 注意力机制:Transformer模型
    • 混合模型:LSTM+CNN组合
  3. 集成方法
    • 模型堆叠:基础模型预测作为新特征输入到元模型
    • 加权平均:不同模型预测结果的加权组合
  4. 误差修正
    • 残差模型:对基础模型预测的误差进行建模
    • 后处理方法:基于历史误差分布的校正

2025年电工杯数学建模竞赛B题

赛题分析

问题1:单一车辆类型下的基础路径优化与调度

  • 目标:最小化每日总行驶距离
  • 约束:车辆载重限制、单一起止点、允许分批运输
  • 特点:经典车辆路径问题(VRP)变种,单车型单类型垃圾

问题2:多车辆协同与载重约束下的优化

  • 目标:最小化每日总运输成本
  • 约束:多车型(4类)、多垃圾类型、各自载重/容积限制
  • 特点:多车型车辆路径问题(MDVRP)变种,考虑不同类型垃圾

问题3:含中转站选址与时间窗口的综合优化

  • 目标:最小化运输成本与中转站建设成本之和
  • 约束:中转站容量、时间窗口、碳排放限制、非对称路网
  • 特点:选址-路径问题(LRP)与绿色车辆路径问题(GVRP)结合

求解思路与模型

问题1求解思路

  1. 模型建立:转化为带容量约束的车辆路径问题(CVRP)
  2. 算法选择:节约算法(Clarke-Wright)或遗传算法
  3. 求解步骤
    • 计算所有点间距离矩阵
    • 构建初始解(每点单独往返)
    • 合并路径满足容量约束
  4. 复杂度分析:O(n²)~O(n³)取决于具体实现

Python代码

import numpy as np
from scipy.spatial import distance_matrix

def solve_vrp(points, demands, capacity):
    """使用节约算法求解CVRP"""
    n = len(points)
    dist = distance_matrix(points, points)

    # 初始解:每点单独往返
    routes = [[0, i, 0] for i in range(1, n+1)]
    savings = []

    # 计算所有节约值
    for i in range(1, n+1):
        for j in range(i+1, n+1):
            sav = dist[0,i] + dist[0,j] - dist[i,j]
            savings.append((sav, i, j))

    # 按节约值降序排序
    savings.sort(reverse=True, key=lambda x: x[0])

    # 合并路径
    for sav, i, j in savings:
        route_i = find_route(routes, i)
        route_j = find_route(routes, j)

        if route_i != route_j and sum(demands[k-1] for k in route_i) + sum(demands[k-1] for k in route_j) <= capacity:
            # 合并两条路径
            new_route = merge_routes(route_i, route_j, i, j)
            routes.remove(route_i)
            routes.remove(route_j)
            routes.append(new_route)

    return routes

def find_route(routes, node):
    """找到包含指定节点的路径"""
    for route in routes:
        if node in route:
            return route
    return None

MATLAB代码

function routes = solve_vrp(points, demands, capacity)
    % 使用节约算法求解CVRP
    n = size(points, 1);
    dist = pdist2(points, points);

    % 初始解:每点单独往返
    routes = cell(n,1);
    for i = 1:n
        routes{i} = [1, i+1, 1]; % 假设1是处理厂
    end

    % 计算节约值
    savings = [];
    for i = 1:n
        for j = i+1:n
            sav = dist(1,i+1) + dist(1,j+1) - dist(i+1,j+1);
            savings = [savings; sav, i, j];
        end
    end

    % 按节约值降序排序
    savings = sortrows(savings, -1);

    % 合并路径
    for k = 1:size(savings,1)
        sav = savings(k,1);
        i = savings(k,2);
        j = savings(k,3);

        route_i = find_route(routes, i);
        route_j = find_route(routes, j);

        if ~isequal(route_i, route_j) && sum(demands(route_i(2:end-1)-1)) + sum(demands(route_j(2:end-1)-1)) <= capacity
            % 合并两条路径
            new_route = merge_routes(route_i, route_j, i, j);
            routes = [routes; {new_route}];
            routes(find_route_index(routes, route_i)) = [];
            routes(find_route_index(routes, route_j)) = [];
        end
    end
end

问题2求解思路

  1. 模型建立:多车型车辆路径问题(MDVRP)
  2. 算法扩展:将问题1算法按垃圾类型分解
  3. 求解步骤
    • 按垃圾类型分组收集点
    • 对每种类型独立求解VRP
    • 考虑车辆类型特定约束(载重、容积、成本)
  4. 时间约束处理:添加路径时间计算和约束

Python代码

def solve_mdvrp(points, demands, vehicle_specs):
    """多车型车辆路径问题求解"""
    solutions = {}

    for k, spec in vehicle_specs.items():
        # 筛选当前类型垃圾需求>0的点
        mask = demands[:,k] > 0
        sub_points = points[mask]
        sub_demands = demands[mask, k]

        # 调用VRP求解器
        solutions[k] = solve_vrp(sub_points, sub_demands, spec['Q'])

    return solutions

def add_time_constraint(routes, speed=40, max_hours=12):
    """添加时间约束验证"""
    valid_routes = []
    total_distance = 0

    for route in routes:
        route_dist = calculate_route_distance(route)
        route_time = route_dist / speed

        if route_time <= max_hours:
            valid_routes.append(route)
            total_distance += route_dist
        else:
            # 需要拆分路径
            split_routes = split_route(route, speed, max_hours)
            valid_routes.extend(split_routes)

    return valid_routes

MATLAB代码

function solutions = solve_mdvrp(points, demands, vehicle_specs)
    % 多车型车辆路径问题求解
    solutions = struct();

    for k = 1:length(vehicle_specs)
        % 筛选当前类型垃圾需求>0的点
        mask = demands(:,k) > 0;
        sub_points = points(mask,:);
        sub_demands = demands(mask,k);

        % 调用VRP求解器
        solutions(k).routes = solve_vrp(sub_points, sub_demands, vehicle_specs(k).Q);
    end
end

function valid_routes = add_time_constraint(routes, speed, max_hours)
    % 添加时间约束验证
    valid_routes = {};

    for i = 1:length(routes)
        route = routes{i};
        route_dist = calculate_route_distance(route);
        route_time = route_dist / speed;

        if route_time <= max_hours
            valid_routes{end+1} = route;
        else
            % 需要拆分路径
            split_routes = split_route(route, speed, max_hours);
            valid_routes = [valid_routes, split_routes];
        end
    end
end

问题3求解思路

  1. 两阶段模型
    • 阶段1:中转站选址(设施选址问题)
    • 阶段2:带时间窗的车辆路径问题(VRPTW)
  2. 算法设计
    • 阶段1:使用聚类或整数规划确定选址
    • 阶段2:改进的遗传算法或禁忌搜索
  3. 非对称处理:构建有向图距离矩阵

Python代码

def two_phase_solver(points, demands, candidates, vehicle_specs):
    """两阶段求解器"""
    # 阶段1:中转站选址
    selected_stations = select_stations(points, candidates)

    # 分配收集点到最近中转站
    allocations = allocate_points(points, selected_stations)

    # 阶段2:路径优化
    solutions = {}
    for station in selected_stations:
        station_points = points[allocations == station]
        station_demands = demands[allocations == station]

        for k, spec in vehicle_specs.items():
            mask = station_demands[:,k] > 0
            sub_points = station_points[mask]
            sub_demands = station_demands[mask, k]

            solutions[(station, k)] = solve_vrptw(sub_points, sub_demands, spec)

    return solutions

def solve_vrptw(points, demands, vehicle_spec):
    """带时间窗的车辆路径问题求解"""
    # 实现基于遗传算法的VRPTW求解
    pass

MATLAB代码

function solutions = two_phase_solver(points, demands, candidates, vehicle_specs)
    % 两阶段求解器
    % 阶段1:中转站选址
    selected_stations = select_stations(points, candidates);

    % 分配收集点到最近中转站
    allocations = allocate_points(points, selected_stations);

    % 阶段2:路径优化
    solutions = struct();

    for s = 1:length(selected_stations)
        station = selected_stations(s);
        mask = allocations == station;
        station_points = points(mask,:);
        station_demands = demands(mask,:);

        for k = 1:length(vehicle_specs)
            type_mask = station_demands(:,k) > 0;
            sub_points = station_points(type_mask,:);
            sub_demands = station_demands(type_mask,k);

            solutions(s,k).routes = solve_vrptw(sub_points, sub_demands, vehicle_specs(k));
        end
    end
end

模型建议

  1. 基础模型
    • 节约算法(Clarke-Wright):适合小规模问题,实现简单
    • 最近邻法:快速构建初始解
    • 扫描算法:适合有空间聚集性的问题
  2. 进阶模型
    • 遗传算法:适合中大规模问题,可处理复杂约束
    • 禁忌搜索:避免局部最优,适合VRPTW变种
    • 蚁群算法:适合路径优化,可并行化
  3. 精确算法
    • 分支定价:适合小规模精确求解
    • 动态规划:适合点数量有限的情况
  4. 混合策略
    • 先聚类再路径优化:适合含中转站的问题
    • 多阶段启发式:分解复杂问题为多个子问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值