配电网重构优化:以减小网损为目标的智能算法实现
解决以减小网损为目标的配电网重构问题。采用改进的二进制粒子群算法(BPSO)结合前推回代潮流计算,实现网损最小化重构优化。
matlab
% 配电网重构优化:以减小网损为目标
clear; close all; clc;
%% ====================== 系统参数设置 ======================
% IEEE 33节点配电系统参数
[busdata, branchdata] = ieee33bus();
baseMVA = 10; % 基准功率(MVA)
baseV = 12.66; % 基准电压(kV)
% 转换为标幺值
busdata(:, [4,5]) = busdata(:, [4,5]) / baseMVA; % 负荷功率
branchdata(:, [3,4]) = branchdata(:, [3,4]) / baseV^2 * baseMVA; % 阻抗标幺化
% 网络拓扑参数
nbus = size(busdata, 1); % 节点数
nbranch = size(branchdata, 1); % 支路数
nsw = 5; % 可操作开关数量
% 可操作开关位置 (IEEE 33节点系统的联络开关)
switch_branches = [33, 34, 35, 36, 37]; % 对应支路编号
initial_state = [0, 0, 0, 0, 1]; % 初始状态(0=开,1=合)
% 算法参数
max_iter = 100; % 最大迭代次数
pop_size = 50; % 种群大小
w = 0.729; % 惯性权重
c1 = 1.494; % 个体学习因子
c2 = 1.494; % 社会学习因子
v_max = 6; % 最大速度
repair_prob = 0.8; % 拓扑修复概率
fprintf('配电网重构优化系统\n');
fprintf('系统: IEEE 33节点\n');
fprintf('节点数: %d, 支路数: %d, 可操作开关: %d\n', nbus, nbranch, nsw);
fprintf('优化目标: 最小化有功网损\n\n');
%% ====================== 初始化种群 ======================
% 初始化粒子位置(开关状态)和速度
pop = zeros(pop_size, nsw); % 粒子位置(0或1)
velocity = zeros(pop_size, nsw); % 粒子速度
% 生成初始种群(保证辐射状拓扑)
for i = 1:pop_size
valid = false;
while ~valid
% 随机生成开关状态
pop(i, :) = randi([0,1], 1, nsw);
% 确保与初始状态不同
if isequal(pop(i, :), initial_state)
continue;
end
% 检查拓扑有效性
valid = check_topology(branchdata, switch_branches, pop(i, :));
end
% 初始化速度
velocity(i, :) = -v_max + 2*v_max*rand(1, nsw);
end
% 初始化个体最优
pbest = pop; % 个体最佳位置
pbest_loss = inf(1, pop_size); % 个体最佳网损
% 初始化全局最优
gbest = zeros(1, nsw); % 全局最佳位置
gbest_loss = inf; % 全局最佳网损
% 存储迭代过程
best_loss_iter = zeros(1, max_iter); % 每次迭代的最佳网损
avg_loss_iter = zeros(1, max_iter); % 每次迭代的平均网损
%% ====================== BPSO优化主循环 ======================
for iter = 1:max_iter
% 计算每个粒子的适应度(网损)
current_loss = zeros(1, pop_size);
for i = 1:pop_size
% 应用开关状态
temp_branch = update_branch_state(branchdata, switch_branches, pop(i, :));
% 检查拓扑连通性
if ~is_radial(temp_branch)
% 如果不满足辐射状,进行拓扑修复
if rand < repair_prob
pop(i, :) = repair_topology(temp_branch, switch_branches, initial_state);
temp_branch = update_branch_state(branchdata, switch_branches, pop(i, :));
else
current_loss(i) = inf; % 无效解
continue;
end
end
% 计算潮流和网损
[loss, ~] = forward_backward_sweep(busdata, temp_branch);
current_loss(i) = loss * baseMVA; % 转换为实际功率(kW)
end
% 更新个体最优
update_idx = current_loss < pbest_loss;
pbest(update_idx, :) = pop(update_idx, :);
pbest_loss(update_idx) = current_loss(update_idx);
% 更新全局最优
[min_loss, min_idx] = min(current_loss);
if min_loss < gbest_loss
gbest_loss = min_loss;
gbest = pop(min_idx, :);
end
% 存储迭代数据
best_loss_iter(iter) = gbest_loss;
avg_loss_iter(iter) = mean(current_loss(current_loss < inf));
% 显示迭代信息
fprintf('迭代 %3d: 最佳网损 = %.4f kW, 平均网损 = %.4f kW\n', ...
iter, gbest_loss, avg_loss_iter(iter));
% 更新粒子速度和位置
for i = 1:pop_size
% 更新速度
velocity(i, :) = w*velocity(i, :) + ...
c1*rand(1, nsw).*(pbest(i, :) - pop(i, :)) + ...
c2*rand(1, nsw).*(gbest - pop(i, :));
% 速度限制
velocity(i, :) = min(max(velocity(i, :), -v_max), v_max);
% 更新位置(使用sigmoid函数)
sigmoid_v = 1./(1 + exp(-velocity(i, :)));
pop(i, :) = rand(1, nsw) < sigmoid_v;
end
% 增加多样性机制(每10次迭代)
if mod(iter, 10) == 0
for i = 1:pop_size/5
idx = randi(pop_size);
pop(idx, :) = create_valid_solution(branchdata, switch_branches, initial_state);
end
end
end
%% ====================== 结果分析与可视化 ======================
% 应用最佳解
opt_branch = update_branch_state(branchdata, switch_branches, gbest);
% 计算初始网损
init_branch = update_branch_state(branchdata, switch_branches, initial_state);
[init_loss, init_voltage] = forward_backward_sweep(busdata, init_branch);
init_loss = init_loss * baseMVA; % kW
% 计算优化后网损
[opt_loss, opt_voltage] = forward_backward_sweep(busdata, opt_branch);
opt_loss = opt_loss * baseMVA; % kW
% 计算网损降低率
loss_reduction = (init_loss - opt_loss) / init_loss * 100;
% 显示最终结果
fprintf('\n优化完成!\n');
fprintf('初始网损: %.4f kW\n', init_loss);
fprintf('优化后网损: %.4f kW\n', opt_loss);
fprintf('网损降低率: %.2f%%\n', loss_reduction);
fprintf('最佳开关状态: ');
fprintf('%d ', gbest);
fprintf('\n');
% 可视化结果
figure('Position', [100, 100, 1200, 800]);
% 1. 网损收敛曲线
subplot(2,2,1);
plot(1:max_iter, best_loss_iter, 'b-', 'LineWidth', 2);
hold on;
plot(1:max_iter, avg_loss_iter, 'r--', 'LineWidth', 1.5);
xlabel('迭代次数');
ylabel('网损 (kW)');
title('网损收敛曲线');
legend('最佳网损', '平均网损', 'Location', 'best');
grid on;
% 2. 电压分布比较
subplot(2,2,2);
plot(1:nbus, init_voltage, 'ro-', 'LineWidth', 1.5);
hold on;
plot(1:nbus, opt_voltage, 'bs-', 'LineWidth', 1.5);
xlabel('节点编号');
ylabel('电压幅值 (p.u.)');
title('重构前后电压分布');
legend('初始', '优化后', 'Location', 'best');
yline(0.95, 'k--', 'LineWidth', 1.5); % 电压下限
yline(1.05, 'k--', 'LineWidth', 1.5); % 电压上限
grid on;
% 3. 网损分布
subplot(2,2,3);
[~, loss_branch] = forward_backward_sweep(busdata, init_branch);
bar(1:nbranch, loss_branch * baseMVA, 'r');
xlabel('支路编号');
ylabel('支路损耗 (kW)');
title('初始网损分布');
grid on;
subplot(2,2,4);
[~, loss_branch] = forward_backward_sweep(busdata, opt_branch);
bar(1:nbranch, loss_branch * baseMVA, 'b');
xlabel('支路编号');
ylabel('支路损耗 (kW)');
title('优化后网损分布');
grid on;
% 显示拓扑变化
figure('Position', [100, 100, 800, 600]);
plot_topology(busdata, init_branch, '初始拓扑');
figure('Position', [100, 100, 800, 600]);
plot_topology(busdata, opt_branch, '优化后拓扑');
%% ====================== 函数定义 ======================
% IEEE 33节点系统数据
function [busdata, branchdata] = ieee33bus()
% 节点数据 [节点编号, 类型(1=平衡节点, 0=PQ), Pd(MW), Qd(Mvar)]
busdata = [
1 1 0.0 0.0;
2 0 0.1 0.06;
3 0 0.09 0.04;
4 0 0.12 0.08;
5 0 0.06 0.03;
6 0 0.06 0.02;
7 0 0.2 0.1;
8 0 0.2 0.1;
9 0 0.06 0.02;
10 0 0.06 0.02;
11 0 0.045 0.03;
12 0 0.06 0.035;
13 0 0.06 0.035;
14 0 0.12 0.08;
15 0 0.06 0.01;
16 0 0.06 0.02;
17 0 0.06 0.02;
18 0 0.09 0.04;
19 0 0.09 0.04;
20 0 0.09 0.04;
21 0 0.09 0.04;
22 0 0.09 0.04;
23 0 0.09 0.05;
24 0 0.42 0.2;
25 0 0.42 0.2;
26 0 0.06 0.025;
27 0 0.06 0.025;
28 0 0.06 0.02;
29 0 0.12 0.07;
30 0 0.2 0.6;
31 0 1.5 1.07;
32 0 0.17 0.1;
33 0 0.21 0.1;
];
% 支路数据 [起始节点, 终止节点, R(Ω), X(Ω), 初始状态(1=闭合,0=断开)]
branchdata = [
1 2 0.0922 0.0470 1;
2 3 0.4930 0.2510 1;
3 4 0.3660 0.1864 1;
4 5 0.3811 0.1941 1;
5 6 0.8190 0.7070 1;
6 7 0.1872 0.6188 1;
7 8 0.7114 0.2351 1;
8 9 1.0300 0.7400 1;
9 10 1.0440 0.7400 1;
10 11 0.1966 0.0650 1;
11 12 0.3744 0.1238 1;
12 13 1.4680 1.1550 1;
13 14 0.5416 0.7129 1;
14 15 0.5910 0.5260 1;
15 16 0.7463 0.5450 1;
16 17 1.2890 1.7210 1;
17 18 0.7320 0.5740 1;
2 19 0.1640 0.1565 1;
19 20 1.5042 1.3554 1;
20 21 0.4095 0.4784 1;
21 22 0.7089 0.9373 1;
3 23 0.4512 0.3083 1;
23 24 0.8980 0.7091 1;
24 25 0.8960 0.7011 1;
6 26 0.2030 0.1034 1;
26 27 0.2842 0.1447 1;
27 28 1.0590 0.9337 1;
28 29 0.8042 0.7006 1;
29 30 0.5075 0.2585 1;
30 31 0.9744 0.9630 1;
31 32 0.3105 0.3619 1;
32 33 0.3410 0.5302 1;
% 联络开关 (初始断开)
8 14 0.5 0.5 0;
9 15 0.5 0.5 0;
12 22 0.5 0.5 0;
18 33 0.5 0.5 0;
25 29 0.5 0.5 0;
];
end
% 更新支路状态
function new_branch = update_branch_state(branch, switch_idx, state)
new_branch = branch;
for i = 1:length(switch_idx)
new_branch(switch_idx(i), 5) = state(i);
end
end
% 检查拓扑是否辐射状
function radial = is_radial(branch)
nbus = max(max(branch(:,1:2)));
nbranch = size(branch, 1);
% 构建邻接矩阵
active_branches = branch(branch(:,5) == 1, 1:2);
% 构建连通图
G = graph(active_branches(:,1), active_branches(:,2));
% 检查连通分量
bins = conncomp(G);
% 检查是否树状结构(节点数 = 边数 + 1)
if max(bins) > 1
radial = false; % 存在孤岛
return;
end
if numel(unique(bins)) == 1 && (nbus == size(active_branches, 1) + 1)
radial = true;
else
radial = false;
end
end
% 拓扑修复函数
function new_state = repair_topology(branch, switch_idx, initial_state)
% 简单策略:关闭所有联络开关然后逐个打开
new_state = ones(size(initial_state)); % 关闭所有联络开关
% 计算初始网损
temp_branch = update_branch_state(branch, switch_idx, new_state);
min_loss = forward_backward_sweep([], temp_branch);
% 尝试逐个打开开关
for i = 1:length(switch_idx)
test_state = new_state;
test_state(i) = 0; % 打开一个开关
temp_branch = update_branch_state(branch, switch_idx, test_state);
if is_radial(temp_branch)
loss = forward_backward_sweep([], temp_branch);
if loss < min_loss
new_state = test_state;
min_loss = loss;
end
end
end
end
% 创建有效解
function state = create_valid_solution(branch, switch_idx, initial_state)
valid = false;
while ~valid
state = randi([0,1], 1, length(switch_idx));
if isequal(state, initial_state)
continue;
end
temp_branch = update_branch_state(branch, switch_idx, state);
valid = is_radial(temp_branch);
end
end
% 前推回代潮流计算
function [total_loss, loss_branch, V] = forward_backward_sweep(busdata, branchdata)
% 参数设置
max_iter = 50; % 最大迭代次数
tol = 1e-5; % 收敛容差
% 节点数
nbus = max(max(branchdata(:,1:2)));
% 提取活动支路
active_branches = branchdata(branchdata(:,5) == 1, :);
nbranch_active = size(active_branches, 1);
% 构建节点-支路关联矩阵
A = zeros(nbus, nbranch_active);
root_node = 1; % 平衡节点
% 创建树结构
parent = zeros(1, nbus);
children = cell(1, nbus);
level = zeros(1, nbus);
level(root_node) = 1;
% 构建树结构
for i = 1:nbranch_active
from = active_branches(i, 1);
to = active_branches(i, 2);
if level(from) > 0 && level(to) == 0
parent(to) = from;
children{from} = [children{from}, to];
level(to) = level(from) + 1;
elseif level(to) > 0 && level(from) == 0
parent(from) = to;
children{to} = [children{to}, from];
level(from) = level(to) + 1;
end
end
% 初始化电压
V = ones(nbus, 1);
V(root_node) = 1.0; % 平衡节点电压
% 初始化负荷
Pd = zeros(nbus, 1);
Qd = zeros(nbus, 1);
for i = 1:size(busdata, 1)
node = busdata(i, 1);
Pd(node) = busdata(i, 3);
Qd(node) = busdata(i, 4);
end
% 初始化支路电流和功率
I_branch = zeros(nbranch_active, 1);
P_branch = zeros(nbranch_active, 1);
Q_branch = zeros(nbranch_active, 1);
% 前推回代迭代
for iter = 1:max_iter
% ===== 回代过程 (从叶节点向根节点) =====
% 初始化节点注入功率
P_inj = -Pd; % 负荷消耗功率
Q_inj = -Qd;
% 按节点层级降序处理
[~, order] = sort(level, 'descend');
for i = 1:nbus
node = order(i);
if node == root_node
continue;
end
% 找到连接该节点的支路
branch_idx = find((active_branches(:,1) == parent(node) & ...
(active_branches(:,2) == node) | ...
(active_branches(:,2) == parent(node) & ...
(active_branches(:,1) == node));
% 累加子节点功率
for child = children{node}
P_inj(node) = P_inj(node) + P_branch(find(active_branches(:,1)==node & active_branches(:,2)==child | ...
active_branches(:,2)==node & active_branches(:,1)==child));
Q_inj(node) = Q_inj(node) + Q_branch(find(active_branches(:,1)==node & active_branches(:,2)==child | ...
active_branches(:,2)==node & active_branches(:,1)==child));
end
% 计算支路功率
R = active_branches(branch_idx, 3);
X = active_branches(branch_idx, 4);
P_branch(branch_idx) = P_inj(node) + R * (P_branch(branch_idx)^2 + Q_branch(branch_idx)^2) / V(node)^2;
Q_branch(branch_idx) = Q_inj(node) + X * (P_branch(branch_idx)^2 + Q_branch(branch_idx)^2) / V(node)^2;
end
% ===== 前推过程 (从根节点向叶节点) =====
% 按节点层级升序处理
[~, order] = sort(level);
for i = 1:nbus
node = order(i);
if node == root_node
continue;
end
% 获取父节点电压
parent_node = parent(node);
V_parent = V(parent_node);
% 找到连接该节点的支路
branch_idx = find((active_branches(:,1) == parent_node & ...
(active_branches(:,2) == node) | ...
(active_branches(:,2) == parent_node & ...
(active_branches(:,1) == node));
R = active_branches(branch_idx, 3);
X = active_branches(branch_idx, 4);
P = P_branch(branch_idx);
Q = Q_branch(branch_idx);
% 计算节点电压
V(node) = sqrt((V_parent^2 - 2*(R*P + X*Q)) + (R^2 + X^2)*(P^2 + Q^2)/V_parent^2);
end
% 检查收敛
if iter > 1
max_dV = max(abs(V - V_prev));
if max_dV < tol
break;
end
end
V_prev = V;
end
% 计算支路损耗
loss_branch = zeros(nbranch_active, 1);
for i = 1:nbranch_active
R = active_branches(i, 3);
loss_branch(i) = R * (P_branch(i)^2 + Q_branch(i)^2) / V(active_branches(i,2))^2;
end
total_loss = sum(loss_branch);
end
% 拓扑可视化
function plot_topology(busdata, branchdata, title_str)
% 提取活动支路
active_branches = branchdata(branchdata(:,5) == 1, :);
% 创建图对象
G = graph(active_branches(:,1), active_branches(:,2));
% 绘制拓扑
h = plot(G, 'Layout', 'force', 'UseGravity', true);
% 标记平衡节点
highlight(h, 1, 'NodeColor', 'r', 'MarkerSize', 8);
% 标记联络开关
tie_branches = branchdata(branchdata(:,5) == 0, :);
for i = 1:size(tie_branches, 1)
from = tie_branches(i, 1);
to = tie_branches(i, 2);
highlight(h, [from, to], 'EdgeColor', 'm', 'LineWidth', 2, 'LineStyle', '--');
end
% 设置标题
title(title_str);
set(gca, 'FontSize', 12);
grid on;
end
算法原理与实现
1. 问题建模
配电网重构问题可以表述为:
minf=Ploss(x)=∑k=1NbIk2Rk\min f = P_{loss}(x) = \sum_{k=1}^{N_b} I_k^2 R_kminf=Ploss(x)=k=1∑NbIk2Rk
约束条件:
- 辐射状拓扑约束
- 连通性约束
- 电压约束:Vmin≤Vi≤VmaxV_{min} \leq V_i \leq V_{max}Vmin≤Vi≤Vmax
- 功率平衡约束
其中xxx表示开关状态向量,NbN_bNb为支路数量。
2. 改进二进制粒子群算法(BPSO)
本程序采用改进的BPSO算法解决重构问题:
创新点
-
拓扑修复机制:
- 当粒子位置导致非辐射状拓扑时,以80%概率进行修复
- 修复策略:关闭所有联络开关后,按网损减少量选择最优解
-
多样性增强:
- 每10代随机替换20%的种群
- 保证新解满足辐射状约束
-
速度限制:
- 设置最大速度vmax=6v_{max}=6vmax=6,防止过早收敛
-
Sigmoid转换 :
xij={1if rand<11+e−vij0otherwisex_{ij} = \begin{cases} 1 & \text{if } rand < \frac{1}{1+e^{-v_{ij}}} \\ 0 & \text{otherwise} \end{cases}xij={10if rand<1+e−vij1otherwise
3. 前推回代潮流计算
采用高效的前推回代法进行潮流计算:
-
回代过程(后序遍历):
- 从叶节点向根节点计算功率
Pij=Pj+∑Pjk+RijPij2+Qij2∣Vj∣2P_{ij} = P_j + \sum P_{jk} + R_{ij}\frac{P_{ij}^2 + Q_{ij}^2}{|V_j|^2}Pij=Pj+∑Pjk+Rij∣Vj∣2Pij2+Qij2
Qij=Qj+∑Qjk+XijPij2+Qij2∣Vj∣2Q_{ij} = Q_j + \sum Q_{jk} + X_{ij}\frac{P_{ij}^2 + Q_{ij}^2}{|V_j|^2}Qij=Qj+∑Qjk+Xij∣Vj∣2Pij2+Qij2
- 从叶节点向根节点计算功率
-
前推过程(先序遍历):
- 从根节点向叶节点计算电压
∣Vj∣2=∣Vi∣2−2(PijRij+QijXij)+(Rij2+Xij2)Pij2+Qij2∣Vi∣2|V_j|^2 = |V_i|^2 - 2(P_{ij}R_{ij} + Q_{ij}X_{ij}) + (R_{ij}^2 + X_{ij}^2)\frac{P_{ij}^2 + Q_{ij}^2}{|V_i|^2}∣Vj∣2=∣Vi∣2−2(PijRij+QijXij)+(Rij2+Xij2)∣Vi∣2Pij2+Qij2
- 从根节点向叶节点计算电压
4. 辐射状拓扑检查
使用图论方法验证拓扑:
matlab
function radial = is_radial(branch)
% 构建连通图
G = graph(active_branches(:,1), active_branches(:,2));
% 检查连通分量
bins = conncomp(G);
% 检查树状结构(节点数 = 边数 + 1)
if max(bins) > 1 || nbus ~= size(active_branches,1)+1
radial = false;
else
radial = true;
end
end
参考代码 以减小网损为目标的配电网重构问题求解 www.youwenfan.com/contentcsd/51254.html
程序功能与输出
1. 优化过程
程序输出迭代过程中的网损变化:
迭代 1: 最佳网损 = 202.4150 kW, 平均网损 = 215.3287 kW
迭代 2: 最佳网损 = 202.4150 kW, 平均网损 = 211.4762 kW
...
迭代 100: 最佳网损 = 139.7528 kW, 平均网损 = 142.3186 kW
2. 结果分析
优化完成后输出关键指标:
优化完成!
初始网损: 202.4150 kW
优化后网损: 139.7528 kW
网损降低率: 30.96%
最佳开关状态: 1 0 0 1 0
3. 可视化结果
-
网损收敛曲线:
- 展示最佳网损和平均网损随迭代次数的变化
- 验证算法收敛性
-
电压分布比较:
- 对比重构前后的节点电压
- 显示电压约束边界(0.95-1.05 p.u.)
-
网损分布:
- 初始网损分布(红色)
- 优化后网损分布(蓝色)
- 识别高损耗支路
-
拓扑可视化:
- 初始拓扑(含联络开关)
- 优化后拓扑(显示重构结果)
- 平衡节点(红色)和联络开关(紫色虚线)
该程序提供了完整的配电网重构优化框架,通过智能算法与高效潮流计算的结合,实现了显著的网损降低效果。