How can I make a random exchange but impose a limit on the distance at which this number can move from its initial position?

advertisements

A set of 20 numbers have been stored inside a vector d, for example:

d = [ 5 6 7 8 9 ....]

I use

i = randperm(length(d));
d = d(i);

to randomly shuffle the numbers inside the matrix.

However, I need to find a way to limit the shuffle to ensure that the number does not move more then "5" places from its original position?

Meaning that if originally d(2) = 6, the final position of 6 should only move to d(1) to d(2+5).

Note, d(1) because the numbers cannot move to a negative position.

Any help on this would be appreciated! also, if there is a more efficient way with the shuffling please kindly let me know!


My solution would be to create a random permutation and swap bad indices as long as no index violates the distance rule.

d=data
delta=5;
i= randperm(length(d));
v=badPosition(i);
while(v~=0)
    %lower bound for position
    a=max(1,i(v)-5);
    %upper bound for position
    A=min(numel(i),i(v)+5);
    spos=randi([a,A]);
    h=i(v);
    i(v)=i(spos);
    i(spos)=h;
    v=badPosition(i);
end
d=d(i)


function pos=badPosition(indices)
delta=5;
allPos=(find(indices>(1:numel(indices))+delta|indices<(1:numel(indices))-delta));
if numel(allPos)>0
    pos=allPos(randi(numel(allPos)));
else
    pos=0;
end
end


badPosition is a function which returns 0 if all indices are okay or one index which violates the distance rule. If multiple violations exists, a random index is chosen.