Sorting numbers randomly in a specified range without changing their positions
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
A = [5 8 8 4 0 0 10 10 2 2];
Since A is in the range of 1:10, I want to sort A such that all the repeated numbers are replaced with numbers that hasn't appeared yet within 1 to 10, slotting those numbers in, randomly, without ascending or descending. All their initial positions should be maintained without changing. All zeros will also be replaced with non-zeros in this specified range. Maybe to get a result like below.
Ans = [5 8 1 4 7 3 10 6 9 2];
Accepted Answer
the cyclist
on 26 Nov 2021
% Input
A = [5 8 8 4 0 0 10 10 2 2];
% Find the pool of numbers that are available to fill
% (because they don't appear in A, but are in 1:10, in this case)
pool = setdiff(1:numel(A),unique(A));
% Find the locations to place the numbers
% (i.e. repeats and zeros)
loc = (diff([NaN A]) == 0) | (A==0);
% Fill the locations randomly from the pool
A(loc) = pool(randperm(numel(pool)))
A = 1×10
5 8 7 4 1 6 10 9 2 3
12 Comments
Thank you. It worked. But it didn't work for what I intend using it for. There are two issues... First is that A doesn't consist zeros, I made mistake putting zeros. So, assuming those zeros are ones, I went ahead to edit/erase the second part of line 8 of the code as below, and it worked.
loc = (diff([NaN A]) == 0);
The second issue is that I intend running this process for 50 particle solutions. I edited it into for-loop as below but I'm still getting repeated numbers in each solutions of the particles. Please help.
for i = 1:50
pool = setdiff(1:numel(p(i).Pos),unique(p(i).Pos));
loc = (diff([NaN p(i).Pos] ) == 0);
p(i).Pos(loc) = pool(randperm(numel(pool(i) )))
end
p(i).Pos is the 50 particles consisting of their solutions I intend working on.
the cyclist
on 26 Nov 2021
Can you upload an example of an input that does not give the expected result, and what you expected to see?
You could upload the data directly, ideally in a mat file, using the paperclip icon in the INSERT section of the toolbar.
Ayobami Meadows
on 26 Nov 2021
I have uploaded it to Dropbox link below because it contains different scripts to call. The main file is the PSO.m at line 100.
https://www.dropbox.com/s/way37zllcq0uzfg/UploadMathwork.rar?dl=0
the cyclist
on 26 Nov 2021
Sorry, I don't really want to download, unzip, figure out how to run your scripts, etc.
Can you please just upload and example of one vector that my algorithm does not give the expected result for?
for i = 1:50
% A vector scenario 'p' has been attached for illustration
pool = setdiff(1:numel(p(i).Pos),unique(p(i).Pos));
loc = (diff([NaN p(i).Pos]) == 0);
p(i).Pos(loc) = pool(randperm(numel(pool(i))));
% what is exxpected is not to see any repeated numbers in the
% updated solutions of p(i).Pos
end
Unrecognized function or variable 'p'.
Ah, I see. The problem is that in your original question, the repeated numbers were always consecutive, so my solution assumed that to be the case. Here is a modified solution:
% Input
A = [5 8 8 4 1 1 10 10 2 2 8];
% Find the unique values in A, and the locations of the first instance of
% those values
[uniqueA,locationFirstInstance] = unique(A);
% Find the pool of numbers that are available to fill
% (because they don't appear in A, but are in 1:11, in this case)
entireSet = 1:numel(A);
pool = setdiff(entireSet,unique(A));
% Find the locations of the repeated instances
loc = setdiff(entireSet,locationFirstInstance);
% Fill the locations randomly from the pool
A(loc) = pool(randperm(numel(pool)))
A = 1×11
5 8 11 4 1 3 10 7 2 6 9
You should be able to swap in p(i).Pos for A again, in your actual code.
Again it worked for A but didn't work for the particle loop p(i).Pos. The updated p(i).Pos still consists of repeated numbers. For example, the first particle p(1).Pos has the number 13 repeated three times in column 6, column 7 and column 8. Below is how I edited your code.
for i = 1:50
[uniqueP,locationFirstInstance] = unique(p(i).Pos);
entireSet = 1:numel(p(i).Pos);
pool = setdiff(entireSet,unique(p(i).Pos));
loc = setdiff(entireSet,locationFirstInstance);
p(i).Pos(loc) = pool(randperm(numel(pool(i))));
end
You had a small typo, which is corrected below:
for i = 1:50
[uniqueP,locationFirstInstance] = unique(p(i).Pos);
entireSet = 1:numel(p(i).Pos);
pool = setdiff(entireSet,uniqueP); % <---- I also made a small edit to this line, but it doesn't affect the algorithm
loc = setdiff(entireSet,locationFirstInstance);
p(i).Pos(loc) = pool(randperm(numel(pool))); % <--- Typo: You had numel(pool(i))
end
Ayobami Meadows
on 27 Nov 2021
Job done! Thank you!
Please I still have one more concern. What if the variable is in the form "sol(i,:)" instead of "p(i).Pos"?
Where my problem at is in the last line of the code.
for i = 1:50
[uniqueP,locationFirstInstance] = unique(Sol(i,:));
entireSet = 1:numel(Sol(i,:));
pool = setdiff(entireSet,uniqueP);
loc = setdiff(entireSet,locationFirstInstance);
(Sol(i,:)(loc)) = pool(randperm(numel(pool))); % <--- LHS: I'm having problem in assigning the variable name for loc
end
Sol(i,loc) = pool(randperm(numel(pool)));
Ayobami Meadows
on 4 Dec 2021
Great!
More Answers (0)
Categories
Find more on Search Path in Help Center and File Exchange
See Also
on 25 Nov 2021
on 4 Dec 2021
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)