Performance MATLAB功能:提高代码的速度/性能

Performance MATLAB功能:提高代码的速度/性能,performance,matlab,optimization,vector,indexing,Performance,Matlab,Optimization,Vector,Indexing,我正在尝试编写一个函数(见下面的代码),该函数将创建一个机场列表,其中有1000多个航班起飞或抵达,然后提供一个向量,其中包含(x,y)格式的每个机场的索引。机场和航班数据分别存放在尺寸为1x6267和1x136010的单独结构中,每个机场和航班都有一个唯一的ID号,对应于结构中的列。虽然我编写的代码确实成功地识别了1000多个到达/离开机场的所有机场,但该函数执行几乎需要20分钟,并且只提供机场的ID号,而不提供机场结构中的索引。为了使代码的运行时间在5分钟以下,我需要对代码进行哪些更改?如何

我正在尝试编写一个函数(见下面的代码),该函数将创建一个机场列表,其中有1000多个航班起飞或抵达,然后提供一个向量,其中包含(x,y)格式的每个机场的索引。机场和航班数据分别存放在尺寸为1x6267和1x136010的单独结构中,每个机场和航班都有一个唯一的ID号,对应于结构中的列。虽然我编写的代码确实成功地识别了1000多个到达/离开机场的所有机场,但该函数执行几乎需要20分钟,并且只提供机场的ID号,而不提供机场结构中的索引。为了使代码的运行时间在5分钟以下,我需要对代码进行哪些更改?如何为机场创建(x,y)索引向量?任何帮助都将不胜感激!谢谢

另外,我对MATLAB还比较陌生,所以如果这些问题看起来很愚蠢或明显,我会提前道歉

function list = Problem10( flights, aircraft, airlines, airports )
a=zeros(1,(length(airports)));
for id=1:length(airports)
    a(id)= FlightsToFrom(flights, id);
end
a(a==0) = [];
[list]=[sort(a)]
end

function tofrom = FlightsToFrom(flights, ID)
sum=0;
for ii=1:length(flights)
    if (isequal (flights(1,ii).from_id, ID))||(isequal (flights(1,ii).to_id, ID))
        sum=sum+1;
        if sum > 1000
            break;
        end
    end
end
if sum <=1000
    tofrom=0;
else
    tofrom=ID;
end
end
功能列表=问题10(航班、飞机、航空公司、机场)
a=零(1,(长度(机场));
对于id=1:长度(机场)
a(id)=航班起飞(航班,id);
结束
a(a==0)=[];
[列表]=[排序(a)]
结束
函数tofrom=FlightsToFrom(航班,ID)
总和=0;
对于ii=1:长度(航班)
如果(isequal(航班(1,ii)。从| id,id)到| |(isequal(航班(1,ii)。到| id,id))
总和=总和+1;
如果总和>1000
打破
结束
结束
结束
如果总和>机场(2866)
ans=
代码:“LAX”
名称:'洛杉矶,加利福尼亚州:洛杉矶国际'
>>机场(12866)
ans=
代码:“LAX”
名称:'洛杉矶,加利福尼亚州:洛杉矶国际'
>>机场(4703)
ans=
代码:“海”
名称:'华盛顿州西雅图:西雅图/塔科马国际'
>>机场(14703)
ans=
代码:“海”
名称:'华盛顿州西雅图:西雅图/塔科马国际'
>>航班(4736)
ans=
航空公司代码:31
发件人:1635
收件人:1062
飞机识别号:194
距离:118
播放时间:1792
乘客:1657
月份:1
>>航班(14736)
ans=
航空公司代码:31
发件人:1635
收件人:1062
飞机识别号:194
距离:118
播放时间:1792
乘客:1657
月份:1
>>航班号(17369)。到
ans=
830
>>航班号(17369)。从
ans=
1047

为了加快速度,我建议

function tofrom = FlightsToFrom(flights, ID)
assert(~exist('sum','var'))
nflights=sum([flights.fromId]==ID)+sum([flights.toId]==ID);
if nflights <=1000
    tofrom=0;
else
    tofrom=ID;
end
end

代码中需要花费时间的是在整个航班列表中循环6267次,因为您为每个机场调用FlightsToFrom函数。。。如果你只需在飞行中循环一次就可以解决这个问题,那么程序的运行速度将提高6267倍,也就是一秒钟的几分之一。我不太清楚你所说的“机场指数x,y的向量”是什么意思——这个向量应该包含什么?在任何情况下,您至少可以通过以下方式进行循环:

a=zeros(length(airports),length(airports));
for id = 1:length(flights)
     a[flights(1,id).from_id, flights(1,id).to_id] = a[flights(1,id).from_id, flights(1,id).to_id]  + 1; 
end
最后,
a
是一个矩阵,包含从不同机场起飞的航班次数。a[5,6]将是从5号机场飞往6号机场的航班次数。然后,您可以使用MATLAB的内置函数对该矩阵进行处理,例如

[row, col] = find(a>1000); 
将为您提供发生超过1000次的往返航班的坐标

highdepartures = find(sum(a,1)>1000)); 
highdarrivals = find(sum(a,2)>1000)); 

将分别为您提供出发/到达次数最多的机场坐标列表

您的整个
FlightsToFrom()
函数可以完全矢量化,从而实现以下功能(还有一些额外的小改进):


这可能可以进一步矢量化,但我认为,仅通过这些小的更改所产生的加速应该足以使性能调整方面的任何进一步投资成为一个学术问题,而不是一个实际问题。

Daniel-非常感谢您的帮助!我尝试了你的第一个建议,不幸的是,它没有成功地产生正确的结果。与我使用原始函数得到的机场编号向量不同,这一次生成了空矩阵(我想是因为from_id和to_id分别位于flight struct的单独矩阵中)。循环索引确实与机场id相同。我将重新编辑我的问题,不包括一些样本数据,因此如果您有任何建议,请告诉我。再次感谢你的帮助!我更新了我的答案,假设函数sum和变量名sum存在一些问题。如果断言失败,则是某个全局变量和导致了问题。我刚刚尝试了您的建议,效果非常好!谢谢您的
flights
似乎是一个很好的数字和正方形。如果您想更有效/轻松地处理它,那么将这些信息存储在矩阵中而不是结构中应该会有所帮助。这可能也适用于其他一些结构。我同意矩阵会更简单、更有效。不幸的是,这是我正在学习的一门MATLAB课程的课堂练习的一部分,所以我不得不按照教授设置数据库的方式进行。这非常有效,并且大大缩短了时间……非常感谢!我想我已经被这个循环(这是我们最近在课堂上一直在做的,所以我认为这会是最好的)所困扰,以至于我无法找到这个更直接、更聪明的解决方案。你的回答很有帮助!
[row, col] = find(a>1000); 
highdepartures = find(sum(a,1)>1000)); 
highdarrivals = find(sum(a,2)>1000)); 
function a = Problem10( flights, aircraft, airlines, airports )
    numAirports = length(airports);
    a(numAirports) = 0;  % preallocate: faster than zeros()
    from_ids = [flights.from_id];
    to_ids   = [flights.to_id];
    for id = 1 : numAirports
        a(id) = id * (sum(from_ids==id | to_ids==id) > 1000);
    end
    a(~a) = [];
    %a = sort(a);  % unnecessary - a is already sorted at this stage, by ascending ID!
end