Questa non è statistica, la statistica non permette di fare previsioni, e le funzioni di php (in particolare mt_rand() che è meglio di rand()) forniscono una distrubuzione uniforme, nel senso statistico del termine, dei valori 'estratti'.
La soluzione che rispecchia quello che ti aspetti, è invece la seguente:
(1) generi un array di n elementi che vengono 'mischiati' tramite una funzione pseudocasuale.
(2) ogni volta che hai bisogno di un nuovo valore, lo estrai dall'array (shift o pop, non è importante).
(3) quando l'array ha raggiunto lunghezza zero, lo rigeneri.
Questa una possibile (semplice) soluzione:
class randomPool {
protected $min, $max, $dt = array();
function __construct($min, $max) {
$this->min = $min;
$this->max = $max;
}
function get() {
if (count($this->dt) === 0)
$this->generate();
return array_pop($this->dt);
}
protected function generate() {
// genera un array contenente i valori da $min a $max inclusi
// e poi li 'mischia'
$this->dt = range($this->min, $this->max);
shuffle($this->dt);
}
}
// esempio di uso
$r = new randomPool(1, 10);
for ($i = 0; $i < 100; $i++) echo $r->get() . ' ';
Naturalmente se hai la necessità che il tutto funzioni fra diverse pagine erogate da un web server hai bisogno di definire la persistenza della struttura:
(1) eg. in sessione nel caso il pool sia a disposizione di uno stesso utente
(2) eg. su db nel caso debba essere condiviso fra più utenti (in questo caso puoi usare strategie differenti che generano direttamente record con le caratteristiche che ti interessano in una tabella).