How can I change the rows of a nchoosek matrix to zero, according to a specific pattern, and avoid nested while loops?

1 回表示 (過去 30 日間)
Hi, I have the following matrix:
combs45 = nchoosek(1:45,2);
I want to change some of its rows to zero as follows:
%i=row number
combs45(1,:)=0 %i=1
combs45(2,:)=0 %i=1+1
combs45(45,:)=0 %i=1+44
%combs45(88,:) keep as it is ,i=1 +44 + 43
combs45(130,:) =0 %i=1+ 44 + 43 + 42
combs45(131,:)=0 %i=1 + 44 + 43 + 42 + 1
combs45(171,:)= 0 %i = 1 + 44 + 43 + 42 + 41
%combs45(211,:) keep, i=1 + 44 + 43 + 42 + 41 +40
combs45(250,:) = 0 %i= 1+ 44 + 43 + 42+ 41 + 40 + 39
combs45(251,:) = 0 %i=1 + 44 + 43 + 42 + 41 + 40 + 39 +1
and so on, until the end of the matrix.
I think the pattern is obvious in terms of what i is incremented by, also I want to keep the row unchanged when the number of steps can be exactly divided by 4.
Basically I don't want to pair together any of the elements inside the triplets (1,2,3), (4,5,6), ..., (43,44,45). Specifically, I don't want to pair 1 with 2 or 3, and 2 with 3, then I don't want to pair 4 with 5, etc, but I'm okay pairing 1 with 4, and 4 with 7, etc.
So I thought that in the 45 choose 2 matrix I want to first change the rows of those pairs (e.g., row1 is [1 2]) to 0 (so make row 1 [0 0]), and then remove the 0 elements from the matrix.
I wrote the following code but it's taking too long to run so I don't know if it's actually any good:
combs45=nchoosek(1:45,2);
i=1;
j=44;
count = 0;
while i<=45
while j>0
if mod(count,4)~=0
combs45(i,:)= 0;
count = count+1;
if mod(count,2)== 0
i=i+1;
combs45(i,:)= 0;
count = count+1;
else
i=i+j;
combs45(i,:)= 0;
count = count+1;
j = j-1;
end
else
count = count+1;
j = j-1;
i = i+j;
end
end
end
I'm wondering if there's a faster code I can run (or if there is a better pattern I can find and then adapt the code accordingly). Any help would be appreciated, thank you!
  6 件のコメント
John D'Errico
John D'Errico 2018 年 6 月 26 日
編集済み: John D'Errico 2018 年 6 月 26 日
Emotional? Sigh. I pointed out that your question was highly ambiguous? And I even fixed it to be readable.
Jan
Jan 2018 年 6 月 27 日
編集済み: Jan 2018 年 6 月 27 日
@Oana Cucu: This is a forum for solving questions concerning Matlab. Your question matches the topic and is welcome here.
It is not easy to understand, what you want to achieve, but it is the nature of questions, that some details are not clear. In consequence questions for clarifications are typical for the process of finding a solution.
The members of the forum tell newcomers several times each day to apply a proper formatting. This can become frustrating for the long-term users of the forum, especially because many users still do not care about the instructions - but you did. Thanks!
John D'Errico is not a bunny. There is no reason to threaten to report this to MathWorks, because John is well known in this forum. He offers very useful support for solving Matlab problems and I appreciate his contributions, because they are excellent from the technical point of view. My personal opinion is, that he is not the best teacher for courteousness - but nobody cares about my personal opinions here, except if they concern questions of Matlab problems. Nevertheless, I do not see that his comments here are emotional or aggressive. I think, you will understand the nature of his attitude, if you read some thousands of his contributions or if some of his marvelous tools from the FileExchange saved you days or weeks of work.
I think, this is the most successful way to go: "Thanks and have a nice day!"

サインインしてコメントする。

採用された回答

Ameer Hamza
Ameer Hamza 2018 年 6 月 26 日
編集済み: Ameer Hamza 2018 年 6 月 26 日
Here is my attempt to generate the pattern as described in your question, there might be more efficient ways.
combs45 = nchoosek(1:45,2);
i_pattern = 1; % first pattern value
startNumber = 44;
count = 2;
while i_pattern(end) < size(combs45, 1)
nextValue = 1;
if mod(count, 4) == 2
nextValue = i_pattern(count-1) + 1;
elseif mod(count, 4) == 3
nextValue = i_pattern(count-2) + startNumber;
startNumber = startNumber - 1;
else
nextValue = i_pattern(count-1) + startNumber;
startNumber = startNumber - 1;
end
i_pattern = [i_pattern nextValue];
count = count+1;
end
disp(i_pattern)
Columns 1 through 13
1 2 45 88 130 131 171 211 250 251 288 325 361
Columns 14 through 26
362 396 430 463 464 495 526 556 557 585 613 640 641
Columns 27 through 39
666 691 715 716 738 760 781 782 801 820 838 839 855
Columns 40 through 52
871 886 887 900 913 925 926 936 946 955 956 963 970
Columns 53 through 59
976 977 981 985 988 989 990
Then to set the required rows to zero
i_pattern(4:4:end) = []; % delete every 4th entry.
combs45(i_pattern, :) = 0;
I tried running your code and It appears to be wrong since the value of count exceeds beyond the length of combs45.
  3 件のコメント
Ameer Hamza
Ameer Hamza 2018 年 6 月 26 日
編集済み: Ameer Hamza 2018 年 6 月 26 日
You are welcome. I was also not able to completely run your code, it appears to be an infinite loop. I just paused the code to see the variable values, pausing the code is a good point to remember while debugging your code.
Oana Cucu
Oana Cucu 2018 年 6 月 26 日
編集済み: Oana Cucu 2018 年 6 月 26 日
I think I know what you mean, is that when the 'continue debugging' button normally appears? This time it didn't, but I wrote disp(i) in the code at the end of every 'if' statement and then left it running, and it still is running even though I cliked 'Pause', now it's over 500,000. I guess I don't understand since the code has the condition 'i<=45'?

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by