150 lines
3.5 KiB
C
150 lines
3.5 KiB
C
#include <stdio.h>
|
|
#include "percettrone.h"
|
|
#include "grafico.h"
|
|
|
|
int MAX_EPOCHE = 10000;
|
|
/*
|
|
il tipo indica quali punti vogliamo disegnare nel grafico:
|
|
0: AND
|
|
1: OR
|
|
2: XOR
|
|
3: NAND
|
|
4: NOR
|
|
5: XNOR
|
|
*/
|
|
int tipo = 0;
|
|
|
|
void stampa_risultati(Percettrone);
|
|
void sleep_ms(int);
|
|
|
|
void main()
|
|
{
|
|
srand(time(NULL));
|
|
|
|
allegro_init();
|
|
install_keyboard();
|
|
set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0);
|
|
cls(tipo, 0);
|
|
|
|
int output[4];
|
|
switch (tipo)
|
|
{
|
|
case 0:
|
|
output[0] = 0;
|
|
output[1] = 0;
|
|
output[2] = 0;
|
|
output[3] = 1;
|
|
break;
|
|
case 1:
|
|
output[0] = 0;
|
|
output[1] = 1;
|
|
output[2] = 1;
|
|
output[3] = 1;
|
|
break;
|
|
case 2:
|
|
output[0] = 0;
|
|
output[1] = 1;
|
|
output[2] = 1;
|
|
output[3] = 0;
|
|
break;
|
|
case 3:
|
|
output[0] = 1;
|
|
output[1] = 1;
|
|
output[2] = 1;
|
|
output[3] = 0;
|
|
break;
|
|
case 4:
|
|
output[0] = 1;
|
|
output[1] = 0;
|
|
output[2] = 0;
|
|
output[3] = 0;
|
|
break;
|
|
case 5:
|
|
output[0] = 1;
|
|
output[1] = 0;
|
|
output[2] = 0;
|
|
output[3] = 1;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
Percettrone p = crea_percettrone();
|
|
int colore_rosso = makecol(255, 0, 0);
|
|
|
|
// Contatore per fermare il percettrone, se vale 4 significa che ha indovinato tutte e 4 le combinazioni
|
|
int corrette = 0;
|
|
|
|
Retta *rette = (Retta *)malloc(sizeof(Retta));
|
|
Punto *punti = (Punto *)malloc(sizeof(Punto));
|
|
|
|
// Soglia sigmoide
|
|
double soglia_funzione_attivazione = 0.5;
|
|
|
|
for (int i = 0; i < MAX_EPOCHE; i++)
|
|
{
|
|
if (corrette == 4)
|
|
{
|
|
printf("\nEpoche necessarie: %d\n", i);
|
|
stampa_risultati_layer_singolo(p);
|
|
|
|
//cls(tipo, 0);
|
|
|
|
for (int z = 0; z < i; z++)
|
|
{
|
|
cls(tipo, 0);
|
|
traccia_retta(rette[z].m, rette[z].q, colore_rosso);
|
|
//printf("Sto tracciando la retta con coefficiente: %f e intercetta: %f\n", rette[z].m, rette[z].q);
|
|
stampa_epoca(z + 1);
|
|
sleep_ms(100);
|
|
}
|
|
|
|
readkey();
|
|
break;
|
|
}
|
|
|
|
printf("\nEpoca %d\n", i);
|
|
corrette = 0;
|
|
|
|
for (int j = 0; j < 4; j++)
|
|
{
|
|
double y = funzione_sigmoide(p, x[j][0], x[j][1]);
|
|
|
|
double errore = output[j] - y;
|
|
int previsione = -1;
|
|
|
|
if (y >= soglia_funzione_attivazione)
|
|
{
|
|
previsione = 1;
|
|
}
|
|
else
|
|
{
|
|
previsione = 0;
|
|
}
|
|
|
|
stampa_layer_out(p, previsione, x[j][0], x[j][1], errore);
|
|
|
|
if (previsione == output[j])
|
|
{
|
|
corrette++;
|
|
}
|
|
else
|
|
{
|
|
double gradiente_w1 = errore * y * (1 - y) * x[j][0];
|
|
double gradiente_w2 = errore * y * (1 - y) * x[j][1];
|
|
double gradiente_bias = errore * y * (1 - y);
|
|
|
|
correggi_pesi(&p, gradiente_w1, gradiente_w2, gradiente_bias);
|
|
}
|
|
|
|
rette[i].m = -(p.w1 / p.w2);
|
|
rette[i].q = -(p.bias / p.w2);
|
|
|
|
if (corrette != 4)
|
|
{
|
|
rette = (Retta *)realloc(rette, sizeof(Retta) * (i + 2));
|
|
}
|
|
}
|
|
}
|
|
} |