信号干扰资源调度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
posted @ 2022-10-03 23:13  z5onk0  阅读(90)  评论(0编辑  收藏  举报