Asked by Muhammad Nabeel Hussain
on 26 Sep 2019

I want to genetate two vector X(size=37x1) and Y(size=37x1) of random numbers between

100 to 1900 such that difference between any two numbers of one vector X or Y should be greater than 200.

I have tried generating random number again and again while rejecting if they dont met constraint.

but it make infinte loop.

Actually X and Y are cordinates of turbines. Constraint is no turbine can be in the 200 meter radius of any other turbine. Any idea for doing this very fast? Thanks

Answer by Adam Danz
on 26 Sep 2019

Edited by Adam Danz
on 26 Sep 2019

Accepted Answer

This takes milliseconds.

The main idea is to start off with a set of random coordinates and continually replace coordinates that are too close to another coordinate until either 1) all distances are less than the minimum distance requirement or 2) 100 attempts were made per coordinate.

%Define parameters

nPoints = 37; %number of coordinates

lim = [100,1900]; %bounds of random numbers

minDist = 200; %minimum distance between turbines

% Create random coordinates and continually replace coordinates

% that are too close to another point. Stop when minimum distance

% is satisfied or after making nPoints*100 attempts.

xy = nan(nPoints,2);

c = 0; %Counter

while any(isnan(xy(:))) && c<(nPoints*100)

% Fill NaN values with new random coordinates

xy(isnan(xy)) = rand(1,sum(isnan(xy(:)))) * (lim(2)-lim(1)) + lim(1);

% Identify rows that are too close to another point

[~,isTooClose] = find(triu(squareform(pdist(xy)) < minDist,1));

% Replace too-close coordinates with NaN

xy(isTooClose,:) = NaN;

c = c+1;

end

% Throw error if the loop had to quit and missing values remain

if any(isnan(xy(:)))

error('The while-loop gave up. There are %d coordinates with missing values.',sum(isnan(xy(:,1))))

end

% Display number of attempts

fprintf('%d number of attempts.\n', c)

% Show the minimum distance

distances = squareform(pdist(xy));

fprintf('Min distance = %.2f\n', min(distances(distances~=0)))

% Plot results

figure()

plot(xy(:,1),xy(:,2), 'ks', 'MarkerSize', 10)

grid on

These data in the figure above were produced in <0.08 sec and the minimum distance between coordinates is 205.52.

Muhammad Nabeel Hussain
on 26 Sep 2019

Adam Danz
on 26 Sep 2019

Glad I could help.

Sign in to comment.

Answer by Bruno Luong
on 26 Sep 2019

Similar question has been answered in this thread

Sign in to comment.

Answer by Jos (10584)
on 26 Sep 2019

Brute force attempt:

N = 20 ;

xyRange = [100 1900] ;

minimumDistance = 200 ;

attempt_counter = 1 ;

Distances = 0 ;

while any(Distances < minimumDistance) && attempt_counter < 10000

attempt_counter = attempt_counter + 1 ;

Pxy = randi(xyRange, N, 2) ;

Distances = pdist(Pxy) ;

end

if attempt_counter < 1000

plot(Pxy(:,1), Pxy(:,2),'bo') ;

else

disp('No positions found.') ;

end

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 6 Comments

## Bruno Luong (view profile)

## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/482247-how-to-genetate-random-number-under-constraint#comment_750158

## Muhammad Nabeel Hussain (view profile)

## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/482247-how-to-genetate-random-number-under-constraint#comment_750162

## Adam (view profile)

## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/482247-how-to-genetate-random-number-under-constraint#comment_750166

## Bruno Luong (view profile)

## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/482247-how-to-genetate-random-number-under-constraint#comment_750182

## Adam Danz (view profile)

## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/482247-how-to-genetate-random-number-under-constraint#comment_750183

## Adam Danz (view profile)

## Direct link to this comment

https://it.mathworks.com/matlabcentral/answers/482247-how-to-genetate-random-number-under-constraint#comment_750185

Sign in to comment.