Guarda, ho fatto questo in Java...Purtroppo ho dei problemi con il compilatore C, xo cmq puoi utilizzare l'algoritmo per imparare e fare un porting per il C...
IDEA DI BASE
Per gli spalatori ho usato uno oggetto "Spalatore" (non ci sono gli oggetti in C, lo so, ma puoi usare la stessa cosa con Struct e funzioni), ove le variabili sono:
Età
Guanti
Pala
alLavoro
TempoLavoro
TempoAttesa
id
Età mi serve per calcolare la "Fatica", un indicatore fatto da me perché suppongo che chi è + grande, si stanca prima.
Guanti e Pala sono booleani per capire se questo ha effettivametne guanti e pale
alLavoro è un booleano che dice se sto tizio sta lavorando o no
TempoAttesa e TempoLavoro sono interi e contano (in minuti secondo la mia implementazione) quanto tempo lavora o sta in attesa: sono indicatori importanti per decidere la priorità in coda. Quando stanno in coda, non puoi prendere chi vuoi, ma devi segure la priorità
id è un numero che mi dice chi è: il tizio numero 1, numero 2, etc...
-
Una volta fatto cio, faccio un main dove metto ste belle cose:
Guanti e Pale: quantità di pale e guanti disponibili
GuaniAssegnati e PaleAssegnate: quantità di pale e guanti assegnati
Neve: unità di neve da spalare (io ho fatto finta che siano metri cubi e che uno spalatore riesce a togliere un metro cubo di neve ogni minuto di lavoro, sono unità di misura scelte da me per rendere realistico il sistema).
Un array di spalatori
un array di alLavoro
un array di inAttesa
questi 3 array sono di tipo Spalatore (oggetti) di lunghezza pari al numero di spalatori.
work: numero di tizi al lavoro
wait: numero di tizi in attesa di risorse.
E ora inizia il cuore del problema.
Per prima cosa faccio un do...while che dure fino a quanto c'è neve da spalare (Neve>0)
Poi metto in ordine tutti i tizi che lavorano in ordine decrescente rispetto alla Fatica, così chi è + stanco (indicatore di fatica che tende a 0) lo metto in cima alla lista prossimo ad essere tolto e spostato in attesa.
Fatto ciò, vedo chi ha Fatica <=0 e lo tolgo e lo sposto in attesa, ASSICURANDOMI di mettere le sue risorse un'altra volta disponibili.
Ora metto in ordine i tizi in attesa rispetto alla priorità, quelli con priorità + alta si mettano in cima alla lista in modo da essere facilmente spostati al lavoro qualora ci fossere risorse disponibili.
Assegno le risorse disponibili e con il metodo canWork (puo lavorare?...cioè fa un controllo se possiede sia guanti che pala) lo sposto nell'array alLavoro, modificando il suo stato e tutte ste belle cose...
Fatto ciò, incremento a quelli in attesa, una unità il tempo di attesa e faccio la stessa cosa di chi è al lavoro e incremento il tempo totale di lavoro. Con il metodo toString, in java, mi permette di stampare lo stato dell'oggetto senza richiamare il metodo stesso...se io faccio System.out.println(S[i]) è uguale a System.out.println(S[i].toString)...Da qui ti faccio capire che l'ultimo passaggio stampo lo stato dei lavoratori
CLASSE SPALATORE
codice:
class Spalatore
{
private int eta; //l'eta dello spalatore: utile x calcolare la sua resistenza di lavoro
private boolean Pala; //dice se lo spalatore ha la pala
private boolean Guanti; //dice se lo spalatore ha i guanti
private int TempoDiLavoro; //espresso in minuti
private int TempoDiAttesa; //espresso in minuti
private boolean alLavoro; //stato dello spalatore
private int id;
private static int N=0;
//costruttore che assegno solo l'età
public Spalatore(int old)
{
eta=old;
Pala=Guanti=alLavoro=false;
TempoDiLavoro=TempoDiAttesa=0;
N++;
id=N;
}
public int getEta() { return eta; }
public void setEta(int old) { eta=old; }
public boolean getPala() { return Pala; }
public void setPala() { Pala=true;}
public void unsetPala() { Pala=false;}
public boolean getGuanti() { return Guanti; }
public void setGuanti() { Guanti=true;}
public void unsetGuanti() { Guanti=false;}
//aumenta il tempo di lavoro
public void increaseWorkTime(int i) { TempoDiLavoro+=i; }
public void increaseWorkTime() { TempoDiLavoro++; }
public void cleanWorkTime() { TempoDiLavoro=0; } //pulisce il tempo di lavoro
public void increaseWaitTime(int i) { TempoDiAttesa+=i; }
public void increaseWaitTime() { TempoDiAttesa++; }
public void cleanWaitTime() { TempoDiAttesa=0; } //pulisce il tempo di attesa
//calcola la priorità che deve avere uno spalatore x prendere una pala in relazione al tempo di attesa
public double Priorita()
{
return TempoDiLavoro>0?(((double)TempoDiAttesa + (double)TempoDiLavoro) / (double)TempoDiLavoro):100;
}
//calcola la fatica accumulata
public int Fatica()
{
return 100 - (eta * TempoDiLavoro*10/54);
//la formula è stata ricavata nel seguente modo
//Fatica restituisce un valore tra 0-100, dove 100 è massima resistenza, 0 indica l'ora del caffè
//Si indica statisticamente che un persona di 18 anni può lavorare x 30 minuti in ininterottamente.
//tale prodotto risulta 540...da qui si divide x 540 e si moltiplica per 100...Per le proprietà dei prodotti,
//divido per 10 sai 540 che 100 e da qui ho 54 e 10.
}
//Indica se un particolare spalatore può lavorare (avendo le risorse)
public boolean canWork()
{
return (Pala && Guanti);
}
//mette in pausa o al lavoro il lavoratore
public void Lavora() { cleanWorkTime(); alLavoro=true; }
public void Pausa() { cleanWaitTime(); alLavoro=false; }
public String toString()
{
return ""+id+". Ho "+eta+" anni e "+(alLavoro==true?"sto Lavorando":"sono in pausa (Priorita: "+Priorita()+")" )+" da " + (alLavoro==true?TempoDiLavoro:TempoDiAttesa) +" minuti " +(alLavoro==true? " ("+Fatica()+")":"" ) ;
}
}
PROGRAMMA PRINCIPALE
codice:
public class Spalatori
{
static Spalatore [] alLavoro;
static Spalatore [] inAttesa;
static int PaleAssegnate=0;
static int GuantiAssegnati=0;
static int minutiDiLavoro=0;
static public void main(String [] args)
{
int Neve = 1000; //metri cubi di neve da spalare
int ns=10; //numero di spalatori
int numeroGuanti = 12; //numero di guanti
int numeroPale=4; //numero di pale
int wait=ns; //gente in attesa
int work=0; //gente al lavoro
boolean swap; //variabile di appoggio che indica gli scambi
Spalatore [] S = new Spalatore[ns];
inAttesa = new Spalatore[ns];
alLavoro = new Spalatore[ns];
//inizializzazione
//creo gli spalatori e li metto in attesa
for(int i=0;i<ns;i++)
{
S[i] = new Spalatore( 18 + (int)(Math.random() * 32) );
inAttesa[i]=S[i];
System.out.println(S[i]);
}
//CORE!!!!!!
do
{
//Metto in ordine di fatica le persone che lavorano
do
{
swap=false;
for(int i=0;i<work-1;i++)
{
if(alLavoro[i].Fatica()< alLavoro[i+1].Fatica())
{
Spalatore tmp = alLavoro[i];
alLavoro[i]=alLavoro[i+1];
alLavoro[i+1]=tmp;
swap=true;
}
}
}
while(swap); // esegue l'ordinamento fino a quando non ci sono scambi
//cerco chi ha l'indice di fatica a 0 e lo metto in pausa
for(int i=work-1;i>=0;i--)
{
if(alLavoro[i].Fatica()<=0)
{
//lo metto in pausa e gli tolgo guanti e pala
alLavoro[i].Pausa();
alLavoro[i].unsetGuanti();
alLavoro[i].unsetPala();
work--;
inAttesa[wait]=alLavoro[i];
wait++;
PaleAssegnate--;
GuantiAssegnati-=2;
}
}
//Metto in ordine di priorità le persone in attesa
do
{
swap=false;
for(int i=0;i<wait-1;i++)
{
if(inAttesa[i].Priorita()> inAttesa[i+1].Priorita())
{
Spalatore tmp = inAttesa[i];
inAttesa[i]=inAttesa[i+1];
inAttesa[i+1]=tmp;
swap=true;
}
}
}
while(swap); // esegue l'ordinamento fino a quando non ci sono scambi
//assegno le risorse
for(int i=wait-1;i>=0;i--)
{
if (PaleAssegnate < numeroPale)
{
inAttesa[i].setPala();
PaleAssegnate++;
}
if (GuantiAssegnati < numeroGuanti)
{
inAttesa[i].setGuanti();
GuantiAssegnati+=2;
}
//vedo se uno spalatore in attesa è in grado di lavorare
if(inAttesa[i].canWork())
{
wait--; //decremento il puntatore dei lavoratori in attesa
alLavoro[work] = inAttesa[i]; //metto il tizio da in attesa a lavoro
alLavoro[work].Lavora(); //modifico il suo stato
work++; //aumento il puntatore dei lavoratori al lavoro
}
}
//aumento un minuto di lavoro
minutiDiLavoro++;
//Andiamo a Lavorare!!!
for(int i=0;i<work;i++)
{
alLavoro[i].increaseWorkTime(); //aumento il tempo di lavoro
Neve--; //decremento i metri cubi di neve da spalare
}
//Aumento il tempo di attesa degli altri
for(int i=0;i<wait;i++)
{
inAttesa[i].increaseWaitTime();
}
System.out.println("\nStato di lavoro dopo "+minutiDiLavoro+" minuti\n------------------------------------------------");
for(int i=0;i<S.length;i++)
{
System.out.println(S[i]);
}
}
while(Neve >0);
}
}