%% 多基站无线资源调度系统 - 修复索引错误版
clear; clc; close all;
%% 系统参数配置
total_slots = 100; % 总时隙数 (基于附件4的数据)
num_users = 70; % 用户总数 (U1-U10:10, e1-e20:20, m1-m40:40)
num_bs = 4; % 基站数 (MBS1 + 3个SBS)
RBs_per_bs = 100; % 每个基站资源块数量
slot_duration = 0.001; % 时隙长度(秒)
bandwidth_per_RB = 180e3; % 每个RB带宽(Hz)
power_per_RB = 0.1; % 每个RB发射功率(W)
thermal_noise_density = 1e-3 * 10^(-174/10); % 噪声功率谱密度(W/Hz)
throughput_window = 500; % 平均吞吐量计算窗口大小
% 基站位置 [x, y] (米)
bs_positions = [0, 0; % MBS_1
0, 500; % SBS_1
-433.0127, -250; % SBS_2
433.0127, -250]; % SBS_3
% 用户类型分类
urllc_users = 1:10; % URLLC用户
embb_users = 11:30; % eMBB用户
mtc_users = 31:70; % mMTC用户
%% 数据加载 - 修复任务数据维度问题
fprintf('加载信道数据...\n');
channel_data = cell(4, 1);
channel_files = {'SBS_1.xlsx', 'SBS_2.xlsx', 'SBS_3.xlsx', 'MBS_1.xlsx'};
% 加载信道数据
for bs = 1:num_bs
try
data = readmatrix(channel_files{bs});
% 确保数据包含100行
if size(data, 1) < total_slots
data = [data; zeros(total_slots - size(data,1), size(data,2))];
elseif size(data, 1) > total_slots
data = data(1:total_slots, :);
end
% 确保有70列数据
if size(data, 2) < num_users
data = [data, zeros(size(data,1), num_users - size(data,2))];
elseif size(data, 2) > num_users
data = data(:, 1:num_users);
end
channel_data{bs} = data;
fprintf('成功加载并调整 %s 至 %d×%d\n', channel_files{bs}, size(data,1), size(data,2));
catch
fprintf('使用随机数据替代 %s\n', channel_files{bs});
channel_data{bs} = 80 + 20*rand(total_slots, num_users);
end
end
% 加载任务数据 - 修复维度问题
fprintf('加载任务数据...\n');
try
task_arrivals = readmatrix('taskflow.xlsx');
[rows, cols] = size(task_arrivals);
fprintf('原始任务数据维度: %d×%d\n', rows, cols);
% 调整行数
if rows < total_slots
task_arrivals = [task_arrivals; zeros(total_slots - rows, cols)];
elseif rows > total_slots
task_arrivals = task_arrivals(1:total_slots, :);
end
% 调整列数
if cols < num_users
task_arrivals = [task_arrivals, zeros(size(task_arrivals,1), num_users - cols)];
elseif cols > num_users
task_arrivals = task_arrivals(:, 1:num_users);
end
fprintf('任务数据调整到 %d×%d\n', size(task_arrivals,1), size(task_arrivals,2));
catch
fprintf('任务数据创建中...\n');
task_arrivals = zeros(total_slots, num_users);
% URLLC: 高频到达 (50-300 bits)
task_arrivals(:, urllc_users) = randi([50, 300], total_slots, length(urllc_users));
% eMBB: 中频大包 (500-5000 bits)
task_arrivals(:, embb_users) = randi([500, 5000], total_slots, length(embb_users));
% mMTC: 低频小包 (10-100 bits, 30%活跃)
for u = mtc_users
activity = rand(total_slots, 1) > 0.7; % 30%时隙有任务
task_arrivals(:, u) = activity .* randi([10, 100], total_slots, 1);
end
end
%% 初始化系统状态
user_queues = zeros(num_users, 1); % 用户队列(比特)
avg_throughput = ones(num_users, 1) * 1e6; % 初始平均吞吐量(1Mbps)
% 分配记录
bs_assignment = zeros(total_slots, num_users); % 基站分配
rb_assignment = zeros(total_slots, num_users); % RB分配
bits_transferred = zeros(total_slots, num_users); % 传输比特数
queues_history = zeros(num_users, total_slots); % 队列历史
throughput_history = zeros(num_users, total_slots); % 吞吐量历史
%% 主调度循环
fprintf('开始资源调度...\n');
progress = waitbar(0, '处理时隙 0/100...', 'Name', '资源调度进度');
for t = 1:total_slots
% 1. 更新用户队列
user_queues = user_queues + task_arrivals(t, :)';
queues_history(:, t) = user_queues;
% 2. 获取当前信道状态
current_attenuation = zeros(num_bs, num_users);
for bs = 1:num_bs
if t <= size(channel_data{bs}, 1)
% 确保只取有效列
num_cols = min(size(channel_data{bs}, 2), num_users);
current_attenuation(bs, 1:num_cols) = channel_data{bs}(t, 1:num_cols);
else
% 时隙超出数据范围,使用随机值
current_attenuation(bs, :) = 80 + 20*rand(1, num_users);
end
end
% 3. 用户-基站关联 (选择最小衰减的基站)
[~, selected_bs] = min(current_attenuation, [], 1);
bs_assignment(t, :) = selected_bs;
% 4. 初始化当前时隙资源分配
rb_this_slot = zeros(num_users, 1);
bits_this_slot = zeros(num_users, 1);
%% 为每个基站分配资源
for bs = 1:num_bs
% 获取连接当前基站的活跃用户
connected_users = find(selected_bs == bs & user_queues > 0);
if isempty(connected_users)
continue; % 没有活跃用户
end
% 获取这些用户的信道衰减值
atten_dB = current_attenuation(bs, connected_users);
% 计算信道增益
gains_linear = 10.^(-atten_dB/10);
rx_power = power_per_RB * gains_linear;
noise_power = thermal_noise_density * bandwidth_per_RB;
SNR = rx_power ./ noise_power;
rate_per_RB = bandwidth_per_RB .* log2(1 + SNR);
bits_per_RB_val = rate_per_RB * slot_duration;
% 设置用户优先级
priority_weights = ones(size(connected_users));
for idx = 1:length(connected_users)
user_id = connected_users(idx);
if ismember(user_id, urllc_users)
priority_weights(idx) = 3.5; % URLLC高优先级
elseif ismember(user_id, embb_users)
priority_weights(idx) = 1.8; % eMBB中优先级
end
end
% 计算调度权重
weights = (rate_per_RB ./ avg_throughput(connected_users)') .* priority_weights;
total_weight = sum(weights);
if total_weight <= 0
continue;
end
% 基于权重分配资源
rb_alloc = floor(weights / total_weight * RBs_per_bs);
remaining_RBs = RBs_per_bs - sum(rb_alloc);
% 剩余RB分配
[~, sorted_idx] = sort(weights, 'descend');
for i = 1:length(sorted_idx)
if remaining_RBs <= 0
break;
end
user_idx = sorted_idx(i);
if rb_alloc(user_idx) < RBs_per_bs % 避免过度分配
rb_alloc(user_idx) = rb_alloc(user_idx) + 1;
remaining_RBs = remaining_RBs - 1;
end
end
% 应用分配并更新队列
for i = 1:length(connected_users)
user_id = connected_users(i);
allocated_bits = min(user_queues(user_id), rb_alloc(i) * bits_per_RB_val(i));
user_queues(user_id) = user_queues(user_id) - allocated_bits;
bits_this_slot(user_id) = bits_this_slot(user_id) + allocated_bits;
rb_this_slot(user_id) = rb_this_slot(user_id) + rb_alloc(i);
end
end
% 5. 更新系统状态
instant_rate = bits_this_slot / slot_duration;
avg_throughput = (1 - 1/throughput_window) .* avg_throughput + (1/throughput_window) .* instant_rate;
% 记录结果
rb_assignment(t, :) = rb_this_slot;
bits_transferred(t, :) = bits_this_slot;
throughput_history(:, t) = avg_throughput;
% 更新进度条
waitbar(t/total_slots, progress, sprintf('完成时隙 %d/%d', t, total_slots));
end
close(progress);
fprintf('资源调度完成!\n');
%% 性能分析与可视化
fprintf('分析性能并生成结果...\n');
% 创建结果目录
if ~exist('results', 'dir')
mkdir('results');
end
% 1. 系统总吞吐量 (Mbps)
total_throughput = sum(bits_transferred, 2) / 1e6;
figure('Position', [100, 100, 800, 400]);
plot(1:total_slots, total_throughput, 'b-', 'LineWidth', 2);
title('系统总吞吐量');
xlabel('时隙');
ylabel('吞吐量 (Mbps)');
grid on;
saveas(gcf, 'results/system_throughput.png');
% 2. 用户队列分析
figure('Position', [100, 100, 1000, 600]);
% 总队列长度
subplot(2,1,1);
total_queue = sum(queues_history, 1) / 1e6; % MBits
plot(1:total_slots, total_queue, 'r-', 'LineWidth', 1.5);
title('系统总队列长度');
xlabel('时隙');
ylabel('队列长度 (MBit)');
grid on;
% 各类用户平均队列长度
subplot(2,1,2);
hold on;
urllc_queue = mean(queues_history(urllc_users, :), 1) / 1e3; % kBits
embb_queue = mean(queues_history(embb_users, :), 1) / 1e3;
mtc_queue = mean(queues_history(mtc_users, :), 1) / 1e3;
plot(1:total_slots, urllc_queue, 'r-', 'LineWidth', 1.5);
plot(1:total_slots, embb_queue, 'g-', 'LineWidth', 1.5);
plot(1:total_slots, mtc_queue, 'b-', 'LineWidth', 1.5);
title('平均队列长度 (按用户类型)');
xlabel('时隙');
ylabel('队列长度 (kBit)');
legend('URLLC', 'eMBB', 'mMTC', 'Location', 'best');
grid on;
saveas(gcf, 'results/queue_analysis.png');
% 3. 用户类型吞吐量比较
urllc_tput = sum(bits_transferred(:, urllc_users), 2) / 1e6; % Mbps
embb_tput = sum(bits_transferred(:, embb_users), 2) / 1e6;
mtc_tput = sum(bits_transferred(:, mtc_users), 2) / 1e6;
figure('Position', [100, 100, 800, 400]);
hold on;
plot(1:total_slots, urllc_tput, 'r-', 'LineWidth', 1.5);
plot(1:total_slots, embb_tput, 'g-', 'LineWidth', 1.5);
plot(1:total_slots, mtc_tput, 'b-', 'LineWidth', 1.5);
title('用户类型吞吐量比较');
xlabel('时隙');
ylabel('吞吐量 (Mbps)');
legend('URLLC', 'eMBB', 'mMTC', 'Location', 'best');
grid on;
saveas(gcf, 'results/throughput_by_type.png');
% 4. 基站负载分析
bs_load = zeros(total_slots, size(bs_positions,1));
colors = [1 0 0; 0 1 0; 0 0 1; 0.5 0 0.5]; % 各基站颜色
figure('Position', [100, 100, 900, 600]);
for bs = 1:size(bs_positions,1)
for t = 1:total_slots
users_in_bs = find(bs_assignment(t,:) == bs);
bs_load(t, bs) = sum(rb_assignment(t, users_in_bs));
end
subplot(2,2,bs);
plot(1:total_slots, bs_load(:, bs), 'Color', colors(bs,:), 'LineWidth', 1.5);
title(sprintf('基站 %d 资源使用', bs));
xlabel('时隙');
ylabel('分配的RB数量');
ylim([0, 110]);
grid on;
end
saveas(gcf, 'results/bs_utilization.png');
% 5. 地理分布可视化
figure('Position', [100, 100, 700, 600]);
hold on;
% 绘制基站
scatter(bs_positions(:,1), bs_positions(:,2), 200, 'k', 'filled');
text(bs_positions(1,1), bs_positions(1,2)+30, 'MBS', 'FontSize', 12, 'HorizontalAlignment', 'center');
text(bs_positions(2,1), bs_positions(2,2)+30, 'SBS1', 'FontSize', 12, 'HorizontalAlignment', 'center');
text(bs_positions(3,1), bs_positions(3,2)+30, 'SBS2', 'FontSize', 12, 'HorizontalAlignment', 'center');
text(bs_positions(4,1), bs_positions(4,2)+30, 'SBS3', 'FontSize', 12, 'HorizontalAlignment', 'center');
% 绘制用户连接 (最后时隙)
rng(42); % 设置随机种子以保证可重现性
for user = 1:10:num_users
t = total_slots; % 使用最后一个时隙
bs_id = bs_assignment(t, user);
% 在基站周围生成用户位置
user_pos_x = bs_positions(bs_id, 1) + randn(1)*150;
user_pos_y = bs_positions(bs_id, 2) + randn(1)*150;
% 根据用户类型设置标记和颜色
if ismember(user, urllc_users)
marker = '^';
color = [1 0 0]; % 红色
elseif ismember(user, embb_users)
marker = 's';
color = [0 0.5 0]; % 绿色
else
marker = 'o';
end
end;位置 2 处的索引超出数组边界。索引不能超过 70。
出错 untitled5wenti4 (第 139 行)
atten_dB = current_attenuation(bs, connected_users);