Tempo medio di uscita di una stringa
Definizione
modificaNella teoria delle probabilità il tempo medio di uscita di una stringa è il calcolo della previsione di uscita di una stringa prefissata di caratteri estraendo casualmente le lettere da un insieme finito di caratteri, dato dalla formula , dove:
- è il numero totale di caratteri dell'alfabeto di riferimento
- è un insieme di indici che contiene i valori
- la posizione del primo carattere, pari a
- la posizione dell'ultimo carattere, pari alla lunghezza della stringa
- le posizioni di ogni sotto-stringa ripetuta all'interno della stringa
- è una variabile aleatoria che definisce il tempo di uscita della stringa
Per calcolare la previsione è necessario anche conoscere la probabilità di uscita di un carattere dall'insieme totale dei caratteri, dato da , dove è una variabile aleatoria che può assumere i valori di un carattere dell'alfabeto, mentre l'evento definisce l'uscita del carattere alla -esima estrazione.
Esempio
modificaSi calcola la previsione del tempo medio di uscita della parola ABRACADABRA utilizzando l'alfabeto inglese composto da ventisei lettere.
Utilizzando la definizione si ha che
Si osserva che contiene le posizioni del primo e dell'ultimo carattere, oltre alla posizione dell'ultimo carattere della sotto-stringa ABRA ripetuta.
Da ciò ne deriva che , ossia il tempo medio di uscita della parola ABRACADABRA è dopo aver effettuato circa miliardi di digitazioni casuali su una tastiera di caratteri.
Passaggio al limite
modificaSi può facilmente vedere che la previsione del tempo medio di uscita di una stringa è una funzione divergente all'aumentare del numero di caratteri da estrarre. Pertanto, il limite della previsione per un numero di caratteri che tende all'infinito è pari a infinito, ossia .
Intuitivamente si può calcolare il limite, considerando l'ipotesi che non esistano sotto-stringhe ripetute. Se questo limite tende a infinito a maggior ragione il limite nel caso di ripetizioni tende ad infinito. Si può non tenere conto dell'indice iniziale, pari sempre a uno, in quanto nel calcolo del limite sarebbe una costante. In base a queste considerazioni si osserva che e se il limite di per che tende a infinito è pari a infinito, allora anche il limite sarà pari a infinito. Per ogni la funzione è divergente, quindi .
Enunciato
modificaSia un insieme di caratteri, con . Si può definire una stringa prefissata di lunghezza caratteri tale che .
Sia uno spazio di probabilità, tale che , è una -algebra di e una misura di probabilità sullo spazio . Su questo spazio si può costruire una successione di variabili aleatorie tali che .
Sia il tempo più piccolo entro il quale al tempo la successione realizza la stringa . Si definisce il tempo di uscita della stringa.
Si prova che , con .
Dimostrazione
modificaSia una filtrazione tale che e , ossia la -algebra generata dalla successione di variabili aleatorie al tempo .
Osservazione 1
modificae sono dei tempi di arresto rispetto a
Per il paradosso di Borel , ossia la probabilità di ottenere la sequenza digitando casualmente le lettere di una tastiera è quasi certa. Da ciò deriva che . Anche è un tempo di arresto rispetto a in quanto, essendo una costante,
Osservazione 2
modifica
Si definisce una successione di variabili aleatorie indipendenti, per ogni fissato, tale che . La successione è indipendente in quanto è funzione della successione , anch'essa indipendente.
Per ogni si osserva che la previsione di è pari a uno. Infatti
Si pone
La successione è una -martingala.
Osservazione 2.1
modifica
Osservazione 2.2
modifica
Si pone , che per la trasformazione secondo Burkholder è anch'essa una -martingala.
Si trova il valore di quando .
Dato che stiamo considerando il caso che , il valore più piccolo tra e è proprio
Per definizione di , ossia il più piccolo tale che la stringa si realizzi, si ha in quanto esiste almeno un carattere compreso tra e dove . Come conseguenza si ha che e quindi
Osservazione 2.3
modifica
Si trova il valore di quando .
Ne segue che
In base all'osservazione 2.3 si ha che
Considerando che per definizione si ha che
Dato che la probabilità di una funzione indicatrice corrisponde all'evento stesso si ha che
Conclusione
modifica
Per l'osservazione 2 si ha che
Fissando e facendo variare si ottiene che
La somma per ogni della probabilità che il tempo di arresto sia uguale a equivale a calcolare la probabilità che sia finito, pari a per l'osservazione 1.
Pertanto si dimostra la tesi ottenendo che
Verifiche sperimentali
modificaSi può dimostrare sperimentalmente il tempo medio di uscita di una stringa implementando un algoritmo che simula l'estrazione casuale dei caratteri e campionando il numero di estrazioni necessarie a comporre una determinata parola. L'algoritmo può essere implementato attraverso un simulatore, oppure utilizzando un linguaggio di programmazione fornito di una libreria che implementi un generatore di numeri pseudo casuale. Di seguito si descrive un semplice algoritmo di esempio, scritto con il linguaggio ANSI C, che permette di campionare i tempi di uscita di una stringa. Successivamente si descrive come avviene il campionamento dei dati e si fa vedere che i dati tendono alla previsione matematica.
Algoritmo di campionamento
modificaPer effettuare un campionamento del tempo di uscita di una stringa è necessario implementare un algoritmo che effettui la stessa estrazione un certo numero di volte, solitamente maggiore di trenta. L'alfabeto di riferimento è quello inglese composto da ventisei lettere.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <time.h>
#define MIN_CAR 97
#define MAX_CAR 122
#define DELTA_CAR 26
#define MARKER_STR "-s"
#define MARKER_GIRI "-n"
#define MARKER_SID "-r"
#define MARKER_SAVE "-f"
#define MARKER_VERBOSE "-v"
#define VERBOSE_OFF "off"
int verbose;
unsigned long long estrai_stringa(int l, char * s){
unsigned long long n;
int k, maxk;
char c;
n = 0;
k = 0;
maxk = 0;
while (k < l){
if (n == ULLONG_MAX){
if (verbose == 1){
printf("raggiunto limite massimo di estrazioni: %llu\n", n);
printf("numero massimo di caratteri estratti: %d su %d\n", maxk, l);
fflush(stdout);
}
return 0;
}
c = (char) (MIN_CAR + (rand() % DELTA_CAR));
if (c == s[k]){
k++;
if (maxk < k){
maxk = k;
}
}else{
k = 0;
}
n++;
}
if (verbose == 1){
printf("stringa estratta dopo %llu step\n", n);
fflush(stdout);
}
return n;
}
int main(int argc, char * argv[]){
int i, l = -1, n = -1;
time_t t;
unsigned int sid = 0;
unsigned long long ret;
char * s;
FILE * f = NULL;
verbose = 1;
for (i = 0; i < argc; i++){
if (strcmp(argv[i], MARKER_STR) == 0){
s = argv[i + 1];
l = strlen(s);
}else if (strcmp(argv[i], MARKER_GIRI) == 0){
n = atoi(argv[i + 1]);
}else if (strcmp(argv[i], MARKER_SID) == 0){
sid = atoi(argv[i + 1]);
}else if (strcmp(argv[i], MARKER_VERBOSE) == 0){
if (strcmp(argv[i + 1], VERBOSE_OFF) == 0){
verbose = 0;
}
}else if (strcmp(argv[i], MARKER_SAVE) == 0){
f = fopen(argv[i + 1], "a");
if (f == NULL){
printf("errore nella creazione del file\n");
fflush(stdout);
return -1;
}
}
}
if (l == -1){
if (verbose == 1){
printf("specificare la stringa da estrarre: -s [stringa]\n");
fflush(stdout);
}
return -1;
}
if (n == -1){
if (verbose == 1){
printf("specificare il numero di iterazioni: -n [numero iterazioni]\n");
fflush(stdout);
}
return -1;
}
if (sid == 0){
if (verbose == 1){
printf("nessun sid specificato (opzione -r [sid]), uso sid generato automaticamente\n");
fflush(stdout);
}
sid = (unsigned int) time(&t);
}
if (verbose == 1){
printf("**** start estrazione ****\n");
printf("sid = %du\n", sid);
printf("stringa = %s\n", s);
printf("lunghezza = %d\n", l);
printf("iterazioni = %d\n\n", n);
fflush(stdout);
}
srand(sid);
for (i = 0; i < n; i++){
ret = estrai_stringa(l, s);
if (ret == 0){
printf("errore nell'estrazione della stringa\n");
fflush(stdout);
return -1;
}
if (f != NULL){
fprintf(f, "%llu\n", ret);
}
}
if (f != NULL){
fclose(f);
}
return 0;
}
Per compilare il codice è necessario salvarlo in un file (es. gen.c) e creare l'eseguibile attraverso un compilatore C. Di seguito si riporta il comando per compilare il sorgente con il compilatore gcc per il sistema operativo linux.
gcc gen.c -o gen
Verifica ipotesi mediante test di Student
modificaIl test di verifica ipotesi di Student permette di stabilire se la media campionaria si discosti in modo significativo alla media matematica . Per effettuare il test si formulano le ipotesi e . Nel caso in cui viene verificata l'ipotesi si stabilisce che le due previsioni sono attinenti con una certa probabilità di errore. Nel caso in cui viene verificata l'ipotesi si stabilisce che le due previsioni non sono attinenti con una certa probabilità di errore. Per effettuare il test di verifica è necessario ottenere i seguenti dati:
- è la numerosità del campione, ossia il numero di volte in cui si è registrato il tempo di uscita della parola "ciao"
- è il campione da verificare, dove rappresenta il numero di estrazioni occorse prima di comporre la parola "ciao"
- è la media campionaria
- è la varianza campionaria
- è la media matematica
- è la statistica che ha legge di Student con gradi di libertà
- è l'errore tollerabile nella conferma dell'ipotesi
- è il quantile della legge di Student con gradi di libertà associato alla tolleranza
Il test si esegue comparando il valore della statistica con il relativo quantile. Nel caso in cui si verifica l'ipotesi con una probabilità pari a . Nel caso in cui, invece, si respinge l'ipotesi e si conferma l'ipotesi con una probabilità di errore pari ad .
Esempio
modificaSi procede ad un esempio concreto per verificare mediante il test di Student le ipotesi e .
Per prima cosa si procede al campionamento dei dati utilizzando l'algoritmo descritto nella sezione precedente con il comando
./gen -s ciao -n 100 -f campionamento -r 1492875030
dove:
- ciao è la stringa da estrarre
- 100 è la numerosità del campionamento
- campionamento è il nome del file dove verranno salvati i risultati delle estrazioni
- 1492875030 è il seme per inizializzare il generatore pseudo casuale
Non appena il programma termina l'esecuzione è possibile procedere con il test di Student per stabilire se il numero di estrazioni necessarie per ottenere la stringa "ciao" è attinente alla previsione matematica. Si calcolano i parametri necessari a fare il test:
- è la numerosità del campione
- è la media campionaria
- è la varianza campionaria
- è la media matematica
- è la statistica con legge di Student
- si pone come errore tollerabile nel caso di verifica di
- il quantile associato è
Essendo si conferma l'ipotesi e pertanto la media campionaria conferma la media matematica. Analizzando il grafico sottostante con l'andamento delle previsioni parziali al variare della numerosità si vede chiaramente come .
Bibliografia
modificaPaolo Baldi, Calcolo delle Probabilità e Statistica - Seconda Edizione, Milano, McGraw-Hill, 1998, ISBN 88-386-0737-0.
Paolo Baldi, Calcolo delle Probabilità, Milano, McGraw-Hill, 2007, ISBN 978-88-386-6365-9.
Francesca Biagini, Massimo Campanino, Elementi di Probabilità e Statistica, Milano, Springer, 2006, ISBN 88-470-0330-X.