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
|
||||
Reference in New Issue
Block a user