How to create random integer numbers its summation not equal to each other summation ??

2 vues (au cours des 30 derniers jours)
Moataz Mohsen
Moataz Mohsen le 29 Août 2015
Commenté : Walter Roberson le 30 Août 2015
suppose that I choose random integer number X = randi([100,4000],1,20); How to make condition that if random numbers contain 200, 300 and 500, the chosen of random number will be repeated as the sum of 200 + 300 equal 500 . also I refuse the random number if 175,200, 300, 600, 1100 as the sum of 200+300+600 equal 1100 which already included in the random numbers ??? any suggestion ??
  1 commentaire
the cyclist
the cyclist le 29 Août 2015
Do you need to check that every possible sum of any number of elements does not occur elsewhere in the vector? I'm not sure that that is computationally feasible for a 20-element vector.

Connectez-vous pour commenter.

Réponses (1)

Walter Roberson
Walter Roberson le 29 Août 2015
X = randi([100, 4000]);
for K = 2 : 20
while true
candidate = randi([100, 4000]);
if ismember(candidate, X); continue; end
summask = dec2bin(1:2^K-1)-'0';
inducedsums = summask * [X;candidate];
if length(inducedsums) ~= length(unique(inducedsums)); continue; end
X = [X;candidate];
break
end
end
This is not so bad for efficiency but it can be made more efficient.
  2 commentaires
Walter Roberson
Walter Roberson le 30 Août 2015
The above code has the potential to infinite loop if it reaches a point where none of the possibilities works. The below code checks each possibility only once and so has only about 3900 checks.
In my tests so far, it has not been possible to fill the 12th position onwards.
Nneeded = 20;
Low = 100; Hi = 4000;
candidates = Low : Hi;
canidx = randi(length(candidates));
X = candidates(canidx);
candidates(canidx) = [];
for K = 2 : Nneeded
fprintf('starting #%d\n', K);
Nsums = 2^K - 1;
summask = dec2bin(1:Nsums)-'0';
trycount = 0;
while ~isempty(candidates)
canidx = randi(length(candidates));
candidate = candidates(canidx);
candidates(canidx) = [];
trycount = trycount + 1;
inducedsums = summask * [X;candidate];
Ninduced = length(unique(inducedsums));
if Ninduced ~= Nsums
fprintf('%d try #%d: with candidate %d, there were %d duplicated sums (%d unique)\n', K, trycount, candidate, Nsums - Ninduced, Ninduced);
continue;
end
X = [X;candidate];
fprintf('%d try #%d: accepted candidate %d\n', K, trycount, candidate);
break
end
if isempty(candidates);
break;
end
end
if length(X) ~= Nneeded
fprintf('Ran out of candidates after creating %d random selections\n', length(X));
end
Walter Roberson
Walter Roberson le 30 Août 2015
The above turns out to be wrong, rejecting cases that you did not ask to reject. The revised code is:
candidates = 100:4000;
X = [];
for K = 1 : 20
summask = dec2bin(2^(K-1):2^K-1)-'0';
canidx = randi(length(candidates));
candidate = candidates(canidx);
X = [X;candidate];
inducedsums = summask * X;
candidates = setdiff(candidates, inducedsums);
end
Note: I do not understand your part "How to make condition that if random numbers contain 200, 300 and 500, the chosen of random number will be repeated as the sum of 200 + 300 equal 500." as it appears to contradict your part about rejecting candidates if they are the sum of earlier candidates. With what you wrote, 500 should be rejected as it is the sum of the earlier 200, 300. I do not understand what it is that would be repeated ?

Connectez-vous pour commenter.

Catégories

En savoir plus sur Debugging and Analysis dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by