簡體   English   中英

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

[英]MATLAB function: improving speed/performance of code

我正在嘗試編寫一個函數(參見下面的代碼),該函數將創建一個機場列表,其中有1,000多個航班離開或到達,然后提供包含(x,y)格式的每個機場的索引的向量。 機場和飛行數據分別位於尺寸為1x6267和1x136010的單獨結構中,並且每個機場和航班都具有與其結構中的列對應的唯一ID號。 雖然我編寫的代碼確實成功識別了1000多個合並到達/離開的機場,但該功能需要近20分鍾才能執行,並且只提供機場的ID號,而不是機場結構中的索引號。 我需要對代碼進行哪些更改才能使其運行時間低於5分鍾,以及如何為機場創建(x,y)索引向量? 任何幫助將不勝感激! 謝謝!

PS我對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

以下是數據庫外觀/行為的一些示例:

(In Workspace)
airports <1x6267 struct>
aircraft <1x384 struct>
airlines <1x1559 struct>
flights <1x136010 struct>

(Inside of struct)
flights(1,6) <1x1 struct>
**Field**       **Value**
airline_id    60
from_id       967
to_id         6252
aircraft_id   18
distance      32
airtime       19
passengers    0
month         1

flights(1,6).from_id <1x1 double>
967


airport(1,176) <1x1 struct>
**Field**       **Value**
code          'AEX'
name          'Alexandria, LA: Alexandria International'

airport(1,176).name <1x40 char>
'Alexandria, LA: Alexandria International'

(In Command Window)

>> airports (2866)

ans = 

    code: 'LAX'
    name: 'Los Angeles, CA: Los Angeles International'

>> airports (1, 2866)

ans = 

    code: 'LAX'
    name: 'Los Angeles, CA: Los Angeles International'

>> airports (4703)

ans = 

    code: 'SEA'
    name: 'Seattle, WA: Seattle/Tacoma International'

>> airports (1, 4703)

ans = 

    code: 'SEA'
    name: 'Seattle, WA: Seattle/Tacoma International'

>> flights (4736)

ans = 

     airline_id: 31
        from_id: 1635
          to_id: 1062
    aircraft_id: 194
       distance: 118
        airtime: 1792
     passengers: 1657
          month: 1

>> flights (1, 4736)

ans = 

     airline_id: 31
        from_id: 1635
          to_id: 1062
    aircraft_id: 194
       distance: 118
        airtime: 1792
     passengers: 1657
          month: 1

>> flights(1,7369).to_id

ans =

   830

>> flights(1,7369).from_id

ans =

        1047

您的整個FlightsToFrom()函數可以完全矢量化,從而產生以下結果(還有一些額外的小改進):

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

這可能是進一步的矢量化,但我認為僅僅通過這些小的變化產生的加速應該足以使性能調整的任何進一步投資成為學術而非實際問題。

為了加快速度,我建議

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

關於第二個問題,機場是怎樣的? 目前您正在使用循環索引,這與機場ID相同嗎?

如果可能,請提供一些示例數據。 例如,這樣一段代碼生成與您的實際數據匹配的隨機輸入數據:

numOfAirports=100
numOfFlights=10000
for idx=1:numOfFlights
    flights(idx).fromId=randi(numOfAirports);flights(idx).toId=randi(numOfAirports);
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)); 

將為您提供出發/到達次數最多的機場坐標列表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM