feat: Initial commit
This commit is contained in:
11
Laboratorio 8/Esercizio 1/Elementi.c
Normal file
11
Laboratorio 8/Esercizio 1/Elementi.c
Normal file
@@ -0,0 +1,11 @@
|
||||
// Laboratorio 8 - Esercizio 1 - Elementi.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include<stdio.h>
|
||||
#include"Elementi.h"
|
||||
|
||||
Elemento leggiElemento(FILE * fp) {
|
||||
Elemento e;
|
||||
fscanf(fp, "%s %d %d %d %d %d %f %d", e.nome, &e.tipo, &e.dirIngresso, &e.dirUscita, (int *) &e.reqPreced, (int *) &e.finale, &e.valore, &e.diff);
|
||||
return e;
|
||||
}
|
||||
25
Laboratorio 8/Esercizio 1/Elementi.h
Normal file
25
Laboratorio 8/Esercizio 1/Elementi.h
Normal file
@@ -0,0 +1,25 @@
|
||||
// Laboratorio 8 - Esercizio 1 - Elementi.h
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#ifndef ELEM_H_DEFINED
|
||||
#define ELEM_H_DEFINED
|
||||
#include<stdbool.h>
|
||||
#include<stdio.h>
|
||||
#define MAX_LEN 30
|
||||
|
||||
enum tipo { TRANSIZIONE, INDIETRO, AVANTI };
|
||||
enum direzione { SPALLE, FRONTE };
|
||||
|
||||
typedef struct elemento {
|
||||
char nome[MAX_LEN+1];
|
||||
int tipo;
|
||||
int dirIngresso;
|
||||
int dirUscita;
|
||||
bool reqPreced;
|
||||
bool finale;
|
||||
float valore;
|
||||
int diff;
|
||||
} Elemento;
|
||||
|
||||
Elemento leggiElemento(FILE * fp);
|
||||
#endif
|
||||
20
Laboratorio 8/Esercizio 1/elementi.txt
Normal file
20
Laboratorio 8/Esercizio 1/elementi.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
19
|
||||
ruota 0 1 0 0 0 0.0 1
|
||||
rondata 0 1 0 0 0 0.2 1
|
||||
ribaltata_a_2 0 1 1 0 0 0.25 2
|
||||
back_handspring 0 0 0 0 0 0.4 2
|
||||
front_tuck 2 1 1 0 0 1.75 3
|
||||
front_pike 2 1 1 0 0 2.0 4
|
||||
front_layout 2 1 1 0 0 2.25 5
|
||||
back_tuck 1 0 0 0 0 1.75 3
|
||||
back_pike 1 0 0 0 0 2.0 4
|
||||
back_layout 1 0 0 0 0 2.25 5
|
||||
double_front_tuck 2 1 1 1 0 3.0 6
|
||||
double_front_layout 2 1 1 1 1 4.0 7
|
||||
double_back_tuck 1 0 0 1 0 3.0 6
|
||||
double_back_layout 1 0 0 1 1 4.0 7
|
||||
triple_front_tuck 2 1 1 1 1 6.5 8
|
||||
triple_back_tuck 1 0 0 1 1 6.0 8
|
||||
back_layout_double_twist 1 0 0 1 0 8.0 9
|
||||
back_layout_quad_twist 1 0 0 1 1 12.0 10
|
||||
arabian 1 0 1 0 0 2.5 4
|
||||
345
Laboratorio 8/Esercizio 1/main.c
Normal file
345
Laboratorio 8/Esercizio 1/main.c
Normal file
@@ -0,0 +1,345 @@
|
||||
// Laboratorio 8 - Esercizio 1 - main.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "Elementi.h"
|
||||
#define MAX_ELEM 5
|
||||
#define MAX_DIAG 3
|
||||
|
||||
typedef struct params
|
||||
{
|
||||
bool acrobNecessaria;
|
||||
bool acrobAvantiNecessaria;
|
||||
bool acrobIndietroNecessaria;
|
||||
} Requirements;
|
||||
|
||||
Elemento *leggiFile(char *filename, int *N)
|
||||
{
|
||||
FILE *fin;
|
||||
if ((fin = fopen(filename, "r")) == NULL)
|
||||
{
|
||||
puts("Impossibile aprire il file");
|
||||
return NULL;
|
||||
}
|
||||
fscanf(fin, "%d", N);
|
||||
Elemento *lista = malloc(*N * sizeof(Elemento));
|
||||
for (int i = 0; i < *N; i++)
|
||||
{
|
||||
lista[i] = leggiElemento(fin);
|
||||
}
|
||||
fclose(fin);
|
||||
return lista;
|
||||
}
|
||||
|
||||
float calcElementValue(Elemento e, Requirements reqs, bool acrobInSeqNecessaria)
|
||||
{
|
||||
float value = (e.valore / e.diff);
|
||||
|
||||
if (e.tipo == AVANTI && reqs.acrobAvantiNecessaria)
|
||||
{
|
||||
value += 1;
|
||||
}
|
||||
|
||||
if (e.tipo == INDIETRO && reqs.acrobIndietroNecessaria)
|
||||
{
|
||||
value += 1;
|
||||
}
|
||||
|
||||
if (e.tipo > 0 && reqs.acrobNecessaria)
|
||||
{
|
||||
value += 1;
|
||||
}
|
||||
|
||||
if (e.tipo > 0 && acrobInSeqNecessaria)
|
||||
{
|
||||
value += 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// variabili passate come contesto alla funzione di confronto chiamata da qsort
|
||||
Requirements context;
|
||||
bool acrobInSeqNecessariaSort;
|
||||
|
||||
int greedyChoice(const void *a, const void *b)
|
||||
{
|
||||
Elemento x = *(Elemento *)a;
|
||||
Elemento y = *(Elemento *)b;
|
||||
|
||||
float va = calcElementValue(x, context, acrobInSeqNecessariaSort);
|
||||
float vb = calcElementValue(y, context, acrobInSeqNecessariaSort);
|
||||
|
||||
return vb > va;
|
||||
}
|
||||
|
||||
void swap(int *a, int *b)
|
||||
{
|
||||
int c = *a;
|
||||
*a = *b;
|
||||
*b = c;
|
||||
}
|
||||
|
||||
void swapE(Elemento *a, Elemento *b)
|
||||
{
|
||||
Elemento c = *a;
|
||||
*a = *b;
|
||||
*b = c;
|
||||
}
|
||||
|
||||
void sortAccettabili(Elemento *accettabili, int N, Requirements *reqs, bool acrobInSeqNecessaria)
|
||||
{
|
||||
context = *reqs;
|
||||
acrobInSeqNecessariaSort = acrobInSeqNecessaria;
|
||||
qsort(accettabili, N, sizeof(Elemento), greedyChoice);
|
||||
}
|
||||
|
||||
int getAccettabili(Elemento *accettabili, Elemento *elementi, int N, int DD, int DP, Elemento *soluzione, int posizioneAssoluta, int posInDiag, int currKp, int diffDiags[MAX_DIAG], int diffTot)
|
||||
{
|
||||
int N_accettabili = 0;
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
if (diffDiags[currKp] + elementi[i].diff > DD || diffTot + elementi[i].diff > DP)
|
||||
continue;
|
||||
|
||||
if (posInDiag == 0 && elementi[i].dirIngresso != FRONTE)
|
||||
continue;
|
||||
|
||||
if (posInDiag > 0 && elementi[i].dirIngresso != soluzione[posizioneAssoluta - 1].dirUscita)
|
||||
continue;
|
||||
|
||||
if (posInDiag == 0 && elementi[i].reqPreced)
|
||||
continue;
|
||||
|
||||
accettabili[N_accettabili++] = elementi[i];
|
||||
}
|
||||
|
||||
return N_accettabili;
|
||||
}
|
||||
|
||||
void stampaSoluzione(Elemento *soluzione, int *diagSize)
|
||||
{
|
||||
float totPoints = 0, diagPoints;
|
||||
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
{
|
||||
diagPoints = 0;
|
||||
for (int j = 0; j < diagSize[i]; j++)
|
||||
{
|
||||
diagPoints += soluzione[i * MAX_ELEM + j].valore;
|
||||
}
|
||||
printf("DIAG #%d > %.3f", i + 1, diagPoints);
|
||||
if (i == MAX_DIAG - 1 && soluzione[diagSize[i] + i * MAX_ELEM - 1].diff >= 8)
|
||||
{
|
||||
printf(" * 1.5 (BONUS)");
|
||||
diagPoints *= 1.5;
|
||||
}
|
||||
printf("\n");
|
||||
totPoints += diagPoints;
|
||||
for (int j = 0; j < diagSize[i]; j++)
|
||||
{
|
||||
printf("%s ", soluzione[i * MAX_ELEM + j].nome);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("TOT = %.3f\n", totPoints);
|
||||
}
|
||||
|
||||
void trovaProgrammaGreedy(Elemento *elementi, int N, int DD, int DP)
|
||||
{
|
||||
int diffDiags[MAX_DIAG] = {0};
|
||||
int tmp, minDiffAvanti = DD, minDiffIndietro = DD;
|
||||
Requirements reqs[MAX_DIAG];
|
||||
bool found;
|
||||
bool contieneElemFinale[MAX_DIAG];
|
||||
bool acrobInSeqNecessaria = true;
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
if (elementi[i].diff < minDiffAvanti && elementi[i].tipo == AVANTI)
|
||||
minDiffAvanti = elementi[i].diff;
|
||||
if (elementi[i].diff < minDiffIndietro && elementi[i].tipo == INDIETRO)
|
||||
minDiffIndietro = elementi[i].diff;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
{
|
||||
contieneElemFinale[i] = false;
|
||||
reqs[i].acrobAvantiNecessaria = reqs[i].acrobIndietroNecessaria = reqs[i].acrobNecessaria = true;
|
||||
}
|
||||
|
||||
int *diagSize = (int *)malloc(MAX_DIAG * sizeof(int));
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
diagSize[i] = 0;
|
||||
Elemento *soluzione = (Elemento *)malloc(MAX_DIAG * MAX_ELEM * sizeof(Elemento));
|
||||
Elemento *accettabili = (Elemento *)malloc(N * sizeof(Elemento));
|
||||
|
||||
int diffTot = 0;
|
||||
for (int numElem = 0; numElem < MAX_ELEM; numElem++)
|
||||
{
|
||||
for (int numDiag = 0; numDiag < MAX_DIAG; numDiag++)
|
||||
{
|
||||
int posizioneAssoluta = numElem + numDiag * MAX_ELEM;
|
||||
if (!contieneElemFinale[numDiag])
|
||||
{
|
||||
int numAcc = getAccettabili(accettabili, elementi, N, DD, DP, soluzione, posizioneAssoluta, numElem, numDiag, diffDiags, diffTot);
|
||||
if (numAcc > 0)
|
||||
{
|
||||
// Ordinamento descrescente delle scelte possibili
|
||||
sortAccettabili(accettabili, numAcc, &reqs[numDiag], acrobInSeqNecessaria);
|
||||
if (reqs[numDiag].acrobAvantiNecessaria != reqs[numDiag].acrobIndietroNecessaria)
|
||||
{
|
||||
found = false;
|
||||
if (reqs[numDiag].acrobAvantiNecessaria)
|
||||
{
|
||||
for (int i = 0; i < numAcc && !found; i++)
|
||||
{
|
||||
// Scelgo la prima diagonale che soddisfa la condizione
|
||||
if (accettabili[i].tipo == AVANTI)
|
||||
{
|
||||
found = true;
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
diagSize[numDiag]++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
for (int i = 0; i < numAcc && !found; i++)
|
||||
{
|
||||
// "cambio" la direzione in uscita dell'ultimo elemento in modo che nell'iterazione dopo si possa provare ad inserire un elemento acrobatico
|
||||
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffAvanti <= DD && !accettabili[i].finale)
|
||||
{
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
diagSize[numDiag]++;
|
||||
found = true;
|
||||
// voglio vincolare l'inserimento della acrobazia nell'iterazione successiva (rispetto alle posizioni degli elementi) a questa diagonale
|
||||
for (tmp = 0; tmp < MAX_DIAG; tmp++)
|
||||
reqs[tmp].acrobAvantiNecessaria = false;
|
||||
reqs[numDiag].acrobAvantiNecessaria = true;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
// Effettuo la scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
diagSize[numDiag]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reqs[numDiag].acrobIndietroNecessaria)
|
||||
{
|
||||
for (int i = 0; i < numAcc && !found; i++)
|
||||
{
|
||||
if (accettabili[i].tipo == INDIETRO)
|
||||
{
|
||||
found = true;
|
||||
// Effettuo la scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
diagSize[numDiag]++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
found = false;
|
||||
for (int i = 0; i < numAcc && !found; i++)
|
||||
{
|
||||
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffIndietro <= DD && !accettabili[i].finale)
|
||||
{
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
diagSize[numDiag]++;
|
||||
for (tmp = 0; tmp < MAX_DIAG; tmp++)
|
||||
reqs[tmp].acrobIndietroNecessaria = false;
|
||||
reqs[numDiag].acrobIndietroNecessaria = true;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
diagSize[numDiag]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
diagSize[numDiag]++;
|
||||
}
|
||||
|
||||
// Aggiorno le difficoltà di ogni diagonale
|
||||
diffDiags[numDiag] += soluzione[posizioneAssoluta].diff;
|
||||
diffTot += soluzione[posizioneAssoluta].diff;
|
||||
|
||||
// Aggiorno i parametri della funzione obiettivo
|
||||
if (soluzione[posizioneAssoluta].tipo == AVANTI)
|
||||
{
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
reqs[i].acrobAvantiNecessaria = false;
|
||||
}
|
||||
if (soluzione[posizioneAssoluta].tipo == INDIETRO)
|
||||
{
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
reqs[i].acrobIndietroNecessaria = false;
|
||||
}
|
||||
|
||||
if (numElem > 0 && soluzione[posizioneAssoluta].tipo > 0 && soluzione[posizioneAssoluta - 1].tipo > 0)
|
||||
{
|
||||
acrobInSeqNecessaria = false;
|
||||
}
|
||||
|
||||
if (soluzione[posizioneAssoluta].finale)
|
||||
{
|
||||
// Blocco l'inserimento di elementi nella diagonale
|
||||
contieneElemFinale[numDiag] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cerco la diagonale con l'elemento che permette di ottenere il bonus
|
||||
int bonusDiag = -1;
|
||||
for (int numDiag = 0; numDiag < MAX_DIAG; numDiag++)
|
||||
{
|
||||
if (soluzione[diagSize[numDiag] + numDiag * MAX_ELEM - 1].diff >= 8)
|
||||
bonusDiag = numDiag;
|
||||
}
|
||||
|
||||
// Sposto se ho trovato una diagonale idonea al bonus che non è già in ultima posizione
|
||||
if (bonusDiag != -1 && bonusDiag != MAX_DIAG - 1)
|
||||
{
|
||||
swap(&diagSize[MAX_DIAG - 1], &diagSize[bonusDiag]);
|
||||
for (int i = 0; i < MAX_ELEM; i++)
|
||||
swapE(&soluzione[i + (MAX_DIAG - 1) * MAX_ELEM], &soluzione[i + bonusDiag * MAX_ELEM]);
|
||||
}
|
||||
|
||||
stampaSoluzione(soluzione, diagSize);
|
||||
|
||||
free(accettabili);
|
||||
free(soluzione);
|
||||
free(diagSize);
|
||||
return;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int N = 0, DP, DD;
|
||||
;
|
||||
Elemento *l = leggiFile("elementi.txt", &N);
|
||||
printf("Inserisci DD e DP: ");
|
||||
scanf("%d %d", &DD, &DP);
|
||||
|
||||
trovaProgrammaGreedy(l, N, DD, DP);
|
||||
|
||||
free(l);
|
||||
return 0;
|
||||
}
|
||||
297
Laboratorio 8/Esercizio 1/main2.c
Normal file
297
Laboratorio 8/Esercizio 1/main2.c
Normal file
@@ -0,0 +1,297 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "Elementi.h"
|
||||
#define MAX_ELEM 5
|
||||
#define MAX_DIAG 3
|
||||
|
||||
typedef struct params {
|
||||
bool acrobNecessaria;
|
||||
bool acrobAvantiNecessaria;
|
||||
bool acrobIndietroNecessaria;
|
||||
} Requirements;
|
||||
|
||||
Elemento *leggiFile(char *filename, int *N)
|
||||
{
|
||||
FILE *fin;
|
||||
if ((fin = fopen(filename, "r")) == NULL)
|
||||
{
|
||||
puts("Impossibile aprire il file");
|
||||
return NULL;
|
||||
}
|
||||
fscanf(fin, "%d", N);
|
||||
Elemento *lista = malloc(*N * sizeof(Elemento));
|
||||
for (int i = 0; i < *N; i++)
|
||||
{
|
||||
lista[i] = leggiElemento(fin);
|
||||
}
|
||||
fclose(fin);
|
||||
return lista;
|
||||
}
|
||||
|
||||
float calcElementValue(Elemento e, Requirements reqs, bool acrobInSeqNecessaria) {
|
||||
float value = (e.valore / e.diff);
|
||||
|
||||
if (e.tipo == AVANTI && reqs.acrobAvantiNecessaria) {
|
||||
value += 1;
|
||||
}
|
||||
|
||||
if (e.tipo == INDIETRO && reqs.acrobIndietroNecessaria) {
|
||||
value += 1;
|
||||
}
|
||||
|
||||
if (e.tipo > 0 && reqs.acrobNecessaria) {
|
||||
value += 1;
|
||||
}
|
||||
|
||||
if (e.tipo > 0 && acrobInSeqNecessaria) {
|
||||
value += 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// variabili passate come contesto alla funzione di confronto chiamata da qsort
|
||||
Requirements context;
|
||||
bool acrobInSeqNecessariaSort;
|
||||
|
||||
int greedyChoice(const void *a, const void *b) {
|
||||
Elemento x = *(Elemento *)a;
|
||||
Elemento y = *(Elemento *)b;
|
||||
|
||||
float va = calcElementValue(x, context, acrobInSeqNecessariaSort);
|
||||
float vb = calcElementValue(y, context, acrobInSeqNecessariaSort);
|
||||
|
||||
return vb > va;
|
||||
}
|
||||
|
||||
void sortAccettabili(Elemento *accettabili, int N, Requirements *reqs, bool acrobInSeqNecessaria) {
|
||||
context = *reqs;
|
||||
acrobInSeqNecessariaSort = acrobInSeqNecessaria;
|
||||
qsort(accettabili, N, sizeof(Elemento), greedyChoice);
|
||||
}
|
||||
|
||||
int getAccettabili(Elemento *accettabili, Elemento *elementi, int N, int DD, int DP, Elemento *soluzione, int posizioneAssoluta, int posInDiag, int currKp, int diffDiags[MAX_DIAG], int diffTot) {
|
||||
int N_accettabili = 0;
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (diffDiags[currKp] + elementi[i].diff > DD || diffTot + elementi[i].diff > DP)
|
||||
continue;
|
||||
|
||||
if (posInDiag == 0 && elementi[i].dirIngresso != FRONTE)
|
||||
continue;
|
||||
|
||||
if (posInDiag > 0 && elementi[i].dirIngresso != soluzione[posizioneAssoluta-1].dirUscita)
|
||||
continue;
|
||||
|
||||
if (posInDiag == 0 && elementi[i].reqPreced)
|
||||
continue;
|
||||
|
||||
accettabili[N_accettabili++] = elementi[i];
|
||||
}
|
||||
|
||||
return N_accettabili;
|
||||
}
|
||||
|
||||
void stampaSoluzione(Elemento *sol, int N, int *kp) {
|
||||
int i, j, diagonaleBonus = -1;
|
||||
float tot = 0, parz;
|
||||
|
||||
// Ricerca possibile diagonale con elemento bonus
|
||||
for (i = 0; i < MAX_DIAG && diagonaleBonus == -1; i++) {
|
||||
for (j = 0; j < MAX_ELEM && diagonaleBonus == -1; j++) {
|
||||
if ((kp[j + MAX_ELEM * i] == -1 || j == MAX_ELEM - 1) && sol[j + MAX_ELEM * i - 1].diff >= 8) {
|
||||
diagonaleBonus = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scambio diagonale bonus, se trovata, con l'ultima diagonale
|
||||
if (diagonaleBonus != -1 && diagonaleBonus != MAX_DIAG - 1) {
|
||||
for (i = 0; i < N; i++) {
|
||||
if (kp[i] == diagonaleBonus) kp[i] = MAX_DIAG;
|
||||
if (kp[i] == MAX_DIAG - 1) kp[i] = diagonaleBonus;
|
||||
}
|
||||
for (i = 0; i < N; i++) {
|
||||
if (kp[i] == MAX_DIAG) kp[i] = MAX_DIAG - 1;
|
||||
}
|
||||
diagonaleBonus = MAX_DIAG - 1;
|
||||
}
|
||||
|
||||
for (j = 0; j < MAX_DIAG; j++) {
|
||||
parz = 0;
|
||||
for (i = 0; i < N; i++) {
|
||||
if (kp[i] == j) {
|
||||
parz += sol[i].valore;
|
||||
}
|
||||
}
|
||||
printf("DIAG #%d > %.3f", j+1, parz);
|
||||
if (j == diagonaleBonus)
|
||||
printf(" * 1.5 (BONUS)");
|
||||
printf("\n");
|
||||
if (j == diagonaleBonus) {
|
||||
parz = parz * 1.5;
|
||||
}
|
||||
tot += parz;
|
||||
for (i = 0; i < N; i++) {
|
||||
if (kp[i] == j) {
|
||||
printf("%s ", sol[i].nome);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("TOT = %.3f\n", tot);
|
||||
}
|
||||
|
||||
void trovaProgrammaGreedy(Elemento *elementi, int N, int DD, int DP) {
|
||||
int diffDiags[MAX_DIAG] = {0};
|
||||
int tmp, minDiffAvanti = DD, minDiffIndietro = DD;
|
||||
Requirements reqs[MAX_DIAG];
|
||||
bool found;
|
||||
bool contieneElemFinale[MAX_DIAG];
|
||||
bool acrobInSeqNecessaria = true;
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (elementi[i].diff < minDiffAvanti && elementi[i].tipo == AVANTI)
|
||||
minDiffAvanti = elementi[i].diff;
|
||||
if (elementi[i].diff < minDiffIndietro && elementi[i].tipo == INDIETRO)
|
||||
minDiffIndietro = elementi[i].diff;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_DIAG; i++) {
|
||||
contieneElemFinale[i] = false;
|
||||
reqs[i].acrobAvantiNecessaria = reqs[i].acrobIndietroNecessaria = reqs[i].acrobNecessaria = true;
|
||||
}
|
||||
|
||||
int *kp = (int *) malloc(MAX_DIAG * MAX_ELEM * sizeof(int));
|
||||
for (int i = 0; i < MAX_DIAG * MAX_ELEM; i++)
|
||||
kp[i] = -1;
|
||||
Elemento *soluzione = (Elemento *) malloc(MAX_DIAG * MAX_ELEM * sizeof(Elemento));
|
||||
Elemento *accettabili = (Elemento *) malloc(N * sizeof(Elemento));
|
||||
|
||||
int diffTot = 0;
|
||||
for (int numElem = 0; numElem < MAX_ELEM; numElem++) {
|
||||
for (int numDiag = 0; numDiag < MAX_DIAG; numDiag++) {
|
||||
int posizioneAssoluta = numElem + numDiag * MAX_ELEM;
|
||||
if (!contieneElemFinale[numDiag]) {
|
||||
int numAcc = getAccettabili(accettabili, elementi, N, DD, DP, soluzione, posizioneAssoluta, numElem, numDiag, diffDiags, diffTot);
|
||||
if (numAcc > 0) {
|
||||
// Ordinamento descrescente delle scelte possibili
|
||||
sortAccettabili(accettabili, numAcc, &reqs[numDiag], acrobInSeqNecessaria);
|
||||
if (reqs[numDiag].acrobAvantiNecessaria != reqs[numDiag].acrobIndietroNecessaria) {
|
||||
found = false;
|
||||
if (reqs[numDiag].acrobAvantiNecessaria) {
|
||||
for (int i = 0; i < numAcc && !found; i++) {
|
||||
// Scelgo la prima diagonale che soddisfa la condizione
|
||||
if (accettabili[i].tipo == AVANTI) {
|
||||
found = true;
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
for (int i = 0; i < numAcc && !found; i++) {
|
||||
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffAvanti <= DD && !accettabili[i].finale) {
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
found = true;
|
||||
for (tmp = 0; tmp < MAX_DIAG; tmp++)
|
||||
reqs[tmp].acrobAvantiNecessaria = false;
|
||||
reqs[numDiag].acrobAvantiNecessaria = true;
|
||||
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reqs[numDiag].acrobIndietroNecessaria) {
|
||||
for (int i = 0; i < numAcc && !found; i++) {
|
||||
if (accettabili[i].tipo == INDIETRO) {
|
||||
found = true;
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
found = false;
|
||||
for (int i = 0; i < numAcc && !found; i++) {
|
||||
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffIndietro <= DD && !accettabili[i].finale) {
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
for (tmp = 0; tmp < MAX_DIAG; tmp++)
|
||||
reqs[tmp].acrobIndietroNecessaria = false;
|
||||
reqs[numDiag].acrobIndietroNecessaria = true;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
}
|
||||
|
||||
// Aggiornamento difficoltà
|
||||
diffDiags[numDiag] += soluzione[posizioneAssoluta].diff;
|
||||
diffTot += soluzione[posizioneAssoluta].diff;
|
||||
|
||||
// Aggiornamento parametri funzione obiettivo
|
||||
if (soluzione[posizioneAssoluta].tipo == AVANTI) {
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
reqs[i].acrobAvantiNecessaria = false;
|
||||
reqs[numDiag].acrobIndietroNecessaria = false;
|
||||
}
|
||||
if (soluzione[posizioneAssoluta].tipo == INDIETRO) {
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
reqs[i].acrobIndietroNecessaria = false;
|
||||
reqs[numDiag].acrobAvantiNecessaria = false;
|
||||
}
|
||||
|
||||
if (numElem > 0 && soluzione[posizioneAssoluta].tipo > 0 && soluzione[posizioneAssoluta-1].tipo > 0) {
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
acrobInSeqNecessaria = false;
|
||||
}
|
||||
|
||||
if (soluzione[posizioneAssoluta].finale) {
|
||||
// Blocco l'inserimento di elementi nella diagonale
|
||||
contieneElemFinale[numDiag] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stampaSoluzione(soluzione, MAX_DIAG * MAX_ELEM, kp);
|
||||
|
||||
free(accettabili);
|
||||
free(soluzione);
|
||||
free(kp);
|
||||
return;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int N = 0, DP, DD;;
|
||||
Elemento *l = leggiFile("elementi.txt", &N);
|
||||
printf("Inserisci DD e DP: ");
|
||||
scanf("%d %d", &DD, &DP);
|
||||
|
||||
trovaProgrammaGreedy(l, N, DD, DP);
|
||||
|
||||
free(l);
|
||||
return 0;
|
||||
}
|
||||
376
Laboratorio 8/Esercizio 1/mainlosttest.c
Normal file
376
Laboratorio 8/Esercizio 1/mainlosttest.c
Normal file
@@ -0,0 +1,376 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "Elementi.h"
|
||||
#define MAX_ELEM 5
|
||||
#define MAX_DIAG 3
|
||||
|
||||
typedef struct params
|
||||
{
|
||||
bool acrobNecessaria;
|
||||
} Requirements;
|
||||
|
||||
typedef struct gparams
|
||||
{
|
||||
bool acrobAvantiNecessaria;
|
||||
bool acrobIndietroNecessaria;
|
||||
bool acrobInSeqNecessaria;
|
||||
} GlobalRequirements;
|
||||
|
||||
Elemento *leggiFile(char *filename, int *N)
|
||||
{
|
||||
FILE *fin;
|
||||
if ((fin = fopen(filename, "r")) == NULL)
|
||||
{
|
||||
puts("Impossibile aprire il file");
|
||||
return NULL;
|
||||
}
|
||||
fscanf(fin, "%d", N);
|
||||
Elemento *lista = malloc(*N * sizeof(Elemento));
|
||||
for (int i = 0; i < *N; i++)
|
||||
{
|
||||
lista[i] = leggiElemento(fin);
|
||||
}
|
||||
fclose(fin);
|
||||
return lista;
|
||||
}
|
||||
|
||||
float calcElementValue(Elemento e, Requirements reqs, GlobalRequirements greqs)
|
||||
{
|
||||
float value = (e.valore / e.diff);
|
||||
|
||||
if (e.tipo == AVANTI && greqs.acrobAvantiNecessaria)
|
||||
{
|
||||
value += 1;
|
||||
}
|
||||
|
||||
if (e.tipo == INDIETRO && greqs.acrobIndietroNecessaria)
|
||||
{
|
||||
value += 1;
|
||||
}
|
||||
|
||||
if (e.tipo > 0 && reqs.acrobNecessaria)
|
||||
{
|
||||
value += 1;
|
||||
}
|
||||
|
||||
if (e.tipo > 0 && greqs.acrobInSeqNecessaria)
|
||||
{
|
||||
value += 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// variabili passate come contesto alla funzione di confronto chiamata da qsort
|
||||
Requirements context;
|
||||
GlobalRequirements gcontext;
|
||||
|
||||
int greedyChoice(const void *a, const void *b)
|
||||
{
|
||||
Elemento x = *(Elemento *)a;
|
||||
Elemento y = *(Elemento *)b;
|
||||
|
||||
float va = calcElementValue(x, context, gcontext);
|
||||
float vb = calcElementValue(y, context, gcontext);
|
||||
|
||||
return vb > va;
|
||||
}
|
||||
|
||||
void swap(int *a, int *b)
|
||||
{
|
||||
int c = *a;
|
||||
*a = *b;
|
||||
*b = c;
|
||||
}
|
||||
|
||||
void swapE(Elemento *a, Elemento *b)
|
||||
{
|
||||
Elemento c = *a;
|
||||
*a = *b;
|
||||
*b = c;
|
||||
}
|
||||
|
||||
void sortAccettabili(Elemento *accettabili, int N, Requirements *reqs, GlobalRequirements *greqs)
|
||||
{
|
||||
context = *reqs;
|
||||
gcontext = *greqs;
|
||||
qsort(accettabili, N, sizeof(Elemento), greedyChoice);
|
||||
}
|
||||
|
||||
int getAccettabili(Elemento *accettabili, Elemento *elementi, int N, int DD, int DP, Elemento *soluzione, int posizioneAssoluta, int posInDiag, int currKp, int diffDiags[MAX_DIAG], int diffTot)
|
||||
{
|
||||
int N_accettabili = 0;
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
if (diffDiags[currKp] + elementi[i].diff > DD || diffTot + elementi[i].diff > DP)
|
||||
continue;
|
||||
|
||||
if (posInDiag == 0 && elementi[i].dirIngresso != FRONTE)
|
||||
continue;
|
||||
|
||||
if (posInDiag > 0 && elementi[i].dirIngresso != soluzione[posizioneAssoluta - 1].dirUscita)
|
||||
continue;
|
||||
|
||||
if (posInDiag == 0 && elementi[i].reqPreced)
|
||||
continue;
|
||||
|
||||
accettabili[N_accettabili++] = elementi[i];
|
||||
}
|
||||
|
||||
return N_accettabili;
|
||||
}
|
||||
|
||||
void stampaSoluzione(Elemento *soluzione, int *diagSize)
|
||||
{
|
||||
float totPoints = 0, diagPoints;
|
||||
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
{
|
||||
diagPoints = 0;
|
||||
for (int j = 0; j < diagSize[i]; j++)
|
||||
{
|
||||
diagPoints += soluzione[i * MAX_ELEM + j].valore;
|
||||
}
|
||||
printf("DIAG #%d > %.3f", i + 1, diagPoints);
|
||||
if (i == MAX_DIAG - 1 && soluzione[diagSize[i] + i * MAX_ELEM - 1].diff >= 8)
|
||||
{
|
||||
printf(" * 1.5 (BONUS)");
|
||||
diagPoints *= 1.5;
|
||||
}
|
||||
printf("\n");
|
||||
totPoints += diagPoints;
|
||||
for (int j = 0; j < diagSize[i]; j++)
|
||||
{
|
||||
printf("%s ", soluzione[i * MAX_ELEM + j].nome);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("TOT = %.3f\n", totPoints);
|
||||
}
|
||||
|
||||
void trovaProgrammaGreedy(Elemento *elementi, int N, int DD, int DP)
|
||||
{
|
||||
int diffDiags[MAX_DIAG] = {0};
|
||||
int tmp, minDiffAvanti = DD, minDiffIndietro = DD;
|
||||
Requirements reqs[MAX_DIAG];
|
||||
GlobalRequirements greqs;
|
||||
bool found;
|
||||
bool contieneElemFinale[MAX_DIAG];
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
if (elementi[i].diff < minDiffAvanti && elementi[i].tipo == AVANTI)
|
||||
minDiffAvanti = elementi[i].diff;
|
||||
if (elementi[i].diff < minDiffIndietro && elementi[i].tipo == INDIETRO)
|
||||
minDiffIndietro = elementi[i].diff;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
{
|
||||
contieneElemFinale[i] = false;
|
||||
reqs[i].acrobNecessaria = true;
|
||||
}
|
||||
|
||||
greqs.acrobAvantiNecessaria = greqs.acrobIndietroNecessaria = greqs.acrobInSeqNecessaria = true;
|
||||
|
||||
int *diagSize = (int *)malloc(MAX_DIAG * sizeof(int));
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
diagSize[i] = 0;
|
||||
Elemento *soluzione = (Elemento *)malloc(MAX_DIAG * MAX_ELEM * sizeof(Elemento));
|
||||
Elemento *accettabili = (Elemento *)malloc(N * sizeof(Elemento));
|
||||
|
||||
int diffTot = 0;
|
||||
for (int numElem = 0; numElem < MAX_ELEM; numElem++)
|
||||
{
|
||||
for (int numDiag = 0; numDiag < MAX_DIAG; numDiag++)
|
||||
{
|
||||
int posizioneAssoluta = numElem + numDiag * MAX_ELEM;
|
||||
if (!contieneElemFinale[numDiag])
|
||||
{
|
||||
int numAcc = getAccettabili(accettabili, elementi, N, DD, DP, soluzione, posizioneAssoluta, numElem, numDiag, diffDiags, diffTot);
|
||||
if (numAcc > 0)
|
||||
{
|
||||
// Ordinamento descrescente delle scelte possibili
|
||||
sortAccettabili(accettabili, numAcc, &reqs[numDiag], &greqs);
|
||||
if (greqs.acrobAvantiNecessaria != greqs.acrobIndietroNecessaria || reqs->acrobNecessaria)
|
||||
{
|
||||
found = false;
|
||||
if (greqs.acrobAvantiNecessaria)
|
||||
{
|
||||
for (int i = 0; i < numAcc && !found; i++)
|
||||
{
|
||||
// Scelgo il primo elemento che soddisfa la condizione
|
||||
if (accettabili[i].tipo == AVANTI)
|
||||
{
|
||||
found = true;
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
diagSize[numDiag]++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
for (int i = 0; i < numAcc && !found; i++)
|
||||
{
|
||||
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffAvanti <= DD && !accettabili[i].finale)
|
||||
{
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
diagSize[numDiag]++;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
diagSize[numDiag]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (greqs.acrobIndietroNecessaria)
|
||||
{
|
||||
for (int i = 0; i < numAcc && !found; i++)
|
||||
{
|
||||
if (accettabili[i].tipo == INDIETRO)
|
||||
{
|
||||
found = true;
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
diagSize[numDiag]++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
found = false;
|
||||
for (int i = 0; i < numAcc && !found; i++)
|
||||
{
|
||||
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffIndietro <= DD && !accettabili[i].finale)
|
||||
{
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
diagSize[numDiag]++;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
diagSize[numDiag]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!greqs.acrobInSeqNecessaria)
|
||||
{
|
||||
for (int i = 0; i < numAcc && !found; i++)
|
||||
{
|
||||
if (accettabili[i].tipo != TRANSIZIONE && diffDiags[numDiag] + accettabili[i].diff + minDiffAvanti <= DD && !accettabili[i].finale)
|
||||
{
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
diagSize[numDiag]++;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
diagSize[numDiag]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < numAcc && !found; i++)
|
||||
{
|
||||
// Scelgo il primo elemento che soddisfa la condizione
|
||||
if (accettabili[i].tipo != TRANSIZIONE)
|
||||
{
|
||||
found = true;
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
diagSize[numDiag]++;
|
||||
if (!greqs.acrobInSeqNecessaria)
|
||||
{
|
||||
reqs[i].acrobNecessaria = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
diagSize[numDiag]++;
|
||||
}
|
||||
|
||||
// Aggiornamento difficoltà
|
||||
diffDiags[numDiag] += soluzione[posizioneAssoluta].diff;
|
||||
diffTot += soluzione[posizioneAssoluta].diff;
|
||||
|
||||
// Aggiornamento parametri funzione obiettivo
|
||||
if (soluzione[posizioneAssoluta].tipo == AVANTI)
|
||||
{
|
||||
greqs.acrobAvantiNecessaria = false;
|
||||
}
|
||||
if (soluzione[posizioneAssoluta].tipo == INDIETRO)
|
||||
{
|
||||
greqs.acrobIndietroNecessaria = false;
|
||||
}
|
||||
|
||||
if (numElem > 0 && soluzione[posizioneAssoluta].tipo > 0 && soluzione[posizioneAssoluta - 1].tipo > 0)
|
||||
{
|
||||
greqs.acrobInSeqNecessaria = false;
|
||||
}
|
||||
|
||||
if (soluzione[posizioneAssoluta].finale)
|
||||
{
|
||||
// Blocco l'inserimento di elementi nella diagonale
|
||||
contieneElemFinale[numDiag] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cerco la diagonale con l'elemento che permette di ottenere il bonus
|
||||
int bonusDiag = -1;
|
||||
for (int numDiag = 0; numDiag < MAX_DIAG; numDiag++)
|
||||
{
|
||||
if (soluzione[diagSize[numDiag] + numDiag * MAX_ELEM - 1].diff >= 8)
|
||||
bonusDiag = numDiag;
|
||||
}
|
||||
|
||||
// Sposto se ho trovato un elemento con bonus che non è già in ultima posizione
|
||||
if (bonusDiag != -1 && bonusDiag != MAX_DIAG - 1)
|
||||
{
|
||||
swap(&diagSize[MAX_DIAG - 1], &diagSize[bonusDiag]);
|
||||
for (int i = 0; i < MAX_ELEM; i++)
|
||||
swapE(&soluzione[i + (MAX_DIAG - 1) * MAX_ELEM], &soluzione[i + bonusDiag * MAX_ELEM]);
|
||||
}
|
||||
|
||||
stampaSoluzione(soluzione, diagSize);
|
||||
|
||||
free(accettabili);
|
||||
free(soluzione);
|
||||
free(diagSize);
|
||||
return;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int N = 0, DP, DD;
|
||||
;
|
||||
Elemento *l = leggiFile("elementi.txt", &N);
|
||||
printf("Inserisci DD e DP: ");
|
||||
scanf("%d %d", &DD, &DP);
|
||||
|
||||
trovaProgrammaGreedy(l, N, DD, DP);
|
||||
|
||||
free(l);
|
||||
return 0;
|
||||
}
|
||||
301
Laboratorio 8/Esercizio 1/mainstr.c
Normal file
301
Laboratorio 8/Esercizio 1/mainstr.c
Normal file
@@ -0,0 +1,301 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "Elementi.h"
|
||||
#define MAX_ELEM 5
|
||||
#define MAX_DIAG 3
|
||||
|
||||
typedef struct params {
|
||||
bool acrobNecessaria;
|
||||
bool acrobAvantiNecessaria;
|
||||
bool acrobIndietroNecessaria;
|
||||
bool haAcrobInSeq;
|
||||
bool acrobInSeqNecessaria;
|
||||
} Requirements;
|
||||
|
||||
Elemento *leggiFile(char *filename, int *N)
|
||||
{
|
||||
FILE *fin;
|
||||
if ((fin = fopen(filename, "r")) == NULL)
|
||||
{
|
||||
puts("Impossibile aprire il file");
|
||||
return NULL;
|
||||
}
|
||||
fscanf(fin, "%d", N);
|
||||
Elemento *lista = malloc(*N * sizeof(Elemento));
|
||||
for (int i = 0; i < *N; i++)
|
||||
{
|
||||
lista[i] = leggiElemento(fin);
|
||||
}
|
||||
fclose(fin);
|
||||
return lista;
|
||||
}
|
||||
|
||||
float calcElementValue(Elemento e, Requirements reqs) {
|
||||
float value = (e.valore / e.diff);
|
||||
|
||||
if (e.tipo == AVANTI && reqs.acrobAvantiNecessaria) {
|
||||
value += 1;
|
||||
}
|
||||
|
||||
if (e.tipo == INDIETRO && reqs.acrobIndietroNecessaria) {
|
||||
value += 1;
|
||||
}
|
||||
|
||||
if (e.tipo > 0 && reqs.acrobNecessaria) {
|
||||
value += 1;
|
||||
}
|
||||
|
||||
if (e.tipo > 0 && reqs.acrobInSeqNecessaria) {
|
||||
value += 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
Requirements context;
|
||||
|
||||
int greedyChoice(const void *a, const void *b) {
|
||||
Elemento x = *(Elemento *)a;
|
||||
Elemento y = *(Elemento *)b;
|
||||
|
||||
float va = calcElementValue(x, context);
|
||||
float vb = calcElementValue(y, context);
|
||||
|
||||
return vb > va;
|
||||
}
|
||||
|
||||
void sortAccettabili(Elemento *accettabili, int N, Requirements *reqs) {
|
||||
context = *reqs;
|
||||
qsort(accettabili, N, sizeof(Elemento), greedyChoice);
|
||||
}
|
||||
|
||||
int getAccettabili(Elemento *accettabili, Elemento *elementi, int N, int DD, int DP, Elemento *soluzione, int posizioneAssoluta, int posInDiag, int currKp, int diffDiags[MAX_DIAG], int diffTot) {
|
||||
int N_accettabili = 0;
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (diffDiags[currKp] + elementi[i].diff > DD || diffTot + elementi[i].diff > DP)
|
||||
continue;
|
||||
|
||||
if (posInDiag == 0 && elementi[i].dirIngresso != FRONTE)
|
||||
continue;
|
||||
|
||||
if (posInDiag > 0 && elementi[i].dirIngresso != soluzione[posizioneAssoluta-1].dirUscita)
|
||||
continue;
|
||||
|
||||
if (posInDiag == 0 && elementi[i].reqPreced)
|
||||
continue;
|
||||
|
||||
accettabili[N_accettabili++] = elementi[i];
|
||||
}
|
||||
|
||||
return N_accettabili;
|
||||
}
|
||||
|
||||
void stampaSoluzione(Elemento *sol, int N, int *kp) {
|
||||
int i, j, bonusKp = -1;
|
||||
float tot = 0, parz;
|
||||
|
||||
// Ricerca possibile diagonale con elemento bonus
|
||||
for (i = 0; i < MAX_DIAG && bonusKp == -1; i++) {
|
||||
for (j = 0; j < MAX_ELEM && bonusKp == -1; j++) {
|
||||
if ((kp[j + MAX_ELEM * i] == -1 || j == MAX_ELEM - 1) && sol[j + MAX_ELEM * i - 1].diff >= 8) {
|
||||
bonusKp = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scambio diagonale bonus, se trovata, con l'ultima diagonale
|
||||
if (bonusKp != -1 && bonusKp != MAX_DIAG - 1) {
|
||||
for (i = 0; i < N; i++) {
|
||||
if (kp[i] == bonusKp) kp[i] = MAX_DIAG;
|
||||
if (kp[i] == MAX_DIAG - 1) kp[i] = bonusKp;
|
||||
}
|
||||
for (i = 0; i < N; i++) {
|
||||
if (kp[i] == MAX_DIAG) kp[i] = MAX_DIAG - 1;
|
||||
}
|
||||
bonusKp = MAX_DIAG - 1;
|
||||
}
|
||||
|
||||
for (j = 0; j < MAX_DIAG; j++) {
|
||||
parz = 0;
|
||||
for (i = 0; i < N; i++) {
|
||||
if (kp[i] == j) {
|
||||
parz += sol[i].valore;
|
||||
}
|
||||
}
|
||||
printf("DIAG #%d > %.3f", j+1, parz);
|
||||
if (j == bonusKp)
|
||||
printf(" * 1.5 (BONUS)");
|
||||
printf("\n");
|
||||
if (j == bonusKp) {
|
||||
parz = parz * 1.5;
|
||||
}
|
||||
tot += parz;
|
||||
for (i = 0; i < N; i++) {
|
||||
if (kp[i] == j) {
|
||||
printf("%s ", sol[i].nome);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("TOT = %.3f\n", tot);
|
||||
}
|
||||
|
||||
void trovaProgrammaGreedy(Elemento *elementi, int N, int DD, int DP) {
|
||||
int diffDiags[MAX_DIAG] = {0};
|
||||
int tmp, minDiffAvanti = DD, minDiffIndietro = DD;
|
||||
Requirements reqs[MAX_DIAG];
|
||||
bool found;
|
||||
bool contieneElemFinale[MAX_DIAG];
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (elementi[i].diff < minDiffAvanti && elementi[i].tipo == AVANTI)
|
||||
minDiffAvanti = elementi[i].diff;
|
||||
if (elementi[i].diff < minDiffIndietro && elementi[i].tipo == INDIETRO)
|
||||
minDiffIndietro = elementi[i].diff;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_DIAG; i++) {
|
||||
contieneElemFinale[i] = false;
|
||||
reqs[i].acrobInSeqNecessaria = reqs[i].haAcrobInSeq = false;
|
||||
reqs[i].acrobAvantiNecessaria = reqs[i].acrobIndietroNecessaria = reqs[i].acrobNecessaria = true;
|
||||
}
|
||||
|
||||
int *kp = (int *) malloc(MAX_DIAG * MAX_ELEM * sizeof(int));
|
||||
for (int i = 0; i < MAX_DIAG * MAX_ELEM; i++)
|
||||
kp[i] = -1;
|
||||
Elemento *soluzione = (Elemento *) malloc(MAX_DIAG * MAX_ELEM * sizeof(Elemento));
|
||||
Elemento *accettabili = (Elemento *) malloc(N * sizeof(Elemento));
|
||||
|
||||
int diffTot = 0;
|
||||
for (int numElem = 0; numElem < MAX_ELEM; numElem++) {
|
||||
for (int numDiag = 0; numDiag < MAX_DIAG; numDiag++) {
|
||||
int posizioneAssoluta = numElem + numDiag * MAX_ELEM;
|
||||
if (!contieneElemFinale[numDiag]) {
|
||||
int numAcc = getAccettabili(accettabili, elementi, N, DD, DP, soluzione, posizioneAssoluta, numElem, numDiag, diffDiags, diffTot);
|
||||
if (numAcc > 0) {
|
||||
// Ordinamento descrescente delle scelte possibili
|
||||
sortAccettabili(accettabili, numAcc, &reqs[numDiag]);
|
||||
if (reqs[numDiag].acrobAvantiNecessaria != reqs[numDiag].acrobIndietroNecessaria) {
|
||||
found = false;
|
||||
if (reqs[numDiag].acrobAvantiNecessaria) {
|
||||
for (int i = 0; i < numAcc && !found; i++) {
|
||||
// Scelgo la prima diagonale che soddisfa la condizione
|
||||
if (accettabili[i].tipo == AVANTI) {
|
||||
found = true;
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
for (int i = 0; i < numAcc && !found; i++) {
|
||||
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffAvanti <= DD && !accettabili[i].finale) {
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
found = true;
|
||||
for (tmp = 0; tmp < MAX_DIAG; tmp++)
|
||||
reqs[tmp].acrobAvantiNecessaria = false;
|
||||
reqs[numDiag].acrobAvantiNecessaria = true;
|
||||
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reqs[numDiag].acrobIndietroNecessaria) {
|
||||
for (int i = 0; i < numAcc && !found; i++) {
|
||||
if (accettabili[i].tipo == INDIETRO) {
|
||||
found = true;
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
found = false;
|
||||
for (int i = 0; i < numAcc && !found; i++) {
|
||||
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffIndietro <= DD && !accettabili[i].finale) {
|
||||
soluzione[posizioneAssoluta] = accettabili[i];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
for (tmp = 0; tmp < MAX_DIAG; tmp++)
|
||||
reqs[tmp].acrobIndietroNecessaria = false;
|
||||
reqs[numDiag].acrobIndietroNecessaria = true;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Effettuo scelta localmente ottima
|
||||
soluzione[posizioneAssoluta] = accettabili[0];
|
||||
kp[posizioneAssoluta] = numDiag;
|
||||
}
|
||||
|
||||
// Aggiornamento difficoltà
|
||||
diffDiags[numDiag] += soluzione[posizioneAssoluta].diff;
|
||||
diffTot += soluzione[posizioneAssoluta].diff;
|
||||
|
||||
// Aggiornamento parametri funzione obiettivo
|
||||
if (soluzione[posizioneAssoluta].tipo == AVANTI) {
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
reqs[i].acrobAvantiNecessaria = false;
|
||||
reqs[numDiag].acrobIndietroNecessaria = false;
|
||||
}
|
||||
if (soluzione[posizioneAssoluta].tipo == INDIETRO) {
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
reqs[i].acrobIndietroNecessaria = false;
|
||||
reqs[numDiag].acrobAvantiNecessaria = false;
|
||||
}
|
||||
|
||||
if (numElem > 0 && soluzione[posizioneAssoluta].tipo > 0 && soluzione[posizioneAssoluta-1].tipo > 0) {
|
||||
for (int i = 0; i < MAX_DIAG; i++)
|
||||
reqs[i].haAcrobInSeq = true;
|
||||
}
|
||||
|
||||
if (numElem > 0 && soluzione[posizioneAssoluta-1].tipo > 0 && !reqs[numDiag].haAcrobInSeq) {
|
||||
reqs[numDiag].acrobInSeqNecessaria = true;
|
||||
} else
|
||||
reqs[numDiag].acrobInSeqNecessaria = false;
|
||||
|
||||
if (soluzione[posizioneAssoluta].finale) {
|
||||
// Skip a prossima diagonale se è stato inserito un elemento finale
|
||||
contieneElemFinale[numDiag] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stampaSoluzione(soluzione, MAX_DIAG * MAX_ELEM, kp);
|
||||
|
||||
free(accettabili);
|
||||
free(soluzione);
|
||||
free(kp);
|
||||
return;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int N = 0, DP, DD;;
|
||||
Elemento *l = leggiFile("elementi.txt", &N);
|
||||
printf("Inserisci DD e DP: ");
|
||||
scanf("%d %d", &DD, &DP);
|
||||
|
||||
trovaProgrammaGreedy(l, N, DD, DP);
|
||||
|
||||
free(l);
|
||||
return 0;
|
||||
}
|
||||
59
Laboratorio 8/Esercizio 1/testset_risulutati.txt
Normal file
59
Laboratorio 8/Esercizio 1/testset_risulutati.txt
Normal file
@@ -0,0 +1,59 @@
|
||||
--- Test Case #1 ---
|
||||
DD = 10 DP = 20
|
||||
TOT = 17.800
|
||||
DIAG #1 > 1.750
|
||||
front_tuck
|
||||
DIAG #2 > 3.750
|
||||
front_tuck front_pike
|
||||
DIAG #3 > 8.200 * 1.5 (BONUS)
|
||||
rondata back_layout_double_twist
|
||||
|
||||
--- Test Case #2 ---
|
||||
DD = 7 DP = 30
|
||||
TOT = 11.200
|
||||
DIAG #1 > 3.700
|
||||
rondata back_tuck back_tuck
|
||||
DIAG #2 > 3.750
|
||||
front_tuck front_pike
|
||||
DIAG #3 > 3.750
|
||||
front_tuck front_pike
|
||||
|
||||
--- Test Case #3 ---
|
||||
DD = 10 DP = 35
|
||||
TOT = 26.250
|
||||
DIAG #1 > 5.750
|
||||
front_tuck double_front_layout
|
||||
DIAG #2 > 8.200
|
||||
rondata back_layout_double_twist
|
||||
DIAG #3 > 8.200 * 1.5 (BONUS)
|
||||
rondata back_layout_double_twist
|
||||
|
||||
--- Test Case #4 ---
|
||||
DD = 12 DP = 28
|
||||
TOT = 34.000
|
||||
DIAG #1 > 12.200
|
||||
rondata back_layout_quad_twist
|
||||
DIAG #2 > 3.500
|
||||
front_tuck front_tuck
|
||||
DIAG #3 > 12.200 * 1.5 (BONUS)
|
||||
rondata back_layout_quad_twist
|
||||
|
||||
--- Test Case #5 ---
|
||||
DD = 12 DP = 30
|
||||
TOT = 34.950
|
||||
DIAG #1 > 4.450
|
||||
rondata arabian front_tuck
|
||||
DIAG #2 > 12.200
|
||||
rondata back_layout_quad_twist
|
||||
DIAG #3 > 12.200 * 1.5 (BONUS)
|
||||
rondata back_layout_quad_twist
|
||||
|
||||
--- Test Case #6 ---
|
||||
DD = 11 DP = 33
|
||||
TOT = 38.750
|
||||
DIAG #1 > 12.200
|
||||
rondata back_layout_quad_twist
|
||||
DIAG #2 > 8.250
|
||||
front_tuck triple_front_tuck
|
||||
DIAG #3 > 12.200 * 1.5 (BONUS)
|
||||
rondata back_layout_quad_twist
|
||||
316
Laboratorio 8/Esercizio 2/Graph.c
Normal file
316
Laboratorio 8/Esercizio 2/Graph.c
Normal file
@@ -0,0 +1,316 @@
|
||||
// Laboratorio 8 - Esercizio 2 - Graph.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Graph.h"
|
||||
#include "ST.h"
|
||||
|
||||
typedef struct node *link;
|
||||
struct node
|
||||
{
|
||||
int id;
|
||||
int wt;
|
||||
link next;
|
||||
};
|
||||
|
||||
struct graph
|
||||
{
|
||||
int V;
|
||||
int E;
|
||||
int **madj;
|
||||
link *ladj;
|
||||
link z;
|
||||
ST tab;
|
||||
};
|
||||
|
||||
static link newNode(int id, int wt, link next)
|
||||
{
|
||||
link t = (link)malloc(sizeof(*t));
|
||||
t->id = id;
|
||||
t->wt = wt;
|
||||
t->next = next;
|
||||
return t;
|
||||
}
|
||||
|
||||
static void freeList(link t, link z)
|
||||
{
|
||||
link q, x = t;
|
||||
if (t == z)
|
||||
return;
|
||||
|
||||
while (x != z)
|
||||
{
|
||||
q = x->next;
|
||||
free(x);
|
||||
x = q;
|
||||
}
|
||||
}
|
||||
|
||||
static int searchList(link t, link z, int id)
|
||||
{
|
||||
for (link x = t; x != z; x = x->next)
|
||||
{
|
||||
if (x->id == id)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Edge EDGEcreate(int v, int w, int wt)
|
||||
{
|
||||
Edge e;
|
||||
e.v = v;
|
||||
e.w = w;
|
||||
e.wt = wt;
|
||||
return e;
|
||||
}
|
||||
|
||||
// Questa variabile è usata dalla funzione `vertexCompare` che è chiamata da qsort
|
||||
Graph tmpG;
|
||||
|
||||
static int vertexCompare(const void *a, const void *b)
|
||||
{
|
||||
return (strcmp(STsearchByIndex(tmpG->tab, (*(Edge *)a).w).name, STsearchByIndex(tmpG->tab, (*(Edge *)b).w).name));
|
||||
}
|
||||
|
||||
static void EDGEsort(Edge *edges, int N, Graph G)
|
||||
{
|
||||
tmpG = G;
|
||||
qsort(edges, N, sizeof(Edge), vertexCompare);
|
||||
}
|
||||
|
||||
Graph GRAPHload(FILE *fin)
|
||||
{
|
||||
int lines = 0, wt;
|
||||
Graph G;
|
||||
|
||||
Item item1, item2;
|
||||
|
||||
for (char c = getc(fin); c != EOF; c = getc(fin))
|
||||
if (c == '\n') // Se leggo un newline aumento il numero delle linee
|
||||
lines = lines + 1;
|
||||
|
||||
fseek(fin, 0, SEEK_SET);
|
||||
|
||||
G = GRAPHinit(2 * lines); // Alloco sovrastimando il numero di vertici
|
||||
for (int i = 0; i < lines; i++)
|
||||
{
|
||||
item1 = ITEMread(fin);
|
||||
item2 = ITEMread(fin);
|
||||
fscanf(fin, " %d", &wt);
|
||||
|
||||
int id1 = GRAPHgetIndex(G, item1);
|
||||
int id2 = GRAPHgetIndex(G, item2);
|
||||
|
||||
GRAPHinsertE(G, id1, id2, wt);
|
||||
}
|
||||
|
||||
return G;
|
||||
}
|
||||
|
||||
void GRAPHinsertE(Graph G, int v, int w, int wt)
|
||||
{
|
||||
if (G->madj[v][w] == 0)
|
||||
G->E++;
|
||||
G->madj[v][w] = 1;
|
||||
G->madj[v][w] = wt;
|
||||
G->madj[w][v] = 1;
|
||||
G->madj[w][v] = wt;
|
||||
}
|
||||
|
||||
void GRAPHremoveE(Graph G, int v, int w)
|
||||
{
|
||||
if (G->madj[v][w] != 0)
|
||||
G->E--;
|
||||
G->madj[v][w] = 0;
|
||||
G->madj[w][v] = 0;
|
||||
}
|
||||
|
||||
static int **MATRIXinit(int r, int c, int val)
|
||||
{
|
||||
int i, j;
|
||||
int **t = malloc(r * sizeof(int *));
|
||||
for (i = 0; i < r; i++)
|
||||
t[i] = malloc(c * sizeof(int));
|
||||
for (i = 0; i < r; i++)
|
||||
for (j = 0; j < c; j++)
|
||||
t[i][j] = val;
|
||||
return t;
|
||||
}
|
||||
|
||||
static link *LISTinit(int V, link z)
|
||||
{
|
||||
link *list = (link *)malloc(V * sizeof(link));
|
||||
for (int v = 0; v < V; v++)
|
||||
list[v] = z;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
Graph GRAPHinit(int V)
|
||||
{
|
||||
Graph G = malloc(sizeof *G);
|
||||
G->V = 0;
|
||||
G->E = 0;
|
||||
G->madj = MATRIXinit(V, V, 0);
|
||||
G->z = newNode(-1, -1, NULL);
|
||||
G->ladj = LISTinit(V, G->z);
|
||||
G->tab = STinit(V);
|
||||
return G;
|
||||
}
|
||||
|
||||
void GRAPHfree(Graph G)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < G->V; i++)
|
||||
free(G->madj[i]);
|
||||
free(G->madj);
|
||||
for (i = 0; i < G->V; i++)
|
||||
{
|
||||
freeList(G->ladj[i], G->z);
|
||||
}
|
||||
free(G->ladj);
|
||||
free(G->z);
|
||||
STfree(G->tab);
|
||||
free(G);
|
||||
}
|
||||
|
||||
int GRAPHgetIndex(Graph G, Item item)
|
||||
{
|
||||
int id = STsearch(G->tab, item);
|
||||
if (id == -1)
|
||||
{
|
||||
id = STinsert(G->tab, item);
|
||||
G->V++;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void GRAPHbuildLadj(Graph G)
|
||||
{
|
||||
link t;
|
||||
|
||||
for (int i = 0; i < G->V; i++)
|
||||
{
|
||||
freeList(G->ladj[i], G->z);
|
||||
G->ladj[i] = G->z;
|
||||
}
|
||||
|
||||
for (int i = 0; i < G->V; i++)
|
||||
{
|
||||
for (int j = 0; j < G->V; j++)
|
||||
{
|
||||
if (G->madj[i][j] != 0)
|
||||
G->ladj[i] = newNode(j, G->madj[i][j], G->ladj[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < G->V; i++)
|
||||
{
|
||||
if (G->ladj[i] != G->z)
|
||||
{
|
||||
printf("%d", i);
|
||||
for (t = G->ladj[i]; t != G->z; t = t->next)
|
||||
{
|
||||
printf(" -> (%d,%d)", t->id, t->wt);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int checkAdjacencyM(Graph G, int id1, int id2, int id3)
|
||||
{
|
||||
if (!G->madj[id1][id2] || !G->madj[id1][id3])
|
||||
return 0;
|
||||
|
||||
if (!G->madj[id2][id1] || !G->madj[id2][id3])
|
||||
return 0;
|
||||
|
||||
if (!G->madj[id3][id1] || !G->madj[id3][id2])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int checkAdjacencyL(Graph G, int id1, int id2, int id3)
|
||||
{
|
||||
if (!searchList(G->ladj[id1], G->z, id2) || !searchList(G->ladj[id1], G->z, id2))
|
||||
return 0;
|
||||
|
||||
if (!searchList(G->ladj[id2], G->z, id1) || !searchList(G->ladj[id2], G->z, id3))
|
||||
return 0;
|
||||
|
||||
if (!searchList(G->ladj[id3], G->z, id1) || !searchList(G->ladj[id3], G->z, id2))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void GRAPHCheckVertexAdiacency(Graph G)
|
||||
{
|
||||
puts("Inserisci i tre vertici specificando per ogni vertice \"<nome> <subnet>\"");
|
||||
Item i1 = ITEMread(stdin);
|
||||
Item i2 = ITEMread(stdin);
|
||||
Item i3 = ITEMread(stdin);
|
||||
|
||||
int id1 = STsearch(G->tab, i1);
|
||||
int id2 = STsearch(G->tab, i2);
|
||||
int id3 = STsearch(G->tab, i3);
|
||||
|
||||
if (id1 == -1 || id2 == -1 || id3 == -1)
|
||||
{
|
||||
puts("Attenzione: vertici non validi");
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkAdjacencyM(G, id1, id2, id3))
|
||||
{
|
||||
puts("I vertici formano un sottografo completo");
|
||||
}
|
||||
else
|
||||
{
|
||||
puts("I vertici non formano un sottografo completo");
|
||||
}
|
||||
}
|
||||
|
||||
void GRAPHprintOrdered(Graph G)
|
||||
{
|
||||
Item *items = malloc(G->V * sizeof(Item));
|
||||
Edge *edges = malloc(G->V * sizeof(Edge));
|
||||
|
||||
for (int i = 0; i < G->V; i++)
|
||||
{
|
||||
items[i] = STsearchByIndex(G->tab, i);
|
||||
}
|
||||
|
||||
ITEMsort(items, G->V);
|
||||
|
||||
for (int i = 0; i < G->V; i++)
|
||||
{
|
||||
int id = GRAPHgetIndex(G, items[i]);
|
||||
printf("%s %s:\n", items[i].name, items[i].subnet);
|
||||
|
||||
// Crea lista di edges
|
||||
int N = 0;
|
||||
for (int j = 0; j < G->V; j++)
|
||||
{
|
||||
if (G->madj[id][j] != 0)
|
||||
edges[N++] = EDGEcreate(id, j, G->madj[id][j]);
|
||||
}
|
||||
|
||||
EDGEsort(edges, N, G);
|
||||
|
||||
for (int j = 0; j < N; j++)
|
||||
{
|
||||
printf(" - %s %s, peso %d\n", STsearchByIndex(G->tab, edges[j].w).name, STsearchByIndex(G->tab, edges[j].w).subnet, edges[j].wt);
|
||||
}
|
||||
}
|
||||
|
||||
free(edges);
|
||||
free(items);
|
||||
}
|
||||
26
Laboratorio 8/Esercizio 2/Graph.h
Normal file
26
Laboratorio 8/Esercizio 2/Graph.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// Laboratorio 8 - Esercizio 2 - Graph.h
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#ifndef GRAPH_DEFINED
|
||||
#define GRAPH_DEFINED
|
||||
|
||||
#include<stdio.h>
|
||||
#include"Item.h"
|
||||
#define MAXC 100
|
||||
|
||||
typedef struct edge
|
||||
{
|
||||
int v;
|
||||
int w;
|
||||
int wt;
|
||||
} Edge;
|
||||
typedef struct graph *Graph;
|
||||
Graph GRAPHinit(int V);
|
||||
void GRAPHfree(Graph G);
|
||||
Graph GRAPHload(FILE *fin);
|
||||
void GRAPHbuildLadj(Graph G);
|
||||
void GRAPHCheckVertexAdiacency(Graph G);
|
||||
void GRAPHprintOrdered(Graph G);
|
||||
int GRAPHgetIndex(Graph G, Item item);
|
||||
void GRAPHinsertE(Graph G, int v, int w, int wt);
|
||||
#endif
|
||||
37
Laboratorio 8/Esercizio 2/Item.c
Normal file
37
Laboratorio 8/Esercizio 2/Item.c
Normal file
@@ -0,0 +1,37 @@
|
||||
// Laboratorio 8 - Esercizio 2 - Item.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Item.h"
|
||||
|
||||
Item ITEMcreate(char *name, char *subnet) {
|
||||
Item t;
|
||||
strncpy(t.name, name, MAX_STR+1);
|
||||
strncpy(t.subnet, subnet, MAX_STR+1);
|
||||
return t;
|
||||
}
|
||||
|
||||
Item ITEMread(FILE * fp) {
|
||||
Item item;
|
||||
fscanf(fp, " %s %s", item.name, item.subnet);
|
||||
return item;
|
||||
}
|
||||
|
||||
Item ITEMnull() {
|
||||
Item t;
|
||||
strcpy(t.name, "");
|
||||
strcpy(t.subnet, "");
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static int compareItem(const void *a, const void *b) {
|
||||
return strcmp((*(Item*)a).name, (*(Item*)b).name);
|
||||
}
|
||||
|
||||
void ITEMsort(Item *v, int N) {
|
||||
qsort(v, N, sizeof(Item), compareItem);
|
||||
}
|
||||
23
Laboratorio 8/Esercizio 2/Item.h
Normal file
23
Laboratorio 8/Esercizio 2/Item.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// Laboratorio 8 - Esercizio 2 - Item.h
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#ifndef ITEM_DEFINED
|
||||
#define ITEM_DEFINED
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_STR 30
|
||||
|
||||
typedef struct item {
|
||||
char name[MAX_STR+1];
|
||||
char subnet[MAX_STR+1];
|
||||
} Item;
|
||||
|
||||
Item ITEMcreate(char *name, char *subnet);
|
||||
Item ITEMread(FILE * fp);
|
||||
|
||||
Item ITEMnull();
|
||||
|
||||
void ITEMsort(Item *v, int N);
|
||||
|
||||
#endif
|
||||
61
Laboratorio 8/Esercizio 2/ST.c
Normal file
61
Laboratorio 8/Esercizio 2/ST.c
Normal file
@@ -0,0 +1,61 @@
|
||||
// Laboratorio 8 - Esercizio 2 - ST.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ST.h"
|
||||
#include "Item.h"
|
||||
|
||||
struct st {
|
||||
Item *v;
|
||||
int N;
|
||||
int maxN;
|
||||
};
|
||||
|
||||
ST STinit(int N) {
|
||||
ST st = (ST) malloc(sizeof(*st));
|
||||
|
||||
st->v = (Item *) malloc(N * sizeof(Item));
|
||||
st->N = 0;
|
||||
st->maxN = N;
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
void STfree(ST st) {
|
||||
free(st->v);
|
||||
free(st);
|
||||
}
|
||||
|
||||
int STinsert(ST st, Item item) {
|
||||
if (st->N == st->maxN) {
|
||||
printf("Errore, spazio esaurito nella ST\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
st->v[st->N] = item;
|
||||
st->N++;
|
||||
return st->N -1;
|
||||
}
|
||||
|
||||
Item STsearchByIndex(ST st, int index) {
|
||||
if (index >= st->N)
|
||||
return ITEMnull();
|
||||
|
||||
return st->v[index];
|
||||
}
|
||||
|
||||
int STsearch(ST st, Item item) {
|
||||
int i;
|
||||
for (i = 0; i < st->N; i++) {
|
||||
if (strcmp(item.name, st->v[i].name) == 0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int STcount(ST st) {
|
||||
return st->N;
|
||||
}
|
||||
21
Laboratorio 8/Esercizio 2/ST.h
Normal file
21
Laboratorio 8/Esercizio 2/ST.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// Laboratorio 8 - Esercizio 2 - ST.h
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#ifndef ST_DEFINED
|
||||
#define ST_DEFINED
|
||||
|
||||
#include "Item.h"
|
||||
|
||||
typedef struct st *ST;
|
||||
|
||||
ST STinit(int N);
|
||||
void STfree(ST st);
|
||||
|
||||
int STinsert(ST st, Item item);
|
||||
|
||||
Item STsearchByIndex(ST st, int index);
|
||||
int STsearch(ST st, Item item);
|
||||
|
||||
int STcount(ST st);
|
||||
|
||||
#endif
|
||||
21
Laboratorio 8/Esercizio 2/grafo.txt
Normal file
21
Laboratorio 8/Esercizio 2/grafo.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
Uriel Net3 Bahamut Net2 99
|
||||
Uriel Net3 Igni Net0 45
|
||||
Igni Net0 Tatooine Net1 67
|
||||
Tatooine Net1 Bahamut Net2 33
|
||||
Axii Net0 Igni Net0 42
|
||||
Quen Net0 Igni Net0 18
|
||||
Shiva Net2 Tatooine Net1 12
|
||||
Ifrit Net2 Tatooine Net1 2
|
||||
Ramuh Net2 Tatooine Net1 111
|
||||
Shiva Net2 Ifrit Net2 46
|
||||
Quen Net0 Coruscan Net1 45
|
||||
Shiva Net2 Alderaan Net1 98
|
||||
Ifrit Net2 Alderaan Net1 13
|
||||
Ramuh Net2 Alderaan Net1 9
|
||||
Ramuh Net2 Azrael Net3 23
|
||||
Axii Net0 Cassiel Net3 13
|
||||
Shiva Net2 Cassiel Net3 1
|
||||
Shiva Net2 Yrden Net0 17
|
||||
Alderaan Net1 Yrden Net0 20
|
||||
Cassiel Net3 Yrden Net0 20
|
||||
Cassiel Net3 Azrael Net3 9
|
||||
92
Laboratorio 8/Esercizio 2/main.c
Normal file
92
Laboratorio 8/Esercizio 2/main.c
Normal file
@@ -0,0 +1,92 @@
|
||||
// Laboratorio 8 - Esercizio 2 - main.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include<ctype.h>
|
||||
#include<string.h>
|
||||
|
||||
#include"Graph.h"
|
||||
|
||||
#define MAX_LEN 30
|
||||
|
||||
const int MAXL = 100;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
r_print,
|
||||
r_adj,
|
||||
r_build,
|
||||
r_fine
|
||||
} t_comandi;
|
||||
|
||||
char *toLower(char *s)
|
||||
{
|
||||
for (char *p = s; *p; p++)
|
||||
*p = tolower(*p);
|
||||
return s;
|
||||
}
|
||||
|
||||
t_comandi leggiComando()
|
||||
{
|
||||
t_comandi c;
|
||||
char cmd[MAXL];
|
||||
char tabella[4][20] = {
|
||||
"stampa", "adiacenza", "converti", "fine"};
|
||||
printf("comando (stampa/adiacenza/converti/fine): ");
|
||||
scanf("%s", cmd);
|
||||
toLower(cmd);
|
||||
c = r_print;
|
||||
while (c < 4 && strcmp(cmd, tabella[c]) != 0)
|
||||
c++;
|
||||
return (c);
|
||||
}
|
||||
|
||||
void menuParola(Graph G)
|
||||
{
|
||||
t_comandi comando;
|
||||
int i, continua = 1;
|
||||
while (continua)
|
||||
{
|
||||
comando = leggiComando();
|
||||
switch (comando)
|
||||
{
|
||||
case r_print:
|
||||
GRAPHprintOrdered(G);
|
||||
break;
|
||||
case r_adj:
|
||||
GRAPHCheckVertexAdiacency(G);
|
||||
break;
|
||||
case r_build:
|
||||
GRAPHbuildLadj(G);
|
||||
break;
|
||||
case r_fine:
|
||||
continua = 0;
|
||||
break;
|
||||
default:
|
||||
puts("Comando non valido\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
FILE * fp_read;
|
||||
Graph G;
|
||||
if (argc < 1) {
|
||||
puts("Specifica il file tra gli argomenti");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((fp_read = fopen(argv[1], "r")) == NULL)
|
||||
{
|
||||
puts("Impossibile aprire il file");
|
||||
return 1;
|
||||
}
|
||||
G = GRAPHload(fp_read);
|
||||
fclose(fp_read);
|
||||
|
||||
menuParola(G);
|
||||
|
||||
GRAPHfree(G);
|
||||
|
||||
return 0;
|
||||
}
|
||||
53
Laboratorio 8/Esercizio 3/Asset.c
Normal file
53
Laboratorio 8/Esercizio 3/Asset.c
Normal file
@@ -0,0 +1,53 @@
|
||||
// Laboratorio 8 - Esercizio 3 - Asset.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "Asset.h"
|
||||
#include "ExrateBST.h"
|
||||
|
||||
struct asset
|
||||
{
|
||||
char titolo[STR_LEN];
|
||||
ExrateBST exrates;
|
||||
};
|
||||
|
||||
Asset AssetCreate() {
|
||||
Asset a = malloc(sizeof(*a));
|
||||
a->exrates = ExrateBSTCreate();
|
||||
return a;
|
||||
}
|
||||
|
||||
void AssetFree(Asset a) {
|
||||
ExrateBSTFree(a->exrates);
|
||||
free(a);
|
||||
}
|
||||
|
||||
int AssetCompare(Asset a, Asset b) {
|
||||
return strcmp(a->titolo, b->titolo);
|
||||
}
|
||||
|
||||
char * AssetTitle(Asset a) {
|
||||
return a->titolo;
|
||||
}
|
||||
|
||||
ExrateBST AssetGetExrates(Asset a) {
|
||||
return a->exrates;
|
||||
}
|
||||
|
||||
Asset AssetRead(FILE *fp) {
|
||||
Asset n = AssetCreate();
|
||||
Exrate je;
|
||||
int Nitems;
|
||||
|
||||
fscanf(fp, " %s %d",n->titolo, &Nitems);
|
||||
for (int i = 0; i < Nitems; i++) {
|
||||
ExrateRead(&je, fp);
|
||||
ExrateBSTInsert(n->exrates, je);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void AssetPrint(Asset a) {
|
||||
printf(" - %s\n", a->titolo);
|
||||
}
|
||||
16
Laboratorio 8/Esercizio 3/Asset.h
Normal file
16
Laboratorio 8/Esercizio 3/Asset.h
Normal file
@@ -0,0 +1,16 @@
|
||||
// Laboratorio 8 - Esercizio 3 - Asset.h
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#ifndef ASSET_DEFINED
|
||||
#define ASSET_DEFINED
|
||||
#define STR_LEN 20
|
||||
#include "ExrateBST.h"
|
||||
|
||||
typedef struct asset *Asset;
|
||||
void AssetFree(Asset a);
|
||||
int AssetCompare(Asset a, Asset b);
|
||||
ExrateBST AssetGetExrates(Asset a);
|
||||
Asset AssetRead(FILE *fp);
|
||||
void AssetPrint(Asset a);
|
||||
char * AssetTitle(Asset a);
|
||||
#endif
|
||||
113
Laboratorio 8/Esercizio 3/AssetList.c
Normal file
113
Laboratorio 8/Esercizio 3/AssetList.c
Normal file
@@ -0,0 +1,113 @@
|
||||
// Laboratorio 8 - Esercizio 3 - AssetList.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "Asset.h"
|
||||
#include "AssetList.h"
|
||||
#include "ExrateBST.h"
|
||||
|
||||
typedef struct node *link;
|
||||
struct node
|
||||
{
|
||||
Asset asset;
|
||||
link next;
|
||||
};
|
||||
|
||||
struct assetList
|
||||
{
|
||||
link head;
|
||||
int N;
|
||||
};
|
||||
|
||||
static link createNode(Asset asset, link next)
|
||||
{
|
||||
link new = malloc(sizeof(*new));
|
||||
new->asset = asset;
|
||||
new->next = next;
|
||||
return new;
|
||||
}
|
||||
|
||||
AssetList AssetListCreate()
|
||||
{
|
||||
AssetList al = malloc(sizeof(*al));
|
||||
|
||||
al->head = NULL;
|
||||
al->N = 0;
|
||||
|
||||
return al;
|
||||
}
|
||||
|
||||
void AssetListFree(AssetList al)
|
||||
{
|
||||
for (link x = al->head, p = x->next; p != NULL; x = p, p = x->next)
|
||||
{
|
||||
free(x);
|
||||
}
|
||||
free(al);
|
||||
}
|
||||
|
||||
int AssetListLength(AssetList al) {
|
||||
return al->N;
|
||||
}
|
||||
|
||||
void AssetListPrint(AssetList al) {
|
||||
link h = al->head;
|
||||
while (h != NULL) {
|
||||
AssetPrint(h->asset);
|
||||
h = h->next;
|
||||
}
|
||||
}
|
||||
|
||||
Asset * AssetListGet(AssetList al, int index) {
|
||||
link h;
|
||||
int i = 0;
|
||||
|
||||
h = al->head;
|
||||
while (h != NULL) {
|
||||
if (i == index)
|
||||
return &(h->asset);
|
||||
h = h->next;
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Asset * AssetListSearch(AssetList al, char * query) {
|
||||
link h;
|
||||
|
||||
h = al->head;
|
||||
while (h != NULL) {
|
||||
if (strcmp(AssetTitle(h->asset), query) == 0)
|
||||
return &(h->asset);
|
||||
h = h->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AssetListInsert(AssetList al, Asset asset)
|
||||
{
|
||||
link x, p;
|
||||
if (al->head == NULL)
|
||||
{
|
||||
al->head = createNode(asset, al->head);
|
||||
al->N++;
|
||||
return;
|
||||
}
|
||||
|
||||
for (x = al->head, p = x->next; p != NULL; x = p, p = x->next)
|
||||
{
|
||||
if (AssetCompare(asset, x->asset) == 0)
|
||||
{
|
||||
ExrateBSTMerge(AssetGetExrates(x->asset), AssetGetExrates(asset));
|
||||
return;
|
||||
}
|
||||
else if (AssetCompare(asset, x->asset) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
x->next = createNode(asset, p);
|
||||
al->N++;
|
||||
}
|
||||
18
Laboratorio 8/Esercizio 3/AssetList.h
Normal file
18
Laboratorio 8/Esercizio 3/AssetList.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// Laboratorio 8 - Esercizio 3 - AssetList.h
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#ifndef ASSETLIST_DEFINED
|
||||
#define ASSETLIST_DEFINED
|
||||
#include "Asset.h"
|
||||
|
||||
typedef struct assetList *AssetList;
|
||||
|
||||
AssetList AssetListCreate();
|
||||
void AssetListFree(AssetList al);
|
||||
void AssetListInsert(AssetList al, Asset asset);
|
||||
Asset * AssetListGet(AssetList al, int index);
|
||||
Asset * AssetListSearch(AssetList al, char * query);
|
||||
void AssetListPrint(AssetList al);
|
||||
int AssetListLength(AssetList al);
|
||||
|
||||
#endif
|
||||
36
Laboratorio 8/Esercizio 3/Datetime.c
Normal file
36
Laboratorio 8/Esercizio 3/Datetime.c
Normal file
@@ -0,0 +1,36 @@
|
||||
// Laboratorio 8 - Esercizio 3 - Datetime.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Datetime.h"
|
||||
|
||||
int DateTimeCompare(DateTime a, DateTime b) {
|
||||
if (a.year > b.year)
|
||||
return 1;
|
||||
else if (a.year < b.year)
|
||||
return -1;
|
||||
|
||||
if (a.month > b.month)
|
||||
return 1;
|
||||
else if (a.month < b.month)
|
||||
return -1;
|
||||
|
||||
if (a.day > b.day)
|
||||
return 1;
|
||||
else if (a.day < b.day)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DateTimeRead(DateTime * dt, FILE * fp) {
|
||||
return fscanf(fp, " %d/%d/%d %d:%d", &dt->year, &dt->month,&dt->day,&dt->hours,&dt->minutes) == 5;
|
||||
}
|
||||
|
||||
int DateRead(DateTime * dt, FILE * fp) {
|
||||
dt->hours = 0;
|
||||
dt->minutes = 0;
|
||||
return fscanf(fp, " %d/%d/%d", &dt->year, &dt->month,&dt->day) == 3;
|
||||
}
|
||||
19
Laboratorio 8/Esercizio 3/Datetime.h
Normal file
19
Laboratorio 8/Esercizio 3/Datetime.h
Normal file
@@ -0,0 +1,19 @@
|
||||
// Laboratorio 8 - Esercizio 3 - Datetime.h
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#ifndef DATETIME_DEFINED
|
||||
#define DATETIME_DEFINED
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct datetime {
|
||||
int day;
|
||||
int month;
|
||||
int year;
|
||||
int hours;
|
||||
int minutes;
|
||||
} DateTime;
|
||||
|
||||
int DateTimeCompare(DateTime a, DateTime b);
|
||||
int DateTimeRead(DateTime * dt, FILE * fp);
|
||||
int DateRead(DateTime * dt, FILE * fp);
|
||||
#endif
|
||||
36
Laboratorio 8/Esercizio 3/Exrate.c
Normal file
36
Laboratorio 8/Esercizio 3/Exrate.c
Normal file
@@ -0,0 +1,36 @@
|
||||
// Laboratorio 8 - Esercizio 3 - Exrate.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include <stdio.h>
|
||||
#include "Exrate.h"
|
||||
#include "Datetime.h"
|
||||
|
||||
int ExrateRead(Exrate *e, FILE *fp)
|
||||
{
|
||||
if (!DateTimeRead(&e->datetime, fp))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return fscanf(fp, " %d %d", &e->q, &e->n) == 1;
|
||||
}
|
||||
|
||||
void ExratePrint(Exrate e)
|
||||
{
|
||||
if (e.n == -1)
|
||||
{
|
||||
puts("Quotazione non valida");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Quotazione: %d, numero di transazioni: %d\n", e.q, e.n);
|
||||
}
|
||||
}
|
||||
|
||||
Exrate ExrateEmpty()
|
||||
{
|
||||
Exrate e;
|
||||
e.n = -1;
|
||||
e.q = -1;
|
||||
return e;
|
||||
}
|
||||
16
Laboratorio 8/Esercizio 3/Exrate.h
Normal file
16
Laboratorio 8/Esercizio 3/Exrate.h
Normal file
@@ -0,0 +1,16 @@
|
||||
// Laboratorio 8 - Esercizio 3 - Exrate.h
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#ifndef EXRATE_DEFINED
|
||||
#define EXRATE_DEFINED
|
||||
#include "Datetime.h"
|
||||
|
||||
typedef struct exrate {
|
||||
DateTime datetime;
|
||||
int q, n;
|
||||
} Exrate;
|
||||
|
||||
int ExrateRead(Exrate *e, FILE *fp);
|
||||
void ExratePrint(Exrate e);
|
||||
Exrate ExrateEmpty();
|
||||
#endif
|
||||
266
Laboratorio 8/Esercizio 3/ExrateBST.c
Normal file
266
Laboratorio 8/Esercizio 3/ExrateBST.c
Normal file
@@ -0,0 +1,266 @@
|
||||
// Laboratorio 8 - Esercizio 3 - ExrateBST.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "ExrateBST.h"
|
||||
|
||||
typedef struct node *link;
|
||||
struct node
|
||||
{
|
||||
Exrate exrate;
|
||||
int N;
|
||||
link left, right;
|
||||
};
|
||||
|
||||
struct exrateBST
|
||||
{
|
||||
link root;
|
||||
link z;
|
||||
int N;
|
||||
};
|
||||
|
||||
static link createNode(Exrate exrate, link l, link r, int N)
|
||||
{
|
||||
link new = malloc(sizeof(*new));
|
||||
new->exrate = exrate;
|
||||
new->left = l;
|
||||
new->right = r;
|
||||
new->N = N;
|
||||
return new;
|
||||
}
|
||||
|
||||
static link rotR(link n)
|
||||
{
|
||||
link t = n->left;
|
||||
n->left = t->right;
|
||||
t->right = n;
|
||||
t->N = n->N;
|
||||
n->N = 1;
|
||||
n->N += (n->left) ? n->left->N : 0;
|
||||
n->N += (n->right) ? n->right->N : 0;
|
||||
return t;
|
||||
}
|
||||
|
||||
static link rotL(link h)
|
||||
{
|
||||
link t = h->right;
|
||||
h->right = t->left;
|
||||
t->left = h;
|
||||
t->N = h->N;
|
||||
h->N = 1;
|
||||
h->N += (h->left) ? h->left->N : 0;
|
||||
h->N += (h->right) ? h->right->N : 0;
|
||||
return t;
|
||||
}
|
||||
|
||||
ExrateBST ExrateBSTCreate()
|
||||
{
|
||||
ExrateBST new = malloc(sizeof(*new));
|
||||
new->z = createNode(ExrateEmpty(), NULL, NULL, 0);
|
||||
new->root = new->z;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
static void freeBST(link n, link z)
|
||||
{
|
||||
if (n == z)
|
||||
return;
|
||||
|
||||
free(n->left);
|
||||
free(n->right);
|
||||
free(n);
|
||||
}
|
||||
|
||||
void ExrateBSTFree(ExrateBST ebst)
|
||||
{
|
||||
freeBST(ebst->root, ebst->z);
|
||||
free(ebst->z);
|
||||
free(ebst);
|
||||
}
|
||||
|
||||
static link search(link n, DateTime dt, link z)
|
||||
{
|
||||
if (n == z)
|
||||
return z;
|
||||
|
||||
int c = DateTimeCompare(dt, n->exrate.datetime);
|
||||
if (c == 0)
|
||||
return n;
|
||||
if (c > 0)
|
||||
return search(n->right, dt, z);
|
||||
else
|
||||
return search(n->left, dt, z);
|
||||
}
|
||||
|
||||
Exrate ExrateBSTSearch(ExrateBST ebst, DateTime dt)
|
||||
{
|
||||
// nota: se search restituisce z, allora z,exrate è l'exrate nullo
|
||||
return search(ebst->root, dt, ebst->z)->exrate;
|
||||
}
|
||||
|
||||
static void ExrateBSTInsertLeaf(ExrateBST ebst, Exrate exrate)
|
||||
{
|
||||
if (ebst->root == ebst->z)
|
||||
{
|
||||
ebst->root = createNode(exrate, ebst->z, ebst->z, 1);
|
||||
ebst->N++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
link *n = &ebst->root;
|
||||
while (*n != ebst->z)
|
||||
{
|
||||
(*n)->N++;
|
||||
if (DateTimeCompare(exrate.datetime, (*n)->exrate.datetime) > 0)
|
||||
{
|
||||
|
||||
n = &(*n)->right;
|
||||
}
|
||||
else
|
||||
{
|
||||
n = &(*n)->left;
|
||||
}
|
||||
}
|
||||
*n = createNode(exrate, ebst->z, ebst->z, 1);
|
||||
ebst->N++;
|
||||
}
|
||||
|
||||
void ExrateBSTInsert(ExrateBST ebst, Exrate exrate)
|
||||
{
|
||||
link node = search(ebst->root, exrate.datetime, ebst->z);
|
||||
|
||||
if (node != ebst->z)
|
||||
{
|
||||
// Merge exrate
|
||||
node->exrate.q = ((node->exrate.n * node->exrate.q) + (exrate.n * exrate.q)) / (node->exrate.n + exrate.n);
|
||||
node->exrate.n += exrate.n;
|
||||
}
|
||||
else
|
||||
{
|
||||
ExrateBSTInsertLeaf(ebst, exrate);
|
||||
}
|
||||
}
|
||||
|
||||
static void mergeR(ExrateBST dst, link r, link z)
|
||||
{
|
||||
if (r == z)
|
||||
return;
|
||||
|
||||
mergeR(dst, r->left, z);
|
||||
mergeR(dst, r->right, z);
|
||||
ExrateBSTInsert(dst, r->exrate);
|
||||
}
|
||||
|
||||
void ExrateBSTMerge(ExrateBST dst, ExrateBST src)
|
||||
{
|
||||
mergeR(dst, src->root, src->z);
|
||||
}
|
||||
|
||||
static void getMaxMinLengthR(link n, link z, int *min, int *max, int *counter)
|
||||
{
|
||||
if (n == z)
|
||||
{
|
||||
if (*counter < *min)
|
||||
*min = *counter;
|
||||
if (*counter > *max)
|
||||
*max = *counter;
|
||||
return;
|
||||
}
|
||||
|
||||
(*counter)++;
|
||||
getMaxMinLengthR(n->left, z, min, max, counter);
|
||||
getMaxMinLengthR(n->right, z, min, max, counter);
|
||||
(*counter)--;
|
||||
}
|
||||
|
||||
static int getMaxMinDiff(ExrateBST ebst)
|
||||
{
|
||||
int counter = 0, min = ebst->N, max = 0;
|
||||
getMaxMinLengthR(ebst->root, ebst->z, &min, &max, &counter);
|
||||
|
||||
return max - min;
|
||||
}
|
||||
|
||||
link partR(link h, int r)
|
||||
{
|
||||
int t = h->left->N;
|
||||
if (t > r)
|
||||
{
|
||||
h->left = partR(h->left, r);
|
||||
h = rotR(h);
|
||||
}
|
||||
if (t < r)
|
||||
{
|
||||
h->right = partR(h->right, r - t - 1);
|
||||
h = rotL(h);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
static link balanceR(link h, link z)
|
||||
{
|
||||
int r;
|
||||
if (h == z)
|
||||
return z;
|
||||
r = (h->N + 1) / 2 - 1;
|
||||
h = partR(h, r);
|
||||
h->left = balanceR(h->left, z);
|
||||
h->right = balanceR(h->right, z);
|
||||
return h;
|
||||
}
|
||||
|
||||
void visitInOrderCheckInterval(link h, link z, DateTime dt1, DateTime dt2, int interval, Exrate *min, Exrate *max) {
|
||||
if (h == z)
|
||||
return;
|
||||
|
||||
visitInOrderCheckInterval(h->left,z,dt1,dt2,interval,min,max);
|
||||
|
||||
if (!interval || (DateTimeCompare(h->exrate.datetime, dt1) >= 0 && DateTimeCompare(h->exrate.datetime, dt2) <= 0)) {
|
||||
if (h->exrate.q > max->q)
|
||||
*max = h->exrate;
|
||||
if (h->exrate.q < max->q)
|
||||
*min = h->exrate;
|
||||
}
|
||||
|
||||
visitInOrderCheckInterval(h->right,z,dt1,dt2,interval,min,max);
|
||||
}
|
||||
|
||||
void ExrateBSTBalance(ExrateBST bst)
|
||||
{
|
||||
// calcola la differenza (distanza root -> nodo massima) - (distanza root -> nodo minima)
|
||||
int diff = getMaxMinDiff(bst);
|
||||
|
||||
if (diff >= S)
|
||||
{
|
||||
printf("La differenza tra il cammino più corto e quello più lungo è di %d, bilancio l'albero...\n", diff);
|
||||
bst->root = balanceR(bst->root, bst->z);
|
||||
|
||||
diff = getMaxMinDiff(bst);
|
||||
printf("Bilanciato, ora la differenza è di: %d\n", diff);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("La differenza tra il cammino più corto e quello più lungo è di %d, non è necessario bilanciare l'albero\n", diff);
|
||||
}
|
||||
}
|
||||
|
||||
void ExrateBSTMinMaxW(ExrateBST bst, DateTime dt1, DateTime dt2, int interval) {
|
||||
Exrate min, max;
|
||||
min = max = bst->root->exrate;
|
||||
visitInOrderCheckInterval(bst->root, bst->z, dt1, dt2, interval, &min, &max);
|
||||
printf("Quotazione minima: ");
|
||||
ExratePrint(min);
|
||||
printf("Quotazione massima: ");
|
||||
ExratePrint(max);
|
||||
}
|
||||
|
||||
void ExrateBSTMinMax(ExrateBST bst) {
|
||||
DateTime empty;
|
||||
ExrateBSTMinMaxW(bst, empty, empty, 0);
|
||||
}
|
||||
|
||||
void ExrateBSTMinMaxInInterval(ExrateBST bst, DateTime dt1, DateTime dt2) {
|
||||
ExrateBSTMinMaxW(bst, dt1, dt2, 1);
|
||||
}
|
||||
23
Laboratorio 8/Esercizio 3/ExrateBST.h
Normal file
23
Laboratorio 8/Esercizio 3/ExrateBST.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// Laboratorio 8 - Esercizio 3 - ExrateBST.h
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#ifndef EXRATEBST_DEFINED
|
||||
#define EXRATEBST_DEFINED
|
||||
|
||||
#include "Exrate.h"
|
||||
#include "Datetime.h"
|
||||
|
||||
#define S 5
|
||||
|
||||
typedef struct exrateBST *ExrateBST;
|
||||
ExrateBST ExrateBSTCreate();
|
||||
void ExrateBSTFree(ExrateBST ebst);
|
||||
void ExrateBSTInsert(ExrateBST ebst, Exrate exrate);
|
||||
void ExrateBSTMerge(ExrateBST dst, ExrateBST src);
|
||||
|
||||
Exrate ExrateBSTSearch(ExrateBST ebst, DateTime dt);
|
||||
void ExrateBSTBalance(ExrateBST bst);
|
||||
void ExrateBSTMinMaxInInterval(ExrateBST bst, DateTime dt1, DateTime dt2);
|
||||
void ExrateBSTMinMax(ExrateBST bst);
|
||||
|
||||
#endif
|
||||
11
Laboratorio 8/Esercizio 3/F1.txt
Normal file
11
Laboratorio 8/Esercizio 3/F1.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
3
|
||||
ABC001 4
|
||||
2018/01/01 00:00 100 3
|
||||
2018/01/01 00:01 78 1
|
||||
2018/01/01 00:02 345 9
|
||||
2018/01/01 00:03 13 1
|
||||
ABC002 2
|
||||
2018/01/01 00:00 244 23
|
||||
2018/01/01 00:01 190 56
|
||||
ABC003 1
|
||||
2018/01/02 00:00 1 1
|
||||
11
Laboratorio 8/Esercizio 3/F2.txt
Normal file
11
Laboratorio 8/Esercizio 3/F2.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
3
|
||||
ABC006 4
|
||||
2018/01/03 00:00 100 3
|
||||
2018/01/03 00:01 78 1
|
||||
2018/01/03 00:02 345 9
|
||||
2018/01/03 00:03 13 1
|
||||
ABC003 2
|
||||
2018/01/03 00:00 244 23
|
||||
2018/01/03 00:01 190 56
|
||||
ABC011 1
|
||||
2018/01/06 00:00 1 1
|
||||
17
Laboratorio 8/Esercizio 3/F3.txt
Normal file
17
Laboratorio 8/Esercizio 3/F3.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
4
|
||||
ABC005 4
|
||||
2018/01/07 00:00 100 3
|
||||
2018/01/07 00:01 78 1
|
||||
2018/01/07 00:02 345 9
|
||||
2018/01/07 00:03 13 1
|
||||
ABC002 2
|
||||
2018/01/12 00:00 244 23
|
||||
2018/01/11 00:01 190 56
|
||||
ABC003 1
|
||||
2018/01/20 00:00 1 1
|
||||
ABC001 5
|
||||
2018/01/20 00:00 3 3
|
||||
2018/01/21 00:00 3 3
|
||||
2018/01/22 00:00 3 3
|
||||
2018/01/23 00:00 3 3
|
||||
2018/01/24 00:00 3 3
|
||||
180
Laboratorio 8/Esercizio 3/main.c
Normal file
180
Laboratorio 8/Esercizio 3/main.c
Normal file
@@ -0,0 +1,180 @@
|
||||
// Laboratorio 8 - Esercizio 3 - main.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include<ctype.h>
|
||||
#include<string.h>
|
||||
|
||||
#include"AssetList.h"
|
||||
#include"Asset.h"
|
||||
#include"ExrateBST.h"
|
||||
|
||||
#define MAX_LEN 30
|
||||
|
||||
const int MAXL = 100;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
r_read,
|
||||
r_select_asset,
|
||||
r_get_quot_date,
|
||||
r_get_quot_min_max_date,
|
||||
r_get_min_max,
|
||||
r_balance,
|
||||
r_fine
|
||||
} t_comandi;
|
||||
|
||||
char *toLower(char *s)
|
||||
{
|
||||
for (char *p = s; *p; p++)
|
||||
*p = tolower(*p);
|
||||
return s;
|
||||
}
|
||||
|
||||
t_comandi leggiComando()
|
||||
{
|
||||
t_comandi c;
|
||||
char cmd[MAXL];
|
||||
char tabella[7][30] = {
|
||||
"leggi_file", "seleziona_asset", "quotazione_data", "quotazione_min_max_data", "quotazione_min_max","bilancia", "fine"};
|
||||
printf("comando (leggi_file, seleziona_asset, quotazione_data, quotazione_min_max_data, quotazione_min_max, bilancia, fine): ");
|
||||
scanf("%s", cmd);
|
||||
toLower(cmd);
|
||||
c = r_read;
|
||||
while (c < 7 && strcmp(cmd, tabella[c]) != 0)
|
||||
c++;
|
||||
return (c);
|
||||
}
|
||||
|
||||
void handleRead(AssetList assetList) {
|
||||
FILE *fp;
|
||||
char filename[MAX_LEN+1];
|
||||
int N;
|
||||
|
||||
printf("Filename: ");
|
||||
scanf("%s", filename);
|
||||
|
||||
if ((fp = fopen(filename, "r")) == NULL) {
|
||||
printf("ERROR opening input file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fscanf(fp, "%d", &N);
|
||||
for (int i = 0; i < N; i++) {
|
||||
Asset newAsset = AssetRead(fp);
|
||||
AssetListInsert(assetList, newAsset);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void handleAssetSelection(AssetList assetList, Asset **selectedAsset) {
|
||||
char title[MAX_LEN+1];
|
||||
|
||||
if (AssetListLength(assetList) == 0)
|
||||
printf("Nessun asset selezionato\n");
|
||||
else {
|
||||
AssetListPrint(assetList);
|
||||
printf("Quale asset vuoi scegliere: ");
|
||||
scanf("%s", title);
|
||||
|
||||
if ((*selectedAsset = AssetListSearch(assetList, title)) == NULL) {
|
||||
printf("Nessun asset trovato\n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void handleSingleExrateSearch(AssetList assetList, Asset *selectedAsset) {
|
||||
Exrate dailyexrate;
|
||||
|
||||
if (selectedAsset == NULL)
|
||||
printf("Nessun asset selezionato\n");
|
||||
else {
|
||||
DateTime dt;
|
||||
printf("Data (yyyy/mm/dd): ");
|
||||
DateRead(&dt, stdin);
|
||||
dailyexrate = ExrateBSTSearch(AssetGetExrates(*selectedAsset), dt);
|
||||
ExratePrint(dailyexrate);
|
||||
}
|
||||
}
|
||||
|
||||
void handleMultiExrateSearch(AssetList assetList, Asset *selectedAsset) {
|
||||
if (selectedAsset == NULL)
|
||||
printf("Nessun asset selezionato\n");
|
||||
else {
|
||||
ExrateBSTMinMax(AssetGetExrates(*selectedAsset));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void handleMultiExrateSearchInterval(AssetList assetList, Asset *selectedAsset) {
|
||||
if (selectedAsset == NULL)
|
||||
printf("Nessun asset selezionato\n");
|
||||
else {
|
||||
DateTime dt1;
|
||||
DateTime dt2;
|
||||
printf("Data inizio (yyyy/mm/dd): ");
|
||||
DateRead(&dt1, stdin);
|
||||
printf("Data fine (yyyy/mm/dd): ");
|
||||
DateRead(&dt2, stdin);
|
||||
|
||||
ExrateBSTMinMaxInInterval(AssetGetExrates(*selectedAsset), dt1, dt2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void handleBalance(Asset *asset) {
|
||||
if (asset == NULL)
|
||||
printf("Nessun asset selezionato\n");
|
||||
else
|
||||
ExrateBSTBalance(AssetGetExrates(*asset));
|
||||
}
|
||||
|
||||
void menuParola(AssetList al)
|
||||
{
|
||||
Asset *selected = NULL;
|
||||
t_comandi comando;
|
||||
int i, continua = 1;
|
||||
while (continua)
|
||||
{
|
||||
comando = leggiComando();
|
||||
switch (comando)
|
||||
{
|
||||
case r_read:
|
||||
handleRead(al);
|
||||
break;
|
||||
case r_select_asset:
|
||||
handleAssetSelection(al, &selected);
|
||||
break;
|
||||
case r_get_quot_date:
|
||||
handleSingleExrateSearch(al, selected);
|
||||
break;
|
||||
case r_get_quot_min_max_date:
|
||||
handleMultiExrateSearchInterval(al, selected);
|
||||
break;
|
||||
case r_get_min_max:
|
||||
handleMultiExrateSearch(al, selected);
|
||||
break;
|
||||
case r_balance:
|
||||
handleBalance(selected);
|
||||
break;
|
||||
case r_fine:
|
||||
continua = 0;
|
||||
break;
|
||||
default:
|
||||
puts("Comando non valido\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
char filename[MAX_LEN];
|
||||
AssetList al = AssetListCreate();
|
||||
|
||||
menuParola(al);
|
||||
|
||||
AssetListFree(al);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user