Listing des Programms HOPSI-PI.C


/*      Programm hopsi-pi.c                                  */
/*      Bidirektionaler Autoassoziativspeicher nach          */
/*      Hopfield mit Hebb-Lernregel zur Bilderassoziation    */
/*      sowie Sigma-Pi-Neuronen 2-ter Ordnung                */
/*      Burkhard Lenze                                       */
/*      13.02.2009                                           */

/*      header-files                     */

#include <stdio.h>
#include <math.h>
#include "hopsi-pi.h"

/*      globale Variablen                */

int x[21];                               /*  Ein-/Ausgabevektorfeld          */
int w[21];                               /*  Matrixfeld der Gewichte 0. Ordn.*/
int ww[21][21];                          /*  Matrixfeld der Gewichte 1. Ordn.*/
int www[21][21][21];                     /*  Matrixfeld der Gewichte 2. Ordn.*/
int n;                                   /*  Anzahl der Ein-/Ausgabe-Neuronen*/
int zeile_x,spalte_x;                    /*  Zeilen/Spalten der Bilder       */
char com;                                /*  Menuparameter                   */

/*      Funktionen                       */

void lese_x(void) 
    {
    int i,r,c,nn;
    char k;
    FILE *f;
    char dat[20];
    printf("\nWie lautet die Bilddatei ? \n");
    scanf("%s",&dat);
    f=fopen(dat,"r");
    fscanf(f,"%d",&nn);
    if (nn==spalte_x) 
       {
       fscanf(f,"%d",&nn);
       if (nn==zeile_x)
          {      
          i=1; 
          for (r=1;r<=zeile_x+1;r++)
              {
              for (c=1;c<=spalte_x+1;c++) 
                  {
                  fscanf(f,"%c",&k);
                  printf("%c",k);
                  if (k=='.') {
                              x[i]=-1;
                              }
                  if (k=='X') {
                              x[i]=1;
                              }
                  if (k=='\n') {i=i-1;}
                  i=i+1;
                  }
              }
          }
       else
          {
          printf("\nFehler! Zeilen in Datei %2d statt %2d \n",nn,zeile_x);
          }
       } 
    else
       {
       printf("\nFehler! Spalten in Datei %2d statt %2d \n",nn,spalte_x);
       }
    fclose(f);
    }

int T(int A)
    {
    if (A>0) return(1);
    if (A<0) return(-1);
    } 

void lernen(void) 
    {
    int i,j,k;
    lese_x();
    for (i=1;i<=n;i++)
        {
        w[i]=w[i]+x[i];
        for (j=1;j<i;j++) 
            {
            ww[i][j]=ww[i][j]+(x[i]*x[j]);
            ww[j][i]=ww[i][j];
            for (k=1;k<j;k++)
                {
                www[i][j][k]=www[i][j][k]+(x[i]*x[j]*x[k]);
                www[i][k][j]=www[i][j][k];      
                www[j][k][i]=www[i][j][k];      
                www[j][i][k]=www[i][j][k];      
                www[k][i][j]=www[i][j][k];      
                www[k][j][i]=www[i][j][k];
                }       
            }
        }
    }

void zeichne_x(void) 
    {
    int i,r,c;
    i=1;
    printf("\n");
    for (r=1;r<=zeile_x;r++) 
        {
        for (c=1;c<=spalte_x;c++) 
            {
            if (x[i]>0)
               {
               printf("X");
               }
            else
               {
               printf(".");
               }
            i=i+1; 
            }
        printf("\n");
        }
    }

void ausfuehren(void) 
    {
    int i,j,k,u,C,A;
    lese_x();
    zeichne_x();
    u=-1;
    do
      {
      u=u+1;    
      C=0;
      for (j=1;j<=n;j++)
          {
          A=w[j];
          for (i=1;i<=n;i++) 
              {
              A=A+(ww[i][j]*x[i]);
              for (k=1;k<i;k++)
                  {
                  A=A+(www[k][i][j]*x[k]*x[i]);
                  }
              }
          if (A!=0)
             {
             if (T(A)!=x[j]) C=1;       
             x[j]=T(A);
             }
          }
      zeichne_x();
      }
    while (C!=0);
    } 

void veraendern(void) 
    {
    int i,j,k;
    printf("\n");
    printf("Wieviele Zeilen im Eingabe-Bild ? ");
    scanf("%d",&zeile_x);
    printf("Wieviele Spalten im Eingabe-Bild ? ");
    scanf("%d",&spalte_x);
    n=zeile_x*spalte_x;
    if (n>20)
       {
       printf("\n Bild zu gross! Ggf. globale Felder vergroessern! \n ");
       }
    if (n<21)
       {
       for (i=1;i<=n;i++) {x[i]=0;}
       for (i=1;i<=n;i++) 
           {
           w[i]=0;
           for (j=1;j<=n;j++) 
               {
               ww[j][i]=0;
               for (k=1;k<=n;k++)
                   {
                   www[k][j][i]=0;
                   }
               }
           }    
       }
    }


/*      Hauptprogramm                    */

int main(void)
    {
    veraendern();
    do 
      {
      printf("\nlernen ausfuehren veraendern beenden:\n");
      fflush(stdin);
      scanf("%c",&com);        
      switch(com)
            {
            case 'l': lernen(); break;
            case 'a': ausfuehren(); break;
            case 'v': veraendern(); break;
            default:  break;
            } 
      }
    while (com!='b'); 
    return(0);
    }






Burkhard Lenze
Im Februar 2009