Dato un intervallo intero e un numero all'interno di tale intervallo, qual è il modo ragionevolmente robusto ed efficace per selezionare casualmente un nuovo numero nell'intervallo in modo tale che non sia uguale al numero specificato?
Ogni volta che ho bisogno di farlo, di solito uso qualcosa come:
// Randomly choose an integer within an inclusive range with the condition
// that the result not equal the previous number chosen
// INPUT: lastNum is an int in the range [minVal, maxVal]
int ChooseNewNumber(lastNum){
minVal = 0;
maxVal = N; // This would usually be a value like someContainer.size - 1
intervalLength = maxVal - minVal + 1;
// Assume RandomInt...() is an existing function that lives up to its name
int newNum = RandomIntWithinInclusiveRange(minVal, maxVal);
if (newNum == lastNum){
// Add a random offset to newNum and wrap around if necessary
newNum = (newNum+RandomIntWithinInclusiveRange(1, intervalLength - 1)) % (maxVal+1);
}
return newNum;
}
Funziona e sembra evitare l'introduzione di qualsiasi bias nel caso newNum == lastNum
, ma è un po 'goffo. C'è un modo più pulito per realizzare la stessa cosa?
EDIT: come sottolineato da coredump, il metodo sopra non funziona se minVal != 0
. Solo per riferimento, la linea:
newNum = (newNum+RandomIntWithinInclusiveRange(1, intervalLength - 1)) % (maxVal+1);
dovrebbe essere:
new = ((new + RandomIntWithinInclusiveRange(1, intervalLength - 1) - minVal) % intervalLength) + minVal;
Mi rendo conto che questo errore ha dato l'impressione che minVal
potrebbe sempre essere 0; mi dispiace per questo.