Scelta chiave in Tabella di Hash

di il
4 risposte

Scelta chiave in Tabella di Hash

Ciao a tutti,
sto cercando di risolvere un esercizio che richiede l'utilizzo di una tabella di Hash, il testo è questo:

Una società sportiva deve organizzare un programma di allenamento per il potenziamento delle prestazioni fisiche dei propri atleti. Il programma prevede 4 fasi di allenamento e per ogni fase è disponibile un certo numero di esercizi, ognuno dei quali caratterizzato da un determinato dispendio energetico.
Le informazione relative agli esercizi possibili, al dispendio energetico loro associato (numero minore o uguale a 500) ed alle fasi in cui sono impiegabili sono memorizzate sul file. Sul file per ogni esercizio è riportata una riga, che contiene il nome dell’ esercizio (senza spazio), il dispendio energetico associato e l’ elenco delle fasi in cui l’esercizio può essere impiegato (numeri di 1 a 4).
Esempio di file di ingresso:
addominali_alti 200 1 2
addominali_bassi 500 1 2
glutei 250 1 3
adduttori 350 1 3 4
bicipiti 200 1 2
quadricipiti 150 2 4
trapezi 300 2
dorsali 350 3 4
pettorali 300 2 3
abduttori 200 2 3
tricipiti 100 1 3 4
deltoidi 200 1 3
femorali 400 2 3 4

Scrivere un programma in C, che legge da tastiera il valore di N (numero di esercizi massimo in ogni fase) e K (dispendio massimo di calorie in ogni fase) e che sia in grado di determinare per ciascuna fase l’esercizio/gli esercizi da svolgere in modo tale da avvicinarsi il più possibile al dispendio energetico massimo fissato, senza superarlo. Alla fine il programma deve stampare sul schermo, per ognuna fase, la lista degli esercizi ed il dispendio energetico loro associato.
Esempio di soluzione (N=3, K=800)
Fase 1
addominali_alti 200
addominali_bassi 500
tricipiti 100
Fase 2
bicipiti 200
abduttori 200
femorali 400
Fase 3
glutei 250
adduttori 350
deltoidi 200
Fase 4
quadricipiti 150
trapezi 300
dorsali 350

Osservazione: lo stesso esercizio non può essere svolto in più di una fase.


Il mio dubbio riguarda la scelta della chiave,con la quale inserisco i dati nella tabella di Hash.
Infatti, se inserisco come chiave il nome dell'esercizio, quando poi scrivo la funzione che si occupa di calcolare il giusto mix di esercizi, il nome dell'esercizio non mi serve a nulla nella ricerca, perciò risulterebbe inutile aver usato una tabella di Hash!
Cosa mi consigliate?

