estrazione randomica mensile

giusalvo

Nuovo Utente
14 Ago 2012
25
1
3
MS
Saluti a tutti,
mi è stato commissionato ( si fa per dire perchè è a gratis!!!) un programma per l'estrazione di due persone da due gruppi diversi per dei lavori che devono espletare mensilmente, cioè per tutti i sabati del mese.
In questa estrazione, però, ci sono delle persone che non devono essere essere estratte con pari qualifiche e non possono essere ri-estratte prima che tutti siano stati estratti una volta.
Essendo una procedura che partirà dal mese di Gennaio 2013, diciamo dalla settimana del 7 dovrà durare fino al 2 Febbraio ( visto che il mese finisce infrasettimanale).
Lo scenario è questo:
Gruppo A, array di [topolino, minnie, paperino, qui, quo, qua];
Gruppo B, array di [orazio, clarabella, archimede];
Gruppo C, array di [topolino, minnie, orazio] non possono essere estratti insieme perchè hanno stessa qualifica;
Gruppo D, array di [paperino, archimede] non possono essere estratti insieme perchè hanno stessa qualifica;
Uno del gruppo A e uno del gruppo B, facendo i controlli che non apprtenghino a C e a D, devono essere estratti per tutti i sabati di Gennaio.

A febbraio sarà il turno di altri due e così via per tutto l'anno.
A parte gli array iniziali, qualcuno può dirmi come polter procedere.
Grazie.
Salvo
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
ciao
dai un occhio a questo script che avevo fatto tempo fa', si tratta di distribuire le carte di un mazzo, ma con gli opportuni adeguamenti potrebbe fare (se non ho capito male) quello che ti serve

PHP:
<?php
//costruisco il mazzo di carte
$seme[0]=array('2','3','4','5','6','7','8','9','10','F','D','R','A');
$seme[1]=array('2','3','4','5','6','7','8','9','10','F','D','R','A');
$seme[2]=array('2','3','4','5','6','7','8','9','10','F','D','R','A');
$seme[3]=array('2','3','4','5','6','7','8','9','10','F','D','R','A');
$semi=array('picche','cuori','quadri','fiori');
$giocatore=array('sud','ovest','nord','est');
$carte=13;//numero carte per giocatore
for($k=0; $k < 4; $k++){//distribuisco tra i giocatori
	$numero=0;//numero carte distribuite
	while($numero < $carte){//ripeto sino a che non distribuite tutte le carte al giocatore
		$s=rand(0,3);//estraggo il seme
		$c=rand(0,12);//estraggo la carta
		if(isset($seme[$s][$c])){//la carte esiste
			$giocatori[$k][$s].=$seme[$s][$c]." ";//la attribuisco al giocatore
			$numero++;//incremento il umero di carte per il giocatore k
			unset($seme[$s][$c]);//elimino carta dal mazzo
		}
	}
}
//verifica distribuzione
for($k=0;$k<4;$k++){
	echo "giocatore ".$giocatore[$k]."<br>";
	for($j=0;$j<4;$j++){
		echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seme ".$semi[$j].": ".$giocatori[$k][$j]."<br>";
	}
	echo "<hr>";
}
?>
al posto dei giocatori potresti mettere i mesi, le squadre al posto dei semi e le persone al posto delle carte, modificando i valori fissi
 

giusalvo

Nuovo Utente
14 Ago 2012
25
1
3
MS
Grazie borgo italia per lo script.
Adattandolo alle mie esigenze ho qualche problema.
Ti posto le modifiche:

PHP:
<?php
$gruppo[0]=array('topolino','minnie','paperino','paperina');
$gruppo[1]=array('qui','quo','qua','orazio','clarabella');
$gruppo[2]=array('topolino','minnie','qui','Riserva1'); //gruppo con la stessa qualifica; questi non devono essere estratti insieme
$gruppo[3]=array('paperina','quo','Riserva2','Riserva3');//gruppo con la stessa qualifica; questi non devono essere estratti insieme
$gruppi=array('1','2');
$mesi=array('Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno','Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre');
$estratti=2;//numero persone per mesi

