我正在开发一个程序来计算飞机飞过目标区域时可以看到什么。当它越过该区域时,它可以遵循许多轨道之一,正常区域大小约为 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 探查器在我的程序的瓶颈处确定了这一点。任何帮助将非常感激。 谢谢,里奇
最佳答案
我不太清楚您要做什么,但我建议首先用逻辑索引替换内部循环。
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
使用逻辑索引,您可以用单个操作替换嵌套循环的数百万次迭代。
这里有另一个提示:使用逻辑矩阵而不是 double 矩阵来存储真/假值。
>>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
关于matlab - 简化 for 循环(matlab),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10988122/