ART1.C
上传用户:huangyn889
上传日期:2022-07-27
资源大小:9k
文件大小:10k
开发平台:

Visual C++

  1. /******************************************************************************
  2.                       ===========================
  3.         Network:      Adaptive Resonance Theory 1
  4.                       ===========================
  5.         Application:  Brain Modeling
  6.                       Stability-Plasticity Demonstration
  7.         Author:       Karsten Kutza
  8.         Date:         27.6.96
  9.         Reference:    G.A. Carpenter, S. Grossberg
  10.                       A Massively Parallel Architecture
  11.                       for a Self-Organizing Neural Pattern Recognition Machine
  12.                       Computer Vision, Graphics, and Image Processing, 37,
  13.                       pp. 54-115, 1987
  14.  ******************************************************************************/
  15. /******************************************************************************
  16.                             D E C L A R A T I O N S
  17.  ******************************************************************************/
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <math.h>
  21. typedef int           BOOL;
  22. typedef char          CHAR;
  23. typedef int           INT;
  24. typedef double        REAL;
  25. #define FALSE         0
  26. #define TRUE          1
  27. #define NOT           !
  28. #define AND           &&
  29. #define OR            ||
  30. #define MIN_REAL      -HUGE_VAL
  31. #define MAX_REAL      +HUGE_VAL
  32. typedef struct {                     /* A LAYER OF A NET:                     */
  33.         INT           Units;         /* - number of units in this layer       */
  34.         BOOL*         Output;        /* - output of ith unit                  */
  35.         REAL**        Weight;        /* - connection weights to ith unit      */
  36.         BOOL*         Inhibited;     /* - inhibition status of ith F2 unit    */
  37. } LAYER;
  38. typedef struct {                     /* A NET:                                */
  39.         LAYER*        F1;            /* - F1 layer                            */
  40.         LAYER*        F2;            /* - F2 layer                            */
  41.         INT           Winner;        /* - last winner in F2 layer             */
  42.         REAL          A1;            /* - A parameter for F1 layer            */
  43.         REAL          B1;            /* - B parameter for F1 layer            */
  44.         REAL          C1;            /* - C parameter for F1 layer            */
  45.         REAL          D1;            /* - D parameter for F1 layer            */
  46.         REAL          L;             /* - L parameter for net                 */
  47.         REAL          Rho;           /* - vigilance parameter                 */
  48. } NET;
  49. /******************************************************************************
  50.                A P P L I C A T I O N - S P E C I F I C   C O D E
  51.  ******************************************************************************/
  52. #define N             5
  53. #define M             10
  54. #define NO_WINNER     M
  55. #define NUM_DATA      30
  56. CHAR                  Pattern[NUM_DATA][N] = { "   O ",
  57.                                                "  O O",
  58.                                                "    O",
  59.                                                "  O O",
  60.                                                "    O",
  61.                                                "  O O",
  62.                                                "    O",
  63.                                                " OO O",
  64.                                                " OO  ",
  65.                                                " OO O",
  66.                                                " OO  ",
  67.                                                "OOO  ",
  68.                                                "OO   ",
  69.                                                "O    ",
  70.                                                "OO   ",
  71.                                                "OOO  ",
  72.                                                "OOOO ",
  73.                                                "OOOOO",
  74.                                                "O    ",
  75.                                                " O   ",
  76.                                                "  O  ",
  77.                                                "   O ",
  78.                                                "    O",
  79.                                                "  O O",
  80.                                                " OO O",
  81.                                                " OO  ",
  82.                                                "OOO  ",
  83.                                                "OO   ",
  84.                                                "OOOO ",
  85.                                                "OOOOO"  };
  86. BOOL                  Input [NUM_DATA][N];
  87. BOOL                  Output[NUM_DATA][M];
  88. FILE*                 f;
  89. void InitializeApplication(NET* Net)
  90. {
  91.   INT n,i,j;
  92.   for (n=0; n<NUM_DATA; n++) {
  93.     for (i=0; i<N; i++) {
  94.       Input[n][i] = (Pattern[n][i] == 'O');
  95.     }
  96.   }
  97.   Net->A1  = 1;
  98.   Net->B1  = 1.5;
  99.   Net->C1  = 5;
  100.   Net->D1  = 0.9;
  101.   Net->L   = 3;
  102.   Net->Rho = 0.9;
  103.   for (i=0; i<Net->F1->Units; i++) {
  104.     for (j=0; j<Net->F2->Units; j++) {
  105.       Net->F1->Weight[i][j] = (Net->B1 - 1) / Net->D1 + 0.2;
  106.       Net->F2->Weight[j][i] = Net->L / (Net->L - 1 + N) - 0.1;
  107.     }
  108.   }
  109.   f = fopen("ART1.txt", "w");
  110. }
  111. void WriteInput(NET* Net, BOOL* Input)
  112. {
  113.   INT i;
  114.    
  115.   for (i=0; i<N; i++) {
  116.     fprintf(f, "%c", (Input[i]) ? 'O' : ' ');
  117.   }
  118.   fprintf(f, " -> ");
  119. }
  120. void WriteOutput(NET* Net, BOOL* Output)
  121. {
  122.   if (Net->Winner != NO_WINNER)
  123.     fprintf(f, "Class %in", Net->Winner);
  124.   else
  125.     fprintf(f, "new Input and all Classes exhaustedn");
  126. }
  127. void FinalizeApplication(NET* Net)
  128. {
  129.   fclose(f);
  130. }
  131. /******************************************************************************
  132.                           I N I T I A L I Z A T I O N
  133.  ******************************************************************************/
  134. void GenerateNetwork(NET* Net)
  135. {
  136.   INT i;
  137.   Net->F1 = (LAYER*) malloc(sizeof(LAYER));
  138.   Net->F2 = (LAYER*) malloc(sizeof(LAYER));
  139.       
  140.   Net->F1->Units     = N;
  141.   Net->F1->Output    = (BOOL*)  calloc(N, sizeof(BOOL));
  142.   Net->F1->Weight    = (REAL**) calloc(N, sizeof(REAL*));
  143.   Net->F2->Units     = M;
  144.   Net->F2->Output    = (BOOL*)  calloc(M, sizeof(BOOL));
  145.   Net->F2->Weight    = (REAL**) calloc(M, sizeof(REAL*));
  146.   Net->F2->Inhibited = (BOOL*)  calloc(M, sizeof(BOOL));
  147.   for (i=0; i<N; i++) {
  148.     Net->F1->Weight[i] = (REAL*) calloc(M, sizeof(REAL));
  149.   }
  150.   for (i=0; i<M; i++) {
  151.     Net->F2->Weight[i] = (REAL*) calloc(N, sizeof(REAL));
  152.   }
  153. }
  154. void SetInput(NET* Net, BOOL* Input)
  155. {
  156.   INT  i;
  157.   REAL Activation;
  158.    
  159.   for (i=0; i<Net->F1->Units; i++) {
  160.     Activation = Input[i] / (1 + Net->A1 * (Input[i] + Net->B1) + Net->C1);
  161.     Net->F1->Output[i] = (Activation > 0);
  162.   }
  163. }
  164. void GetOutput(NET* Net, BOOL* Output)
  165. {
  166.   INT i;
  167.    
  168.   for (i=0; i<Net->F2->Units; i++) {
  169.     Output[i] = Net->F2->Output[i];
  170.   }
  171. }
  172. /******************************************************************************
  173.                      P R O P A G A T I N G   S I G N A L S
  174.  ******************************************************************************/
  175. void PropagateToF2(NET* Net)
  176. {
  177.   INT  i,j;
  178.   REAL Sum, MaxOut;
  179.    
  180.   MaxOut = MIN_REAL;
  181.   Net->Winner = NO_WINNER;
  182.   for (i=0; i<Net->F2->Units; i++) {
  183.     if (NOT Net->F2->Inhibited[i]) {
  184.       Sum = 0;
  185.       for (j=0; j<Net->F1->Units; j++) {
  186.         Sum += Net->F2->Weight[i][j] * Net->F1->Output[j];
  187.       }
  188.       if (Sum > MaxOut) {
  189.         MaxOut = Sum;
  190.         Net->Winner = i;
  191.       }
  192.     }
  193.     Net->F2->Output[i] = FALSE;
  194.   }
  195.   if (Net->Winner != NO_WINNER)
  196.     Net->F2->Output[Net->Winner] = TRUE;
  197. }
  198. void PropagateToF1(NET* Net, BOOL* Input)
  199. {
  200.   INT  i;
  201.   REAL Sum, Activation;
  202.    
  203.   for (i=0; i<Net->F1->Units; i++) {
  204.     Sum = Net->F1->Weight[i][Net->Winner] * Net->F2->Output[Net->Winner];
  205.     Activation = (Input[i] + Net->D1 * Sum - Net->B1) /
  206.                  (1 + Net->A1 * (Input[i] + Net->D1 * Sum) + Net->C1);
  207.     Net->F1->Output[i] = (Activation > 0);
  208.   }
  209. }
  210. /******************************************************************************
  211.                         A D J U S T I N G   W E I G H T S
  212.  ******************************************************************************/
  213. REAL Magnitude(NET* Net, BOOL* Input)
  214. {
  215.   INT  i;
  216.   REAL Magnitude;
  217.   Magnitude = 0;
  218.   for (i=0; i<Net->F1->Units; i++) {
  219.     Magnitude += Input[i];
  220.   }
  221.   return Magnitude;
  222. }
  223. void AdjustWeights(NET* Net)
  224. {
  225.   INT  i;
  226.   REAL MagnitudeInput_;
  227.   for (i=0; i<Net->F1->Units; i++) {
  228.     if (Net->F1->Output[i]) {
  229.       MagnitudeInput_ = Magnitude(Net, Net->F1->Output);
  230.       Net->F1->Weight[i][Net->Winner] = 1;
  231.       Net->F2->Weight[Net->Winner][i] = Net->L / (Net->L - 1 + MagnitudeInput_);
  232.     }
  233.     else {
  234.       Net->F1->Weight[i][Net->Winner] = 0;
  235.       Net->F2->Weight[Net->Winner][i] = 0;
  236.     }
  237.   }
  238. }
  239. /******************************************************************************
  240.                       S I M U L A T I N G   T H E   N E T
  241.  ******************************************************************************/
  242. void SimulateNet(NET* Net, BOOL* Input, BOOL* Output)
  243. {
  244.   INT  i;
  245.   BOOL Resonance, Exhausted;
  246.   REAL MagnitudeInput, MagnitudeInput_;
  247.   WriteInput(Net, Input);      
  248.   for (i=0; i<Net->F2->Units; i++) {
  249.     Net->F2->Inhibited[i] = FALSE;
  250.   }
  251.   Resonance = FALSE;
  252.   Exhausted = FALSE;
  253.   do {
  254.     SetInput(Net, Input);
  255.     PropagateToF2(Net);
  256.     GetOutput(Net, Output);
  257.     if (Net->Winner != NO_WINNER) {
  258.       PropagateToF1(Net, Input);
  259.       MagnitudeInput = Magnitude(Net, Input);
  260.       MagnitudeInput_ = Magnitude(Net, Net->F1->Output);
  261.       if ((MagnitudeInput_ / MagnitudeInput) < Net->Rho)
  262.         Net->F2->Inhibited[Net->Winner] = TRUE;
  263.       else
  264.         Resonance = TRUE;
  265.     }
  266.     else Exhausted = TRUE;
  267.   } while (NOT (Resonance OR Exhausted));
  268.   if (Resonance)
  269.     AdjustWeights(Net);
  270.   WriteOutput(Net, Output);      
  271. }
  272. /******************************************************************************
  273.                                     M A I N
  274.  ******************************************************************************/
  275. void main()
  276. {
  277.   NET Net;
  278.   INT n;
  279.   GenerateNetwork(&Net);
  280.   InitializeApplication(&Net);
  281.   for (n=0; n<NUM_DATA; n++) {
  282.     SimulateNet(&Net, Input[n], Output[n]);
  283.   }
  284.   FinalizeApplication(&Net);
  285. }