for($k=0;$k<2; $k++){
$numero=0;
while($numero < $estratti){
     $g=rand(0,1);//estraggo il gruppo
     $p=rand(0,3);//estraggo le persone

  if(isset($gruppo[$g][$p])){
   $persone[$k][$g].=$gruppo[$g][$p]." ";
   $numero++;
   unset($gruppo[$g][$p]);
  }
 }
}
for ($k=0;$k<12;$k++){
echo "Mese ".$mesi[$k]."<br>";
for ($j=0;$j<2;$j++){
echo "&nbsp;&nbsp;&nbsp;&nbsp; ".$gruppi[$j].": ".$persone[$k][$j]."<br>";

}
echo "<hr>";
}
?>

Per l'elenco dei mesi va bene;
Mentre mi da un offset alla riga 17 e non capisco come devo intervenire.
Inoltre mi estrae correttamente i nominativi per i primi due mesi poi mi da un offset alla riga 26.
PS: Ma gli array dei gruppi devono essere tutti con lo stesso numero di elementi?

Grazie
Salvo
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
ciao
sto guardando, ma sto trovando dei problemi.
lo script (come lo vorresti tu) mi entra in un loop con un tempo molto grande soprattutto dopo aver estratto i primi.
il problema è che la funzione rand(0,4) estrae un numero (es. il 2) sempre con una probabilità 0.25.
man mano che estrae, e quindi elimino l'estratto dagli array, le probabilita di estrarre con rand rimangono 0.25, ma diventa, man mano che i nomi dimiuiscono, sempre più difficile che al numero estratto corrisponda un nominativo.
quindi il while opera sinche non lo trova, allungando i tempi di ricerca ad ogni estrazione.
per capirsi ti faccio un esempio (relativo ad un gruppo solo, ma il concetto è lo stesso).
dopo alcune estrazioni (ed eliminazioni) il gruppo 0 si è rriduce da
$gruppo[0]=array('topolino','minnie','paperino','paperina');
a
$gruppo[0]=array('topolino','paperina');
ma il rand continua ad estrarre sempre da 0 a 4 quindi il while continua a ripetersi sino a che non viene estratto uno 0 o un 1.

