2013-11-01 79 views
4

給定一個整數n,我想得到如下的矢量。例如。如果n = 3,那麼向量應該是[1,1,2,1,2,3],如果n = 4,則向量應該是[1,1,2,1,2,3,1,2,3 ,4]等等。有沒有簡單的方法來做到這一點?謝謝。用matlab生成增量值的矢量

+0

如何數字高,你可能有n個? – PearsonArtPhoto

+0

@PearsonArtPhoto當然不超過1000。謝謝。 – user2945166

回答

2

下面是一個使用了「上三角矩陣」函數來從全序列的簡單重複選擇所需的條目的溶液:

A = triu(repmat((1 : n)', 1, n)); 
A = A(A ~= 0)' 

triu設置下面的對角線一切爲零。這種方法僅適用於原始序列不包括零的情況,當然這是爲1 : n給出的。不過,一個更好的解決辦法可能是使用的triu結果只用於索引:

A = repmat((1 : n)', 1, n); 
A = A(triu(ones(n)) ~= 0); 

這是相當快,在1秒以下運行時對於n = 10,000我的機器上。如Dennis Jaheruddin指出的,這種方法需要的暫時內存比臨時內存少兩倍(精確因子是2 n /(n + 1))。

1

以下是另外三種方法。我期望他們比@A的矢量化解決方案更有效率。 Donda或@Mohsen,但當然對於n = 1000或更少,這不太可能是一個問題。

最有趣的部分是兩種方法之間的速度差異,第二個和第三個也可以在一秒鐘內爲n=10000工作,但第一個更慢!

n = 1000; 

% Slow vector growing 
tic 
v=[]; 
for t = 1:n 
    v = [v 1:t]; 
end 
toc % 0.6 sec 


tic 
% Fast vector growing 
v=[]; 
for t = 1:n 
    x = 1:t; 
    v(end+x) = x; 
end 
toc % 0.01 sec 

tic 
% Preallocated loop 
v=zeros(n*(n+1)/2,1); 
count = 0; 
for t = 1:n 
    x = 1:t; 
    v(count+x) = x; 
    count = count+t; 
end 
toc % 0.01 sec as well 
+0

速度差異很有趣。不確定,但是可以通過將'v'預先分配給n(n + 1)/ 2個元素來使兩種方法更快,但是當然您需要明確指出每個新子序列的寫入位置。 –

+0

@A。Donda事實上,當我偶然發現這件事時,我正在做這件事。在通過第二種方法找到加速之後,我決定停止,因爲我會以簡單交易的速度進行交易。 –

+0

在我的'n = 1000'的基準測試中,你的'預分配循環'方法比'快速向量增長'方法快兩倍,但仍比'cumsum'慢兩倍。 –

3

你得到使用此

w=ones(1,n*(n+1)/2); 
w(1+cumsum(1:n-1))=-(0:n-2); 
w=cumsum(w); 

在我的機器一個快速的解決方案,丹尼斯的解決方案是爲最快n<=8,但之後這種方法是最快的。

使用這個基準測試代碼:

n=2000; 
N=1e6/n; 

tic 
for k=1:N 
    A = repmat((1 : n)', 1, n); 
    A = A(triu(ones(n)) ~= 0); 
end 
toc 


tic 
for k=1:N 
    w=ones(1,n*(n+1)/2); 
    w(1+cumsum(1:n-1))=-(0:n-2); 
    w=cumsum(w); 
end 
toc 

tic 
for k=1:N 
    %// Fast vector growing 
    v=[]; 
    for t = 1:n 
     x = 1:t; 
     v(end+x) = x; 
    end 
end 
toc 

對於n=4

Elapsed time is 5.688693 seconds. 
Elapsed time is 3.576366 seconds. 
Elapsed time is 1.878887 seconds. 

對於n=8

Elapsed time is 2.985184 seconds. 
Elapsed time is 1.851967 seconds. 
Elapsed time is 1.834574 seconds. 

對於n=100

Elapsed time is 1.084404 seconds. 
Elapsed time is 0.352033 seconds. 
Elapsed time is 2.502724 seconds. 

對於n=1000

Elapsed time is 15.625361 seconds. 
Elapsed time is 3.949131 seconds. 
Elapsed time is 11.497764 seconds. 

對於n=2000

Elapsed time is 29.940548 seconds. 
Elapsed time is 7.649394 seconds. 
Elapsed time is 22.846367 seconds. 
+1

不錯! ......... –

+0

嗯,我不打算,但如果有速度比較,我會寫更快的循環替代我想到的。不知道它與cumsum方法相比如何。 - 更新:預分配的循環(當然)比增長的循環更快,但是(當然)不如您的矢量化解決方案快。 –

+0

直觀的'triu'方法非常聰明的選擇。 – chappjc