信号干扰资源调度matlab程序(局部最优解版本)
用matlab写了一个用于信号干扰资源调度的程序,一开始使用回溯法求全局最优解,但发现时间复杂度过高,信号数目超过20个后,跑个半天都跑不出结果,改成求局部最优解,来来回回测了很多组数据,改了很多遍,最后在时间和得分之间折中,实测效果较好,代码量从800L到3000L,最后压缩到1300L
%% 0清零
clear all;
clc;
format short;
%% 1 读取输入,生成可处理文件file_name
file_in = input('输入原始信号文件完整名字(如Signal.xls):\n', 's');
file_name = '输入';
file_point = '频点';
sheet1 = '数据';
sheet2 = '跳频数据';
fprintf('[提示]现在输入表的sheet1和sheet2是不是叫"%s"和"%s",如果不是,请更改名字保持一致,如果是,按回车继续!\n', sheet1, sheet2);
disp('等待按下回车中......')
pause();
firallH = 25*3600; %跳频的第一个时间
firallF = 25*3600; %定频的第一个时间
firsecH = 0; %跳频的第一个时间秒
firsecF = 0; %定频的第一个时间秒
Hisfirst = 0; %跳频时间最早的标记
date_name = datestr(now,'yyyymmddHHMMSS');
file_name = strcat(file_name, date_name);
file_name = strcat(file_name, '.xls');
% 定频
[Fsdata, Fsstr] = xlsread(file_in, sheet1);
datasz = size(Fsdata, 1);
Fdata = zeros(datasz, 4);
timestr = datestr(Fsdata(:, 3),'HH:MM:SS');
for i = 1:datasz
Hour = str2num(timestr(i, 1:2));
Minute = str2num(timestr(i, 4:5));
seconds = str2num(timestr(i, 7:8));
timeF = Hour*3600 + Minute*60 + seconds;
if timeF<firallF
firallF = timeF;
firsecF = seconds;
end
if seconds>0
Minute = Minute + 1; %从后一分钟开始算
end
fnum = Fsdata(i, 1);
typestr = cell2mat(Fsstr(i+1, 4));
flag = 0;
try
if typestr=='DS'
flag = 1;
end
catch MException
flags = 0;
end
if flag==1
Fdata(i, :) = [Hour Minute NaN fnum];
else
Fdata(i, :) = [Hour Minute fnum NaN];
end
end
xlswrite(file_name, Fdata, 'Sheet1', 'A1');
% 跳频
Hsdata = xlsread(file_in, sheet2);
datasz = size(Hsdata, 1);
Hdata = zeros(datasz, 6);
timestr = datestr(Hsdata(:, 4),'HH:MM:SS');
for i = 1:datasz
Hour = str2num(timestr(i, 1:2));
Minute = str2num(timestr(i, 4:5));
seconds = str2num(timestr(i, 7:8));
timeH = Hour*3600 + Minute*60 + seconds;
if timeH<firallH
firallH = timeH;
firsecH = seconds;
end
if seconds>0
Minute = Minute + 1;
end
f1num = Hsdata(i, 1);
f2num = Hsdata(i, 2);
interval = Hsdata(i, 3);
ffsignal = Hsdata(i, 7);
Hdata(i, :) = [Hour Minute f1num f2num interval ffsignal];
end
if firallH > firallF
firstsec = firsecF;
Hisfirst = -1;
elseif firallH < firallF
firstsec = firsecH;
Hisfirst = 1;
end
xlswrite(file_name, Hdata, 'Sheet2', 'A1');
%% 2 全局变量初始化
% 时间处理
global startT;
global endT;
global allR;
global cars_num;
start_time = input('输入干扰开始时间(如13:10):\n', 's');
end_time = input('输入干扰结束时间(如14:00):\n', 's');
cars_num = input('输入每轮总的干扰台站数:\n');
start_str = strsplit(start_time, ':');
startH = eval(start_str{1});
startM = eval(start_str{2});
startT = startH*60+startM; %开始时间
end_str = strsplit(end_time, ':');
endH = eval(end_str{1});
endM = eval(end_str{2});
endT = endH*60+endM; %结束时间
allT = endT - startT;
time_flag = 0;
if allT>60 %四轮
if allT<=70
allR = 4;
gtime = [startT startT+10 startT+30 startT+50];
else
time_flag = 1;
allR = 5;
gtime = [startT startT+10 startT+30 startT+50 startT+70];
res_time = allT - 70;
end
else %三轮
if allT<=50
allR = 3;
gtime = [startT startT+10 startT+30];
else
time_flag = 1;
allR = 4;
gtime = [startT startT+10 startT+30 startT+50];
res_time = allT - 50;
end
end
%跳频
signal = xlsread(file_name, 2);%读取信号表格
[row,col] = size(signal);%读取所获得信号的大小
sg_num = signal(row,col);%最后一个波道的编号
%定频
Fsignal = xlsread(file_name, 1);
[Frow, Fcol] = size(Fsignal);
cars_res = 60/45;
%% 2跳频资源
% 2.1计算信号的波道数量sg_count
sg_count = zeros(1,sg_num);
for i = 1:row
for j =1:sg_num
if signal(i,6) == j
sg_count(j) = sg_count(j)+1;
end
end
end
% 2.2计算各波道的点数hops_num
hops_num = zeros(row,1);%存储各波段的点数
for i = 1:row
hops_num(i) = (signal(i,4)-signal(i,3))/(signal(i,5)*0.001) + 1;
end
max_hops_num = max(hops_num);
max_hops_num = int32(max_hops_num);
h_size = max_hops_num;%将所建立的空矩阵尺寸调整为所需大小
hops = zeros(h_size,sg_num);%建立一个空矩阵存储所有波段的点
% 2.3计算所有波道的点hops
for i = 1:row
for j = 1:hops_num(i)
hops(j,i) = signal(i,3) + signal(i,5)*0.001*(j-1);
end
end
hops = roundn(hops,-3);%保留3位小数避免double数据的精度影响数据
% 2.4将总的信号矩阵按波道切割为单个信号signal
deal_signals = mat2cell(hops,max_hops_num,sg_count);
for i = 1:sg_num
eval(['s',int2str(i),'=cell2mat(deal_signals(i))']);
end
% 2.5计算每个信号的频点数signal_hops_num
position = 1;
pause = sg_count(1);
signal_hops_num = zeros(1,sg_num);%存储每个信号的频点数
for i = 1:sg_num
for j = position:pause
signal_hops_num(i) = signal_hops_num(i)+hops_num(j);
end
position = position + sg_count(i);
if i+1 <= sg_num
pause = pause+sg_count(i+1);
end
end
% 2.6确定跳频信号类型signal_type
%signal_type中,1代表频数为128,2代表频数为256,4代表频数为512,8代表频数为1024
signal_type = zeros(sg_num,1);
for i = 1:sg_num
signal_type(i) = round(signal_hops_num(i)/128);%通过除以128四舍五入取整确定信号跳频数
end
% 2.7计算单一信号-资源数关系sr
global sr;
sr = signal_type;
for i = 1:length(sr)
if sr(i)==0
sr(i) = 1;
elseif sr(i)==3
sr(i) = 4;
elseif (sr(i)>4 && sr(i)<8)
sr(i) = 8;
end
end
%% 3计算时刻-信号关系
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 定频部分 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 3.1 建立定频信号属性矩阵Fsp和定频信号时刻-出现信号关系Fst
% 读入表格按时间排序
for i = 1:Frow %60*小时数+分钟数
time = Fsignal(i, 1)*60 + Fsignal(i, 2);
Fsignal(i, 2) = time;
end
Fsignal2 = sortrows(Fsignal, 2);
%Fsp:第一行是代号(按照读进来的顺序编号),第二行是对应频点值,第三行是标记(定频用0,直扩用1)
%Fst:每列代表当前时刻出现的信号,第一行代表时刻
global Fsg_num
global Fsp
global Fst
Fsg_num = 0;
Fsp = zeros(3, 2*Frow);
Fst = zeros(500, Frow); %硬编码:最大定频信号数是1000
st_num2 = 0;
gt = 0;
ct = 1;
time1 = 0;
for i = 1:Frow
time2 = Fsignal2(i, 2);
if time2~=time1
gt = gt + 1; %列加1
ct = 1;
else
ct = ct + 1; %行加1
end
try
Fs1 = Fsignal2(i, 3); %定频
catch MException
Fs1 = NaN;
end
try
Fs2 = Fsignal2(i, 4); %直扩
catch MException
Fs2 = NaN;
end
if or(~isnan(Fs1), ~isnan(Fs2))
Fst(1, gt) = time2;
end
if ~isnan(Fs1)
Fsg_num = Fsg_num + 1;
Fsp(1, Fsg_num) = Fsg_num;
Fsp(2, Fsg_num) = Fs1;
Fsp(3, Fsg_num) = 0;
Fst(1+ct, gt) = Fsg_num;
end
if ~isnan(Fs2)
Fsg_num = Fsg_num + 1;
Fsp(1, Fsg_num) = 0-Fsg_num;
Fsp(2, Fsg_num) = Fs2;
Fsp(3, Fsg_num) = 1;
Fst(1+ct, gt) = 0-Fsg_num;
end
time1 = time2; %更新时间
end
Fsp(:,all(Fsp==0,1)) = [];%去掉全零列
Fst(:,all(Fst==0,1)) = [];%去掉全零列
Fst(all(Fst==0,2),:) = [];%去掉全零行
% 按定频和直扩时间顺序收集信号
global Dst;
Dst = zeros(Fsg_num, 1); %直扩
dct = 0;
Pst1 = zeros(Fsg_num, 1); %10分钟内进来的普通定频
pct1 = 0;
Pst = zeros(Fsg_num, 1); %普通定频
pct = 0;
[Frows, Fcols] = size(Fst);
for i =1:Fcols
nowtime = Fst(1, i);
for j = 2:Frows
Fsig = Fst(j, i);
if Fsig==0
continue
elseif Fsig>0 %定频
pct = pct + 1;
Pst(pct) = Fsig;
if nowtime<startT+10 %前10分钟进来的
pct1 = pct1 + 1;
Pst1(pct1) = Fsig;
end
elseif Fsig<0 %直扩
dct = dct + 1;
Dst(dct) = Fsig;
end
end
end
Pst(all(Pst==0,2),:) = [];%去掉全零行
Pst1(all(Pst1==0,2),:) = [];%去掉全零行
Dst(all(Dst==0,2),:) = [];%去掉全零行
%% 方案处理
global scheme_temp;
global tsk_temp;
global Ftsk_temp;
scheme_temp = zeros(2, allR);
tsk_temp = zeros(20, allR);
Ftsk_temp = zeros(8, allR);
global GPoint; %全局跳频输出表,表示哪个时间范围内哪辆车干了哪个信号具体的哪几个点,第一行是开始时间,第二行是车号,第三、四、五行是信号代号,第六行后是具体点
global GFsig; %全局定频输出表,表示哪个时间范围内哪辆车干了哪几个信号,第一行是开始时间,第二行是车号,第三行往后是信号代号
global gp_ct; %全局跳频表的下标
global gf_ct; %全局定频表的下标
global Gtime; %全局时间表,一行,表示干扰的真实时间
global res_car; %当前时刻每辆车剩下的点数,每列代表车号,第一行表示剩下资源数,第二、三、四行表示干扰的信号,第五行往后是干扰的点
global alreadyfill; %当前时刻已经填的点
GPoint = zeros(66, allR*cars_num);
GFsig = zeros(6, cars_num*cars_num);
Gtime = zeros(1, allR);
res_car = zeros(65, cars_num);
alreadyfill = zeros(60*cars_num, 1);
gp_ct = 0;
gf_ct = 0;
% 获取实际时间
for i=1:allR
time = gtime(i);
hour = floor(time/60);
minute = mod(time, 60);
alltime = hour*100 + minute;
Gtime(i) = alltime;
end
global car_flag;
i = 1;
while(true)
scheme_temp1 = scheme_temp;
tsk_temp1 = tsk_temp;
Ftsk_temp1 = Ftsk_temp;
Dst1 = Dst;
res_car1 = res_car;
GPoint1 = GPoint;
gp_ct1 = gp_ct;
GFsig1 = GFsig;
gf_ct1 = gf_ct;
alreadyfill1 = alreadyfill;
%跳频
if i==allR & time_flag==1
fprintf('=======================第%d轮次信号干扰方案======================\n', i);
fprintf('最后一轮还剩%d分钟,继续按照第一轮方案干扰......\n', res_time);
scheme_temp(:, end) = scheme_temp(:, 1);
tsk_temp(:, end) = tsk_temp(:, 1);
Ftsk_temp(:, end) = Ftsk_temp(:, 1);
else
fprintf('=======================第%d轮次信号干扰方案======================\n', i);
Hcar = input('输入干扰跳频用车数:\n');
Hsig = input('输入干扰跳频信道号(以空格隔开):\n', 's');
Fcar = cars_num - Hcar;
scheme_temp(:, i) = [Hcar Fcar]';
sig = strsplit(Hsig);
Hsize = size(sig, 2);
for j = 1:Hsize
tsk_temp(j, i) = eval(sig{j});
end
%定频
build_Ftsk(i, Pst, Pst1);
tsk_temp(all(tsk_temp==0,2),:) = [];%去掉全零行
Ftsk_temp(all(Ftsk_temp==0,2),:) = [];%去掉全零行
end
updateGcar(i);
i = i + 1;
if car_flag == 0
disp('!!!本轮给的跳频车少了,请重新输入本轮方案!!!')
scheme_temp = scheme_temp1;
tsk_temp = tsk_temp1;
Ftsk_temp = Ftsk_temp1;
Dst = Dst1;
res_car = res_car1;
GPoint = GPoint1;
gp_ct = gp_ct1;
GFsig = GFsig1;
gf_ct = gf_ct1;
alreadyfill = alreadyfill1;
i = i - 1;
end
if i>allR
break;
end
end
%% 5 输出
global Pout; %跳频最终输出,第一行是开始时间,第二行是结束时间,第三行是车号,第四、五、六行是信号代号,第七行后是频点
global Fout; %定频最终输出,第一行是开始时间,第二行是结束时间,第三行是车号,第四-七行是信号代号,第八行后是频点
Pout = zeros(67, allR*cars_num);
Fout = zeros(7, allR*cars_num);
tsk_temp(all(tsk_temp==0,2),:) = [];%去掉全零行
Ftsk_temp(all(Ftsk_temp==0,2),:) = [];%去掉全零行
disp('=========================生成方案=========================')
disp('跳频干扰方案:')
disp(tsk_temp)
disp('定频干扰方案:')
disp(Ftsk_temp)
disp('=========================方案结束=========================')
GPoint(:,all(GPoint==0,1)) = [];%去掉全零列
GFsig(:,all(GFsig==0,1)) = [];%去掉全零列
processGcar();
Pout(:,all(Pout==0,1)) = [];%去掉全零列
Fout(:,all(Fout==0,1)) = [];%去掉全零列
write_point(file_point);
%% build_Ftsk函数的实现:根据给定定频台站选定频信号
function build_Ftsk(tck, Pst, Pst1)
% 根据给定定频台站选取干扰信号,第一轮优先干扰定频,后几轮优先直扩
global Ftsk_temp;
global scheme_temp;
global Dst;
% 第一轮
if tck==1
Pst1 = [Pst1' Dst']'; %不够的用直扩来补
Psize1 = size(Pst1, 1);
carF1 = scheme_temp(2, 1); %第一轮定频用车
snumF1 = carF1 * 4; %第一轮可以干的信号数
snumF1 = min(snumF1, Psize1); %不能超过总的信号数
sigF1 = Pst1(1:snumF1); %第一轮干的信号
Ftsk_temp(1:snumF1, 1) = sigF1;
Pst_rest = setdiff(Pst, sigF1); %剩下没干的定频,用于补后面的直扩
Dst = setdiff(Dst, sigF1);
Dst = sort(Dst, 'descend');
Dst = [Dst' Pst_rest']'; %不够的用定频来补
end
%后几轮
Dsize = size(Dst, 1);
carF = scheme_temp(2, tck); %每一轮的定频用车
snumF = carF*4; %每一轮干的信号数
snumF = min(snumF, Dsize); %不能超过剩下的信号数
sigF = Dst(1:snumF); %每一轮干的信号
Ftsk_temp(1:snumF, tck) = sigF;
Dst([1:snumF], :) = []; %更新剩下没干的信号
end
%% updateGcar函数的实现
% 输入:tsk_temp、Ftsk_temp、scheme_temp
% 输出:Gcar、Gpd
% 目的:循环每个时刻的用车数和干扰信号代号,获取每个时间段用哪辆车干扰哪个信号及其频点
function updateGcar(tck)
global tsk_temp;
global Ftsk_temp;
global scheme_temp;
global Gtime;
fprintf('--------------------------进入第%d轮次--------------------------\n', tck)
%获取当前时刻输入
Hcars = scheme_temp(1, tck);
Fcars = scheme_temp(2, tck);
Hsigs = tsk_temp(:, tck);
Hsigs(all(Hsigs==0,2),:) = [];%去掉全零行
Fsigs = Ftsk_temp(:, tck);
Fsigs(all(Fsigs==0,2),:) = [];%去掉全零行
updateTcar(Hcars, Fcars, Hsigs, Fsigs, Gtime(tck));%更新局部车表和全局跳频表
end
%% updateTcar函数的实现
% 根据给定的台站数和信号,更新Tcar和Gpd
function updateTcar(Hcars, Fcars, Hsigs, Fsigs, time)
global cars_num;
global GFsig;
global gf_ct;
%先处理定频
if Fcars==1 %只有一辆定频车那就用最后一辆干扰
gf_ct = gf_ct + 1;
GFsig(1, gf_ct) = time;
GFsig(2, gf_ct) = cars_num;
Fsize = size(Fsigs, 1);
GFsig(3:end, gf_ct) = 0;
GFsig(3:2+Fsize, gf_ct) = Fsigs;
elseif Fcars==2 %有两辆定频车那就用最后两辆干扰
gf_ct = gf_ct + 1;
GFsig(1, gf_ct) = time;
GFsig(2, gf_ct) = cars_num - 1;
GFsig(3:end, gf_ct) = Fsigs(1:4);
gf_ct = gf_ct + 1;
GFsig(1, gf_ct) = time;
GFsig(2, gf_ct) = cars_num;
Fsize = size(Fsigs, 1) - 4;
GFsig(3:end, gf_ct) = 0;
GFsig(3:2+Fsize, gf_ct) = Fsigs(5:end);
end
%然后处理跳频
if all(Hsigs==0) %当前时刻如果不干跳频信号则退出
return
end
Hsize = size(Hsigs, 1);
if Hsize>1 %如果有两个以上跳频
[slaps, slaps_num] = cal_res(Hsigs); %求当前跳频序列的2个信号间最大重合点、点数和重合信号
if slaps_num > 0 %有重合点
assign_slaps(slaps, slaps_num, Hsigs, Hcars, time);
fill_lastcar(Hsigs, Hcars, time);
return
end
end
assign_point(Hsigs, Hcars, time);
fill_lastcar(Hsigs, Hcars, time);
end
%% assign_point函数的实现:用于无重合点的情况分配跳频点
function assign_point(Hsigs, Hcars, time)
global already_fill;
global res_car;
global sr;
disp('本轮干扰跳频为:')
disp(Hsigs')
disp('跳频信号间无重合点,不进行选取')
already_fill = 0;
Hsize = size(Hsigs, 1);
res_car = zeros(65, Hcars); %每辆车剩下的点数
for i=1:Hcars
res_car(1, i) = 60; %每辆车初始化为60个点
end
for i = 1:Hsize
sig = Hsigs(i);
sig_res = sr(sig)*45;
sig_point = choose_points(sig, sig_res);
update_res(sig_res, sig, sig_point, Hcars, time);
end
end
%% assign_slaps函数的实现:用于有重合点的情况来分配跳频点
function assign_slaps(slaps, slaps_num, Hsigs, Hcars, time)
global GPoint;
global gp_ct;
global sr;
global res_car;
global already_fill;
disp('本轮干扰跳频为:')
disp(Hsigs')
fprintf('信号间总共有%d个重合点\n', slaps_num);
slap_car = ceil(slaps_num/60); %装下这些重合点需要多少辆车
slap_res = mod(slaps_num, 60); %最后一辆装重合点的车装了几个点
perfect_car = slap_car - 1; %完整装完重合点的台站数
%先把完整装完重合点的车填满
if perfect_car > 0
for i = 1:perfect_car
gpd = [time i -1 0 0 0 slaps((i-1)*60+1:i*60)']';
gp_ct = gp_ct + 1;
GPoint(:, gp_ct) = gpd;
end
end
%再装不能完整装完重合点的车
res_car = zeros(65, Hcars); %每辆车剩下的点数
for i=1:Hcars
if i>slap_car %还未装的车
res_car(1, i) = 60;
end
if i==slap_car
if slap_res == 60 %最后一辆车刚好装完
gpd = [time i -1 0 0 0 slaps(end-59:end)']';
gp_ct = gp_ct + 1;
GPoint(:, gp_ct) = gpd;
else
res_car(1, i) = 60 - slap_res; %最后一辆装完重合点后剩下的点
res_car(2, i) = -1;
res_car(3, i) = 0;
res_car(4:5, i) = 0;
res_car(6:5+slap_res, i) = slaps(end-slap_res+1:end);
end
end
end
%干完重合点后继续干剩下的信号
already_fill = slaps;
Hsize = size(Hsigs, 1);
for i=1:Hsize
sig_num = Hsigs(i);
sig = evalin('base', ['s', num2str(sig_num)]);
sig_slaps = intersect(sig, slaps);
already_num = size(sig_slaps, 1); %已经干了的点数
sig_res = sr(sig_num)*45; %总的要干的点数
s_rest = sig_res - already_num; %剩下还没干的点数
s_rest = max(s_rest, 0); %不能为负
fprintf('干完重合点后,%d信号已经干了%d个点,还要干%d个点\n', sig_num, already_num, s_rest);
if s_rest>0 %还要继续干
sig_point = choose_points(sig_num, s_rest);
update_res(s_rest, sig_num, sig_point, Hcars, time);
end
end
end
%% fill_lastcar的实现,填充最后一辆车
function fill_lastcar(Hsigs, Hcars, time)
global res_car
global already_fill
global GPoint;
global gp_ct;
%先找到真实的最后一辆车
car_size = size(res_car, 2);
for k = 1:car_size
if res_car(1, k)~= 0
break
end
end
if Hcars>k
fprintf('给的跳频车多了,实际用车数为%d\n', k);
disp('按照实际用车数继续计算......');
Hcars = k;
end
last_res = res_car(1, Hcars);
last_points = res_car(6:end, Hcars);
real_res = sum(last_points==0); %统计最后一列零元素个数,即还需要干的点数
last_res = max(last_res, real_res);
if last_res==0 %资源被用完,不用填充
fprintf('最后一辆车是%d,已经填满,不用补\n', Hcars);
return
end
fprintf('最后一辆车是%d, 还需要补%d个点\n', Hcars, last_res);
%平均补
sig_num = size(Hsigs, 1);
each_num = floor(last_res/sig_num);
last_num = last_res - each_num*(sig_num - 1);
add_point = zeros(last_res, 1);
add_ct = 0;
for i = 1:sig_num-1
sig = Hsigs(i);
real_sig = evalin('base', ['s', num2str(sig)]);
res_sig = setdiff(real_sig, already_fill);
res_sig(all(res_sig==0,2),:) = [];%去掉全零行
res_size = size(res_sig, 1);
min_size = min(res_size, each_num);
add_point(add_ct+1:add_ct+min_size, 1) = res_sig(1:min_size);
add_ct = add_ct + min_size;
fprintf('从%d信号中补了%d个点\n', sig, min_size);
already_fill = union(already_fill, res_sig(1:min_size));
end
sig = Hsigs(end);
real_sig = evalin('base', ['s', num2str(sig)]);
res_sig = setdiff(real_sig, already_fill);
res_sig(all(res_sig==0,2),:) = [];%去掉全零行
res_size = size(res_sig, 1);
last_num = last_res - add_ct; %不够的从最后一个信号里补充
min2_size = min(res_size, last_num);
add_point(add_ct+1:add_ct+min2_size, 1) = res_sig(1:min2_size);
fprintf('从%d信号中补了%d个点\n', sig, min2_size);
already_fill = union(already_fill, res_sig(1:min2_size));
add_size = size(add_point, 1);
res_car(1, Hcars) = 0;
filled_num = 60 - last_res; %已经填充过的点
res_car(6+filled_num:5+add_size+filled_num, Hcars) = add_point;
gpd = [time Hcars res_car(2, Hcars)' res_car(3, Hcars)' res_car(4, Hcars)' res_car(5, Hcars)' res_car(6:end, Hcars)']';
gp_ct = gp_ct + 1;
GPoint(:, gp_ct) = gpd;
end
%% update_res函数的实现,给定信号代号sig、其占点数res和频点points,更新res_car,并在res_car写满后输出
function update_res(sigres, sig, points, Hcars, time)
global res_car
global GPoint;
global gp_ct;
global already_fill;
global car_flag;
car_flag = 1;
flag = 0;
for i=1:Hcars
res = res_car(1, i);
if res==0 %该车资源用尽
continue
end
if sigres >= res %该车在这个时候会被写满
sigres = sigres - res;
has_points = 60 - res; %已经写的点
res_car(1, i) = 0;
if res_car(2, i) == 0
res_car(2, i) = sig;
elseif res_car(3, i) == 0
if sig~=res_car(2, i)
res_car(3, i) = sig;
end
elseif res_car(4, i) == 0
if sig~=res_car(2, i) & sig~=res_car(3, i)
res_car(4, i) = sig;
end
elseif res_car(5, i) == 0
if sig~=res_car(2, i) & sig~=res_car(3, i) & sig~=res_car(4, i)
res_car(5, i) = sig;
end
end
res_car(6+has_points:end, i) = points(1:res);
already_fill = union(already_fill, points(1:res));
if sigres==0
points = 0;
else
points = points(res+1:end);
end
gpd = [time i res_car(2, i)' res_car(3, i)' res_car(4, i)' res_car(5, i)' res_car(6:end, i)']';
gp_ct = gp_ct + 1;
GPoint(:, gp_ct) = gpd;
elseif res>sigres %这个信号会被该车干掉
has_points = 60 - res;
res_car(1, i) = res - sigres;
if res_car(2, i) == 0
res_car(2, i) = sig;
elseif res_car(3, i) == 0
if sig~=res_car(2, i)
res_car(3, i) = sig;
end
elseif res_car(4, i) == 0
if sig~=res_car(2, i) & sig~=res_car(3, i)
res_car(4, i) = sig;
end
elseif res_car(5, i) == 0
if sig~=res_car(2, i) & sig~=res_car(3, i) & sig~=res_car(4, i)
res_car(5, i) = sig;
end
end
res_car(6+has_points:5+has_points+sigres, i) = points;
already_fill = union(already_fill, points);
points = 0;
sigres = 0;
end
if sigres==0 %信号被干了
flag = 1;
break;
end
end
if flag == 0 %信号没被干掉
car_flag = 0;
end
end
%% choose_points函数的实现
% 输入要选的信号和点数,排除掉already_fill的点,返回选中的点
function points = choose_points(sig, num)
global already_fill;
points = zeros(num, 1);
p_ct = 0;
ssig = evalin('base', ['s', num2str(sig)]);
use_sig = setdiff(ssig, already_fill);
use_sig(all(use_sig==0,2),:) = [];%去掉全零行
[rows, cols] = size(use_sig);
for j=1:cols
for i = 2:rows-1
if use_sig(i, j)~=0
p_ct = p_ct + 1;
points(p_ct) = use_sig(i, j);
end
if p_ct>=num
return
end
end
end
end
%% cal_res函数的实现:给定序列计算两个信号间最大重合点,返回重合点数和重合点
function [slaps, slaps_num] = cal_res(tasks)
global sr;
task_sort = sort(tasks);
task_len = size(task_sort, 1);
%计算重合资源数
choo_num = nchoosek(task_len, 2);
choo_vect = nchoosek(task_sort, 2);
slaps = 0;
for i=1:choo_num
foo = choo_vect(i, :);
num1 = foo(1);
num2 = foo(2);
slap1 = evalin('base', ['s', num2str(num1)]);
slap2 = evalin('base', ['s', num2str(num2)]);
slaps_foo = intersect(slap1, slap2);
sr1 = sr(num1)*45;
sr2 = sr(num2)*45;
foo_size = size(slaps_foo, 1) - 1;
if foo_size>sr1
fprintf('%d信号和%d信号之间的重合点数超过了%d信号本身的数量\n', num1, num2, num1);
end
if foo_size>sr2
fprintf('%d信号和%d信号之间的重合点数超过了%d信号本身的数量\n', num1, num2, num2);
end
sr_min = min(sr1, sr2);
if foo_size > sr_min
fprintf('-->原重合点数目为%d个,取其中%d个\n', foo_size, sr_min);
slaps_foo = slaps_foo(1:sr_min);
end
slaps = union(slaps, slaps_foo);
end
slaps(all(slaps==0,2),:) = [];%去掉全零行
slaps = unique(slaps);
slaps_num = size(slaps, 1);
if (slaps_num==0) %无重合点
slaps = 0;
end
end
%% processGcar函数的实现
% 用于去重和合并时间
function processGcar()
global endT;
hour = floor(endT/60);
minute = mod(endT, 60);
time = hour*100 + minute;
final_out = time;
processGpoint(final_out);
processFpoint(final_out);
end
function processGpoint(final_time)
global GPoint;
global Gtime;
global Pout;
p_ct = 0;
gpoint = GPoint;
plen = 65;
allR = size(Gtime, 2);
gpoint(:,all(gpoint==0,1)) = [];%去掉全零列
while(1)
if size(gpoint, 2)<1
break
end
eq_col = zeros(1, allR);
eq_time = zeros(1, allR);
eq_ct = 0;
psize = size(gpoint, 2);
p1 = gpoint(2:end, 1);
start_time = gpoint(1, 1);
end_time = 0;
car_num = gpoint(2, 1);
sig_name = gpoint(3:6, 1);
if psize>1
for i = 2:psize
p2 = gpoint(2:end, i);
if p2(1) == p1(1) %车号相同
if sum(p1==p2)~=plen %干扰信号变了
end_time = gpoint(1, i);
break
else
eq_ct = eq_ct + 1; %记录相同的列
eq_col(eq_ct) = i;
eq_time(eq_ct) = gpoint(1, i);
end
end
end
end
if end_time == 0 %如果一直没变,则干到最后一时刻
min_hour = floor(start_time/100);
min_minute = mod(start_time, 100);
min_time = min_hour*60 + min_minute + 20;
min_hour = floor(min_time/60);
min_minute = mod(min_time, 60);
min_time = min_hour*100 + min_minute;
end_time = min(final_time, min_time);
end
kk = find(Gtime==start_time);
cmp_time = Gtime(kk+1:end);
cmp_size = size(cmp_time, 2);
flagg = 0;
for bb = 1:eq_ct
if cmp_time(bb)~=eq_time(bb)
end_time = cmp_time(bb);
flagg = 1;
break;
end
end
if flagg==0 & cmp_size > eq_ct
end_time = cmp_time(eq_ct + 1);
end
p_ct = p_ct + 1;
psig = p1(6:end);
pout = [start_time end_time sig_name' car_num psig']';
Pout(:, p_ct) = pout;
eq_col(eq_ct+1) = 1; %加上第一列
eq_col(:,all(eq_col==0,1)) = [];%去掉全零列
gpoint(:, eq_col) = []; %删掉所有相同列
end
Pout(:,all(Pout==0,1)) = [];%去掉全零列
end
function processFpoint(final_time)
global GFsig;
global Gtime;
global Fout;
global Fsp;
p_ct = 0;
gpoint = GFsig;
plen = 5;
allR = size(Gtime, 2);
gpoint(:,all(gpoint==0,1)) = [];%去掉全零列
while(1)
if size(gpoint, 2)<1
break
end
eq_col = zeros(1, allR);
eq_time = zeros(1, allR);
eq_ct = 0;
psize = size(gpoint, 2);
p1 = gpoint(2:end, 1);
t1 = gpoint(1, 1);
start_time = gpoint(1, 1);
end_time = 0;
car_num = gpoint(2, 1);
if psize>1
for i = 2:psize
p2 = gpoint(2:end, i);
if p2(1) == p1(1) %车号相同
if sum(p1==p2)~=plen %干扰信号变了
end_time = gpoint(1, i);
break
else
eq_ct = eq_ct + 1; %记录相同的列
eq_col(eq_ct) = i;
eq_time(eq_ct) = gpoint(1, i);
end
end
end
end
if end_time == 0 %如果一直没变,则干到最后一时刻
min_hour = floor(start_time/100);
min_minute = mod(start_time, 100);
min_time = min_hour*60 + min_minute + 20;
min_hour = floor(min_time/60);
min_minute = mod(min_time, 60);
min_time = min_hour*100 + min_minute;
end_time = min(final_time, min_time);
end
kk = find(Gtime==start_time);
cmp_time = Gtime(kk+1:end);
cmp_size = size(cmp_time, 2);
flagg = 0;
for bb = 1:eq_ct
if cmp_time(bb)~=eq_time(bb)
end_time = cmp_time(bb);
flagg = 1;
break;
end
end
if flagg==0 & cmp_size > eq_ct
end_time = cmp_time(eq_ct + 1);
end
p_ct = p_ct + 1;
psig = p1(2:end);
pout = [start_time end_time car_num psig']';
Fout(:, p_ct) = pout;
eq_col(eq_ct+1) = 1; %加上第一列
eq_col(:,all(eq_col==0,1)) = [];%去掉全零列
gpoint(:, eq_col) = []; %删掉所有相同列
end
Fout(:,all(Fout==0,1)) = [];%去掉全零列
fsize = size(Fout, 2); %还原定频信号
for i = 1:fsize
tskF = Fout(4:7, i);
for k = 1:4 %根据定频代号找到对应频点
a = tskF(k);
if a==0
break
end
b = find(Fsp(1, :)==a);
c = Fsp(2, b);
Fout(k+3, i) = c;
end
end
end
%% write_point函数的实现:写频点表
function write_point(file_name)
global Pout;
global Fout;
global Gtime;
date_name = datestr(now,'yyyymmddHHMMSS');
file_name = strcat(file_name, date_name);
file_name = strcat(file_name, '.xls');
fprintf('正在将频点保存到"%s",不要退出!!!请稍等.......\n', file_name);
a = '干扰频率M';
b = '拦阻带宽M';
c = '谱间隔K';
d = '干扰带宽K';
e = '开始时刻';
f = '停止时刻';
g = '干扰样式';
h = '方向(度)';
j = '站号';
k = '波道';
xlswrite(file_name, {a}, 'Sheet1', 'A1');
xlswrite(file_name, {b}, 'Sheet1', 'B1');
xlswrite(file_name, {c}, 'Sheet1', 'C1');
xlswrite(file_name, {d}, 'Sheet1', 'D1');
xlswrite(file_name, {e}, 'Sheet1', 'E1');
xlswrite(file_name, {f}, 'Sheet1', 'F1');
xlswrite(file_name, {g}, 'Sheet1', 'G1');
xlswrite(file_name, {h}, 'Sheet1', 'H1');
xlswrite(file_name, {j}, 'Sheet1', 'I1');
xlswrite(file_name, {k}, 'Sheet1', 'J1');
gct = 1; %行数
allR = size(Gtime, 2);
for i = 1:allR %按时间先后顺序写Pout和Fout
time = Gtime(i);
%先找跳频
findp = find(Pout(1, :)==time);
if ~all(findp==0)
psize = size(findp, 2);
for j = 1:psize
gct = gct + 1;
col = findp(j); %找到Pout对应列
%先获取该列值
point = Pout(8:end, col);
width = 25;
start_time = Pout(1, col);
end_time = Pout(2, col);
style = '离散谱';
car = Pout(7, col);
sig = Pout(3:6, col);
sig(all(sig==0,2),:) = [];%去掉全零行
%先写时间
hour = floor(start_time/100);
minute = mod(start_time, 100);
second = 0;
time1_str = [num2str(hour) ':' num2str(minute) ':' num2str(second)];
Estr = ['E' num2str(gct)];
xlswrite(file_name, {time1_str}, 'Sheet1', Estr);
hour = floor(end_time/100);
minute = mod(end_time, 100);
second = 0;
time2_str = [num2str(hour) ':' num2str(minute) ':' num2str(second)];
Fstr = ['F' num2str(gct)];
xlswrite(file_name, {time2_str}, 'Sheet1', Fstr);
%写带宽
Dstr = ['D' num2str(gct)];
xlswrite(file_name, width, 'Sheet1', Dstr);
%写样式
Gstr = ['G' num2str(gct)];
xlswrite(file_name, {style}, 'Sheet1', Gstr);
%写站号
Istr = ['I' num2str(gct)];
xlswrite(file_name, car, 'Sheet1', Istr);
%写频率
Astr = ['A' num2str(gct)];
p_str = char(join(string(point), ','));
xlswrite(file_name, {p_str}, 'Sheet1', Astr);
%写波道
Jstr = ['J' num2str(gct)];
j_str = char(join(string(sig), ','));
xlswrite(file_name, {j_str}, 'Sheet1', Jstr);
end
end
%再找定频
findf = find(Fout(1, :)==time);
if ~all(findf==0)
fsize = size(findf, 2);
for k = 1:fsize
gct = gct + 1;
col = findf(k); %找到Fout对应列
%先获取该列值
point = Fout(4:end, col);
point(all(point==0,2),:) = [];%去掉全零行
width = 25;
start_time = Fout(1, col);
end_time = Fout(2, col);
style = '多目标';
car = Fout(3, col);
%先写时间
hour = floor(start_time/100);
minute = mod(start_time, 100);
second = 0;
time1_str = [num2str(hour) ':' num2str(minute) ':' num2str(second)];
Estr = ['E' num2str(gct)];
xlswrite(file_name, {time1_str}, 'Sheet1', Estr);
hour = floor(end_time/100);
minute = mod(end_time, 100);
second = 0;
time2_str = [num2str(hour) ':' num2str(minute) ':' num2str(second)];
Fstr = ['F' num2str(gct)];
xlswrite(file_name, {time2_str}, 'Sheet1', Fstr);
%写带宽
Dstr = ['D' num2str(gct)];
xlswrite(file_name, width, 'Sheet1', Dstr);
%写样式
Gstr = ['G' num2str(gct)];
xlswrite(file_name, {style}, 'Sheet1', Gstr);
%写站号
Istr = ['I' num2str(gct)];
xlswrite(file_name, car, 'Sheet1', Istr);
%写频率
Astr = ['A' num2str(gct)];
p_str = char(join(string(point), ','));
xlswrite(file_name, {p_str}, 'Sheet1', Astr);
end
end
end
fprintf('成功将频点保存到"%s"\n', file_name);
disp('==============================END=============================');
end