sto guardando alcune funzioni sugli array in modo da ridurre il limite del rand man mano che estraggo
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
ciao
ho trovato l'inghippo (ma per ora non ho trovato una soluzione valida).
nel caso del mio primo script
il numero di carte (54) è uguale al numero dei giocatori x numero di carte per giocatore (13 x 4), quindi anche rallentando man mano che il mazzo viene distribuito riasce a distribuire il tutto.
nel tuo caso il numero delle persone (da 0 a 3) risulta 4 persone X 4 gruppi = 16, ma devo distribuire
2 gruppi di 2 persone per 12 mesi = 48
quindi ad un certo punto (prima che i mesi e/o '1' o '2' siano terminati le persone da distribuire sono state già tutte eliminate, per cui il while entra in un loop infinito.
l'isset($seme[$s][$c]) non sarà mai vero quindi $numero++; non si incrementa mai.
bisogna cambiare tipo di approccio.
se sei ancora interessato fammelo sapere perche mi "stimola" trovare una soluzione
 

giusalvo

Nuovo Utente
14 Ago 2012
25
1
3
MS
Certo che sono ancora intreressato!.
Nel frattempo ho provato a fare varie prove sia modificando gli array dei gruppi che provando a mettere degli array_rand ed ho anche provato a fare un array_merge ma alla fine la soluzione non veniva lo stesso.
Ho pensato anch'io al problema dell'estrazione annuale e riflettendo un po ho pensato che se la somma dei due gruppi arriva a nove persone( perchè i gruppi 3 e 4 sono le persone dei gruppi 1 e 2 che non devono uscire insieme) per cui 9 persone vengono estratte in 4 mesi (col resto di 1). Per cui, la soluzione che ho proposto ( ma che ancora devono darmi una conferma) è quella di fare un'estrazione trimestrale massimo 4mestrale, modificando di volta in volta il nome dei mesi prima di lanciare la procedura. Così facendo c'è sempre qualche nominativo che rimane non pescato.
Inoltre una cosa strana che ho notato è che in certe estrazioni mi vengono estratti 3 nominativi, per esempio:

Mese Gennaio
1: topolino paperina
2: minnie

e poi magari

Mese Febbraio
1: (vuoto)
2:eek:razio

Grazie per l'interessamento. Se puoi, andiamo avanti...
Ciao
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
ciao
non mi sono dimenticato, ma è più complesso di quello che sembra.
forse, ma sottolineo forse, mi sto avvicinando alla soluzione.
sempre che non sia urgente
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
ciao
un primo script con un però, per ora alcune limitazioni date dal fatto che le persone non possono essere ripetute.
dato che per ogni mese vuoi creare due coppie (usi quindi 4 persone che devi scartare dopo l'uso) più di totelepersone/2 coppie non puoi creare.
poi (per ora, ma sto cercando di capire come generalizzare)
1. l'array persone può andare solo da 0 a 3 (4 gruppi) e ogni elemento con numero perone uguale
2. poui formare solo coppie di due persone
3. ogni mese puoi avere solo due coppie (tot 4 persone/mese)
prova lo script e sappimi dire qualcosa e se sono nella direzione giusta di quello che vuoi
PHP:
<?php
//definizione delle persone
$persone[0]=array('persona0_0','persona0_1','persona0_2','persona0_3','persona0_4','persona0_5');
$persone[1]=array('persona1_0','persona1_1','persona1_2','persona1_3','persona1_4','persona1_5');
$persone[2]=array('persona2_0','persona2_1','persona2_2','persona2_3','persona2_4','persona2_5');
$persone[3]=array('persona3_0','persona3_1','persona3_2','persona3_3','persona3_4','persona3_5');
//verifica
echo " array originale<br>";
foreach($persone as $ch_1 => $val_1){
	echo "persone[$ch_1] : ";
	foreach($val_1 as $ch_2 => $val_2){
		echo " $val_2 ";
	}
	echo "<br>";
}
//numero persone sul raggruppamento da creare
$pers_gruppo=2;//per ora solo coppie
//gruppi di coppie al mese
$gruppi=array('1','2');
//mesi
$mesi=array('Gennaio','Febbraio','Marzo','Aprile','Maggio','Giugno','Luglio','Agosto','Settembre','Ottobre','Novembre','Dicembre');
//conto i gruppo e le persone
$tot_pe=0;
foreach($persone as $ch_1 => $val_1){
	$num=count($val_1);
	$tot_pe += $num;//calcolo il totale
}
//verifica
echo "ho un totale di $tot_pe persone<br>";//ok
//considerato che devo avere 4 persone ogni mese verifico quanti mesi posso coprire
$copertura=(int)($tot_pe/4);
//verifica
$escluse=$tot_pe - 4*$copertura;
echo "copro $copertura mesi = numero di doppie coppie che posso creare<br>";//ok
//per estrarre casualmente le persone
//1. rimescolo tra loro i gruppi di persone
shuffle($persone);
//2. rimescolo casualmente le persone all'interno del loro gruppo
for($k=0;$k < count($persone); $k++){
	shuffle($persone[$k]);
}
//verifica
echo " array rimescolato<br>";
foreach($persone as $ch_1 => $val_1){
	echo "persone[$ch_1] : ";
	foreach($val_1 as $ch_2 => $val_2){
		echo " $val_2 ";
	}
	echo "<br>";
}
//creo le coppie per il gruppo '1' e '2'
for($k=0;$k <= 8; $k++){
	$coppia[$k][0]=$persone[0][$k]." ".$persone[1][$k];
	$coppia[$k][1]=$persone[2][$k]." ".$persone[3][$k];
}
$mese_partenza=0;
$mese_arrivo=$mese_partenza+$copertura-1;
//verifica
echo "copro da ".$mesi[$mese_partenza]." a ".$mesi[$mese_arrivo]."<br>";//ok
/* **** TEST **** */
echo "<hr>";
for($k=0;$k <$copertura; $k++){
	echo "mese: ".$mesi[($k+$mese_partenza)]."<br>";
	echo "&nbsp;&nbsp;&nbsp;&nbsp;gruppo '1': ".$coppia[$k][0]."<br>";
	echo "&nbsp;&nbsp;&nbsp;&nbsp;gruppo '2': ".$coppia[$k][1]."<hr>";
}
?>

p.s.
troverai alcune variabili che poi non vengono utilizzate, non ti preuccupare forse potranno servire in seguito
 

giusalvo

Nuovo Utente
14 Ago 2012
25
1
3
MS
ciao,
ho visto ora il tuo script.
Non mi hanno dato una scadenza, mi hanno chiesto se era possibile fare questo tipo di estrazione.
Vorrei riprendere ua parte del mio primo post perchè penso che stai andando oltre (sei troppo in gamba!) dalla richiesta originale.
Intanto voglio dirti che potrò provare lo script lunedì al rientro perchè a casa non ho un ambiente per poterlo provare.

Lo scenario iniziale era questo:
- 2 gruppi di persone ( gruppo 1 e gruppo 2 ) che abbiamo identificato con due array
- di questi ci sono delle persone ( vedi gruppo 3 e 4) che non devono essere estratti insieme perchè hanno la stessa qualifica.
Ogni mese devono essere estratte solo 2 persone e non 4; è chiaro che così diventa molto più difficile.

Quello che ti chiedevo: è possibile avere degli array con un numero di elementi diversi ( 1° gruppo: 5 elementi, 2° gruppo: 4 elementi, 3° gruppo: 3 elementi e 4° gruppo: 2 elementi).
L'estrazione dovrebbe dare:
Mese Gennaio
1: topolino
2: clarabella

Mese Febbraio
1: paperina
2: quo

Mese Marzo
1: minnie
2: orazio

e considerato che in totale sono 9 persone, mi è stato dato l'OK per fare una estrazione 3mestrale o 4mestrale.
Grazie ancora per il grande contributo che stai mettendo in pratica...
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.046
150
63
PR
www.borgo-italia.it
ciao
ci do un occhio (sempre con la solita pazienza)

edit
scusa dimenticavo
quello che ti chiedevo: è possibile avere degli array con un numero di elementi diversi ( 1° gruppo: 5 elementi, 2° gruppo: 4 elementi, 3° gruppo: 3 elementi e 4° gruppo: 2 elementi).

cioè intendi così e sarà sempre così

PHP:
$persone[0]=array('persona0_0','persona0_1','persona0_2','persona0_3','persona0_4');
$persone[1]=array('persona1_0','persona1_1','persona1_2','persona1_3');
$persone[2]=array('persona2_0','persona2_1','persona2_2');
$persone[3]=array('persona3_0','persona3_1');

o il numero delle persone del gruppo puo variare?
 
Ultima modifica:

giusalvo

Nuovo Utente
14 Ago 2012
25
1
3
MS
ciao e grazie ancora per il tuo interessamento...
I gruppi, che io sappia, rimarranno così per parecchio tempo.

Dicevo nel primo topic che ci sono delle persone che fanno parte di due gruppi, ossia:
facendo rifeimento al tuo esempio, ho questa situazione.
PHP:
$persone[0]=array('persona0_0','persona0_1','persona0_2','persona0_3','persona0_4');
$persone[1]=array('persona1_0','persona1_1','persona1_2','persona1_3');
$persone[2]=array('persona0_0','persona0_1','persona1_0');//di questi due fanno parte del 1 gruppo e uno del 2° a non devono uscire insieme //perchè hanno la stessa qualifica. L'estrazione deve estrarre uno solo di questi (se esce) al mese.
$persone[3]=array('persona0_3','persona1_2'); //di questi 1 fa parte del 1 gruppo e uno del 2° a non devono uscire insieme perchè hanno 
//la stessa qualifica. Anche qui l'estrazione deve estrarne uno solo di questi al mese. 
Vedi che le persone del 3 e del 4 gruppo sono (in parte) le stesse dei gruppi 1 e 2.

Avevo pensato di fare 4 gruppi per ridondare i nominativi e metterli in sotto gruppi, ma se la cosa è giostrabile in altro modo, ben venga...
Pensavo anche a una soluzione del tipo per esempio:

//estrai 1° persona;
$estratto1= [k];

//fa un controllo su chi è stato estratto
se ($estratto1 è uguale a (persona0_0 o persona0_1 o persona1_0)) {
//estrai la 2° persona;
$estratto2=[k];}

se ($estratto2 è uguale a (persona0_1 o persona1_0 o persona0_0)){
//qui si può decidere cosa è meglio fare;
fai una nuova estrazione/ annulla l'estrazione/ oppure estrai $estratto2+1;}
altrimenti
{
//l'estrazione è anadata a buon fine
1: $estratto1;
2: $estratto2;}

e penso che la cosa si possa far fare anche nel caso escano uno dei due elementi del 4 gruppo.
Spero di aver scritto abbastanza chiaramente la mia idea. Non esitare a chiedere se qualcosa non ti è chiaro...
Grazie!
 

giusalvo

Nuovo Utente
14 Ago 2012
25
1
3
MS
Per dare un senso alla chiusura del tread dico che alla fine l'utente che aveva proposto e richiesto la procedura ha deciso di fare una cosa manuale e cartacea sentendo tutti gli interessati.
Non ho continuato sull'argomento per mancanza di tempo per questa cosa.
Grazie a Borgo Italia per le preziose info.
 
Discussioni simili
Autore Titolo Forum Risposte Data
K Estrazione di più risultati da tabelle correlate PHP 5
E Progressbar estrazione dati da tabella mySQL Ajax 9
L Estrazione dati php Database 6
L Estrazione dati casuali non doppioni MySQL 1
D Chiave unica in estrazione dati da array php PHP 0
L Estrazione valori max su più campi MySQL 4
M [PHP] Estrazione random con nomi presi dal db PHP 22
gandalf1959 Estrazione e visualizzazione del simbolo dell'euro php/mysqli PHP 0
ronny1710 Estrazione Dati Tessera Sanitaria .NET Framework 1
F Estrazione Email di persone selezionate e attive / facebook + invio di massa! Annunci servizi di Social Media Marketing 0
V Estrazione di una singola banda da file multi banda (RGB) con Python Programmazione 0
creatorweb [PHP] estrazione ciclica dati con 2 dati alla volta PHP 2
O [PHP] problema estrazione immagine da db PHP 12
Gigi87 [PHP] Estrazione dati da forum o da social network PHP 1
V [PHP] Estrazione con SQL PHP 1
L estrazione dati da mysql in php e salvataggio in cartella del server PHP 51
M [MS Access] Estrazione record multipli MS Access 1
E [PHP] estrazione dati in modo non continuativo PHP 1
S [PHP] estrazione dal DB complicata PHP 7
asevenx [Javascript] Estrazione dal database di un valore in base ad una scelta Javascript 7
S Php e mysql, estrazione da una tabella e inserimento in un'altra tabella PHP 14
P Probelma estrazione stringa PHP 5
C Estrazione Dati da Pagine Gialle PHP 0
L Estrazione Articoli Random da Tabella senza doppioni PHP 1
A Estrazione dati da tabella sql MySQL 27
gandalf1959 Estrazione di un singolo dato da una ricerca mysql PHP 1
T Codice per estrazione dati da db PHP 4
F estrazione codice Javascript 0
R Javascript e html - estrazione EXIF da jpg con link per geolocalizzazione google maps Javascript 0
D php estrazione random nomi e senza ripetizione PHP 14
M Problema con estrazione coordinate da google geocoding PHP 1
L Conversione date ed estrazione PHP 0
L estrazione dati per login PHP 0
W Estrazione dati da DB PHP 20
N Problemi estrazione / visualizzazione immagini dal database con PDO PHP 2
L Estrazione dati per settimana. PHP 13
L estrazione dati e immagini in contemporanea PHP 4
B Estrazione Database valori multipli MySQL 4
M estrazione dati casuali da database Database 0
A Evitare estrazione record doppioni PHP 2
C [PHP][MY SQL] - Estrazione dati database tramite form PHP 8
G estrazione dati da DB tramite PHP errore time out PHP 2
A problema estrazione singolo valore e memorizzazione in variabile PHP 1
B Estrazione dati utente loggato MySQL 1
W Estrazione dati DB da lista MySQL 1
M Connessione Database ed estrazione dati Javascript 6
H Problema riguardo l'estrazione di record dal DB tramite codice univoco PHP 7
G Script php estrazione email PHP 8
D [RISOLTO] Estrazione parole INPUT Javascript 2
A [risolto] Istruzione per estrazione di dati casuali dal db PHP 25

Discussioni simili