3

我正在开发一个程序来计算飞机在目标区域上空飞行时可以看到什么。当它越过该区域时,它可以跟随许多轨道之一,正常区域大小约为 100。我创建了一个大循环来查看飞机是否可以看到该区域的某些部分,但它的运行效率非常低。我已将该区域定义为 1001x1001 的网格

xgrid 定义 x 值的变量 1001x1。

thelines 是一个变量 2 x 1001 x 轨道,其中第一行是顶行对应 x 值处的 y 值。第二行是底线的 y 值。

这两条线之间是可见区域。如果可以看到,则将 seenarea(1001x1001) 上的点标记为 1。如果不是,则将其标记为 0。

for M=1:tracks
    for f=1:1001
        for i=1:1001
            if xgrid(f,1)>thelines(i,1,M) && xgrid(f,1)<thelines(i,2,M);
                seenarea(f,i,M)=1; % This indicated the area has been seen
            else
                seenarea(f,i,M)=0; % This is not seen
            end
        end
    end
    fullbestinfo(1,M)={seenarea(:,:,M)}; % This stores the seen area in another cell
    if max(seenarea(:,:,M)) < 1 % No area seen, stop
        seenarea(:,:,M)=[];
        break
    end
end

我已经使用 matlab 分析器在我的程序的瓶颈处确定了这一点。任何帮助将非常感激。谢谢,丰富

4

1 回答 1

7

我不能完全说出你想要做什么,但我建议作为第一步用逻辑索引替换内部循环。

seenarea = false(1001, 1001, tracks); #% preallocate matrix to 'false'
xgrid = repmat(1:1001, 1001, 1); #%same size as the first 2D of seenarea

for M=1:tracks
    border1 = thelines(:,ones(1,1001),M); #% same size as xgrid
    border2 = thelines(:,ones(1,1001)*2,M); #% same size as xgrid
    idx = xgrid > border1 & xgrid < border2; #% idx is a "logical index" 
             #%           ^--- single ampersand
    seenarea(idx,M)=true; 
end

使用逻辑索引,您可以用单个操作替换嵌套循环的数百万次迭代。

这是另一个提示:使用逻辑矩阵而不是双矩阵来存储真/假值。

>>m1 = zeros(1001,1001,100);
>> m2 = false(1001,1001,100);
>> whos m1
  Name         Size                      Bytes  Class     Attributes

  m1        1001x1001x100            801600800  double              

>> whos m2
  Name         Size                      Bytes  Class      Attributes

  m2        1001x1001x100            100200100  logical 

如您所见,逻辑矩阵的内存使用量降低了 8 倍。

速度测试:我很好奇这会有多大的不同。下面是一个快速测试(好吧,只对其中一种实现快速)。对内部循环进行矢量化使我的机器速度提高了大约 75 倍,将 10 个轨道的时间从 7 秒以上减少到大约 0.1 秒。

tic;
for rep=1:100
    for M=1:tracks
        for f=1:1001
            for i=1:1001
                if xgrid(f,1)>thelines(i,1,M) && xgrid(f,1)<thelines(i,2,M);
                    seenarea(f,i,M)=1; 
                else
                    seenarea(f,i,M)=0; 
                end
            end
        end
    end
end
disp(toc/100)
    7.3459

tic;
for rep=1:100
    for M=1:tracks
        border1 = thelines(:,ones(1,1001),M); 
        border2 = thelines(:,ones(1,1001)*2,M); 
        idx = xgrid > border1 & xgrid < border2;                     
        seenarea(idx,M)=true; 
    end
end
disp(toc/100)
    0.0964

>> 7.3459/.0964    
ans =    
   76.2023
于 2012-06-11T22:34:18.107 回答