4 Risposte

  • Re: Scelta chiave in Tabella di Hash

    Quindi il numero massimo di esercizi per fase lo decide l'utente? Non c'è un numero massimo di esercizi da fare per fase, è variabile.
  • Re: Scelta chiave in Tabella di Hash

    Si esatto, è variabile.
    Da tastiera gli dici quanti esercizi a fase vuoi fare e quante calorie a fase vuoi spendere..
    E il tuo algoritmo deve creare un programma di esercizi che per le 4 fasi si avvicini il max possibile alle calorie inserite da tastiera..
  • Re: Scelta chiave in Tabella di Hash

    Ciao , ho cercato di fare l'algoritmo per la scelta degli esercizi ma ho un po di problemi, per adesso ho trovato un algoritmo non molto efficace. Ci lavorerò ancora un po.
    
    #include <stdio.h>
    #include <windows.h>
    #include <string.h>
    
    #define MAX 20
    #define RANGE 50  //stabilisce l'errore che si può avere, per esempio di 50 unità
    
    int ReadFile(char* path);
    int Selezione(int fase, int size, int* indexes);
    int GetExercise(int energia ,int size,int eNum,int* indexes, int* out_indexes);
    int ComparaDati(int a, int b);
    void Scambia(int* a,int* b);
    int Somma(int energia, int *data, int eNum, int from=0);
    
    struct Esercizio
    {
    	char name[MAX];
    	int energia;
    	int serie[4];
    };
    
    adesso passo alla main:
    
    struct Esercizio exc[MAX];
    
    int main(int argc, char * argv[])
    {
    	int n=3, k=800,size,f_size;
    		int indices[MAX];
    		int res_indices[MAX];
    	
    
    	f_size= ReadFile("C:\\Documents and Settings\\Administrator.L-ITDC.000\\Desktop\\Luigi\\esercizi.txt");
    	for (int i=1;i<=4;i++)
    	{
                    Azzera(indices,f_size);
    		if ((size=Selezione(i,f_size,indices))<n)
    		{
    			printf("%s \n","Spiacenti per la prima fase non c'è il numero di esercizi richiesto");
    				system("Pause");
    
    			return 0;
    		}
    		GetExercise(k,size,n,indices,res_indices);
    		printf("Fase %d\n",i);
    		for(int a=0;a<n;a++)
    			printf("%s\n",exc[res_indices[a]].name);
    
    		 
    	}
    
    	system("Pause");
    	return 1;
    }
    
    adesso lo sviluppo delle altre funzioni:

    legge il file e inserisce i dati nella struttura
    
    int ReadFile(char* path)
    {
    	if (strcmp(path,"")==0) return -1;
    
    FILE *fp;
    int i=0, y=0,n;
    
    	fp = fopen(path,"r");	
    
    	for(i=0;(n = getc(fp))!=EOF;i++,y=0)
    	{
    		ungetc(n,fp);
    
    		fscanf(fp,"%s",exc[i].name);
    		fscanf(fp,"%d",&exc[i].energia);
    		while((n=getc(fp))!='\n' && y<=3)
    		{
    			//ungetc(n,fp);
    			fscanf(fp,"%d",&exc[i].serie[y++]); 
    		}
    	}
    	fclose(fp);
    	return i;
    }
    
    qui ci sono le altre per ottenere i dati.
    
    int Selezione(int fase, int size, int* indexes)
    {
    	/*Selezione() inserisce in un array di integer
    	gli indici degli elementi della struttura exc 
    	che hanno l'elemento dell'array campo fase  = a 
    	fase dato input*/
    
     int n=0;
    
    	for (int i=0;i<size;i++)
    	{
    		for(int y=0;y<4 && exc[i].serie[y]!=0;y++)
    			if (exc[i].serie[y]==fase)
    			{
    				indexes[n++]=i;
    				break;
    			}
    	}
    
    	return n;
    
    }
    
    int ComparaDati(int a, int b)
    {
    	if (a==b) return 1;
    
    	if (a>b)
    		if ((a-RANGE)>b)
    			return -1;
    	if ((b-RANGE)>a)
    		return -1;
    
    	return 1;
    
    }
    
    
    int Somma(int energia, int *data, int eNum,int from)
    {
    	int res=0;
    
    	for(int i=from;i<(from+eNum);i++)
    	res += exc[data[i]].energia; 
    
    	if (ComparaDati(res,energia)==1)
    	 return 1;
    
    	return 0;
    }
    void Azzera(int* val, int size)
    {
    	for(int i=0;i<size;i++)
    		val[i]=-1;
    
    }
    void Cp(int *a, int *b, int eNum)
    {
    	for(int i=0;i<eNum;i++)
    		a[i]=b[i];
    
    }
    int GetExercise(int energia ,int size,int eNum,int* indexes, int* out_indexes)
    {
    
    	int val[MAX]={-1};
    	int n;
    	
    	srand((unsigned)time(NULL));
    
    	while(Somma(energia,val,eNum)==0)
    	{
    		_sleep(50);
    		n=0;
    		Azzera(val,size);
    		while (n<eNum)
    		{
    			int a;
    			bool bRes=true;	
    			a = 0+ rand() % size;
    
    				for(int i=0;i<size;i++)
    				{
    					if(val[i]==indexes[a])
    					{
    						bRes=false;
    						break;
    					}
    				
    				}
    			
    			if(bRes==true)
    				val[n++]=indexes[a];
    
    		}
    	}
    	Cp(out_indexes,val,eNum);
    	return 1;
    }
    
    
    ... L'ho testato e funziona, ma ti ripeto l'algoritmo per ottenere gli esercizi la cui somma delle calorie è quella data dall' utente va migliorato molto. Inoltre io ho dato un margina di errore di 50 unità.
  • Re: Scelta chiave in Tabella di Hash

    Si in effetti è sull'algoritmo che ho problemi..
    Perchè non è facile bilanciare 4 fasi con il mix di esercizi migliore in assoluto..
    Secondo te la ricerca della soluzione migliore comunque, deve essere per forza lineare? Mi chiedevo se esiste un metodo più efficiente..
    Comunque grazie per adesso!!
Devi accedere o registrarti per scrivere nel forum
4 risposte