删除重复元素——unique,ismember,setdiff

本文介绍如何使用Matlab中的unique、ismember及setdiff函数来处理多目标优化算法中的重复个体问题,通过具体实例展示了这些函数的应用。

  在多目标优化优化算法如NSGA2,RVEA等算法中,需要对种群个体进行操作,种群个体经过交叉变异产生的子代有可能会产生重复个体,需要对重复个体进行删除,本文列举几个Matlab函数用于对重复个体进行删除。所列举的例子都是以行为一个实体进行操作。

目录

1:unique:删除矩阵中重复元素

2:ismember:判断数组元素是否为集数组成员

3:setdiff:设置两个数组的差集


1:unique:删除矩阵中重复元素

A=unique(A,'rows')将A中每一行视作一个实体,返回A中唯一行。

A=[1 2 3;4 5 6;1 2 3;5 6 7];
A=unique(A,'rows');

结果

2:ismember:判断数组元素是否为集数组成员

Lia = ismember(A,B,'rows') 将 A 和 B 中的每一行视为一个实体,当 A 中的行也存在于 B 中时,将返回包含逻辑值 1 (true) 的列向量。数组中的其他位置将包含逻辑值 0 (false)

A=[1 2 3;4 5 6];
B=[1 2 3;5 6 7];
index=ismember(A,B,'rows');
C=A(index==0,:)

结果:

 3:setdiff:设置两个数组的差集

C=setdiff(A,B,'rows')将 A 和 B 的每一行都视为单个实体,并返回 A 中存在但 B 中不存在的行,不包括重复项。

A=[1 2 3;4 5 6];
B=[1 2 3;5 6 7];
C=setdiff(A,B,'rows')

结果:

 

逐步分析给出下列程序的计算公式,并生成算法流程图:function [island_list, total_load] = improved_flood_alg(dg_locations, dg_powers, load_powers, adj_matrix, critical_loads) % 改进洪水算法 - 增强版(混合种子 + 模拟退火 + 自适应扰动) island_list = cell(size(dg_locations)); total_load = 0; for k = 1:length(dg_locations) dg_node = dg_locations(k); dg_power = dg_powers(k); reach = find_reachable_nodes_bfs(dg_node, adj_matrix); if isempty(reach) island_list{k} = dg_node; continue; end %—— 1. 多策略混合种子生成 —— seeds = generate_hybrid_seeds(dg_node, dg_power, load_powers, reach, critical_loads, adj_matrix); %—— 2. 模拟退火优化 —— best_nodes = seeds{1}; % 初始解 best_load = sum(load_powers(best_nodes)); % 模拟退火参数 T0 = 100.0; % 初始温度 alpha = 0.92; % 降温系数 nIter = 80; % 增加迭代次数 T = T0; current_nodes = best_nodes; current_load = best_load; for iter = 1:nIter %—— 自适应扰动规模 —— if iter <= nIter/3 % 早期:大步长探索 perturbation_size = min(5, length(reach)); elseif iter <= 2*nIter/3 % 中期:中等步长 perturbation_size = min(3, length(reach)); else % 后期:小步长精细调整 perturbation_size = min(2, length(reach)); end %—— 生成候选解 —— cand = adaptive_perturb(current_nodes, reach, load_powers, dg_power, perturbation_size); load_cand = sum(load_powers(cand)); %—— 模拟退火接受准则 —— delta_E = load_cand - current_load; if delta_E > 0 || (rand < exp(delta_E / T) && load_cand <= dg_power) current_nodes = cand; current_load = load_cand; % 更新全局最优 if current_load > best_load best_nodes = current_nodes; best_load = current_load; end end % 降温 T = T * alpha; end island_list{k} = best_nodes; total_load = total_load + best_load; end end function seeds = generate_hybrid_seeds(dg_node, dg_power, load_powers, reach, critical_loads, adj_matrix) % 生成混合种子解 seeds = cell(1, 3); % 种子1:贪心优先级解 scores = zeros(size(reach)); for i = 1:numel(reach) n = reach(i); scores(i) = (ismember(n, critical_loads) * 25) ... + load_powers(n)/25 ... - abs(n - dg_node)*0.03; end [~, idx] = sort(scores, 'descend'); sorted_nodes = reach(idx); current_nodes = dg_node; current_load = 0; for n = sorted_nodes if current_load + load_powers(n) <= dg_power current_nodes(end+1) = n; %#ok<AGROW> current_load = current_load + load_powers(n); end end seeds{1} = current_nodes; % 种子2:纯负荷容量优先解 [~, idx] = sort(load_powers(reach), 'descend'); sorted_by_load = reach(idx); current_nodes = dg_node; current_load = 0; for n = sorted_by_load if current_load + load_powers(n) <= dg_power current_nodes(end+1) = n; %#ok<AGROW> current_load = current_load + load_powers(n); end end seeds{2} = current_nodes; % 种子3:DFS启发式解 dfs_nodes = dfs_greedy_seed(dg_node, dg_power, load_powers, reach, adj_matrix); seeds{3} = dfs_nodes; % 选择最优种子作为初始解 loads = zeros(1, 3); for i = 1:3 loads(i) = sum(load_powers(seeds{i})); end [~, best_idx] = max(loads); seeds = {seeds{best_idx}}; % 只返回最优种子 end function dfs_nodes = dfs_greedy_seed(dg_node, dg_power, load_powers, reach, adj_matrix) % DFS启发式种子生成 dfs_nodes = dg_node; current_load = 0; visited = false(1, length(adj_matrix)); visited(dg_node) = true; % 从DG节点开始DFS stack = dg_node; while ~isempty(stack) && current_load < dg_power current = stack(end); stack(end) = []; % 找到未访问的邻居 neighbors = find(adj_matrix(current, :) & ~visited); for neighbor = neighbors if ismember(neighbor, reach) && ~visited(neighbor) if current_load + load_powers(neighbor) <= dg_power dfs_nodes(end+1) = neighbor; %#ok<AGROW> current_load = current_load + load_powers(neighbor); visited(neighbor) = true; stack(end+1) = neighbor; %#ok<AGROW> end end end end end function cand = adaptive_perturb(current_nodes, reach, load_powers, dg_power, perturbation_size) % 自适应扰动生成候选解 cand = current_nodes; % 扰动类型选择 if rand < 0.4 % 添加节点 available = setdiff(reach, cand); if ~isempty(available) num_add = min(perturbation_size, length(available)); to_add = available(randperm(length(available), num_add)); cand = unique([cand, to_add]); end elseif rand < 0.7 % 删除节点 if length(cand) > 1 num_remove = min(perturbation_size, length(cand)-1); to_remove = randperm(length(cand)-1, num_remove) + 1; % 不删除DG节点 cand(to_remove) = []; end else % 交换节点 if length(cand) > 1 && length(reach) > length(cand) num_swap = min(perturbation_size, length(cand)-1); for i = 1:num_swap if length(cand) > 1 % 随机选择一个非DG节点进行交换 swap_idx = randi(length(cand)-1) + 1; available = setdiff(reach, cand); if ~isempty(available) cand(swap_idx) = available(randi(length(available))); end end end end end % 确保功率约束 while sum(load_powers(cand)) > dg_power && length(cand) > 1 % 移除负荷最大的非DG节点 non_dg = cand(2:end); [~, max_idx] = max(load_powers(non_dg)); cand(max_idx + 1) = []; end end
最新发布
09-05
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值