BAM.C
上传用户:wxmrkjyy
上传日期:2022-07-27
资源大小:5k
文件大小:8k
开发平台:

Visual C++

  1. /******************************************************************************
  2.                       ================================
  3.         Network:      Bidirectional Associative Memory
  4.                       ================================
  5.         Application:  Heteroassociative Memory
  6.                       Association of Names and Phone Numbers
  7.         Author:       Karsten Kutza
  8.         Date:         24.1.96
  9.         Reference:    B. Kosko
  10.                       Bidirectional Associative Memories
  11.                       IEEE Transactions on Systems, Man, and Cybernetics, 18,
  12.                       pp. 49-60, 1988
  13.  ******************************************************************************/
  14. /******************************************************************************
  15.                             D E C L A R A T I O N S
  16.  ******************************************************************************/
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. typedef int           BOOL;
  20. typedef char          CHAR;
  21. typedef int           INT;
  22. #define FALSE         0
  23. #define TRUE          1
  24. #define NOT           !
  25. #define AND           &&
  26. #define OR            ||
  27. #define LO            -1
  28. #define HI            +1
  29. #define BINARY(x)     ((x)==LO ? FALSE : TRUE)
  30. #define BIPOLAR(x)    ((x)==FALSE ? LO : HI)
  31. typedef struct {                     /* A LAYER OF A NET:                     */
  32.         INT           Units;         /* - number of units in this layer       */
  33.         INT*          Output;        /* - output of ith unit                  */
  34.         INT**         Weight;        /* - connection weights to ith unit      */
  35. } LAYER;
  36. typedef struct {                     /* A NET:                                */
  37.         LAYER*        X;             /* - X layer                             */
  38.         LAYER*        Y;             /* - Y layer                             */
  39. } NET;
  40. /******************************************************************************
  41.         R A N D O M S   D R A W N   F R O M   D I S T R I B U T I O N S
  42.  ******************************************************************************/
  43. void InitializeRandoms()
  44. {
  45.   srand(4711);
  46. }
  47. BOOL RandomEqualBOOL()
  48. {
  49.   return rand() % 2;
  50. }      
  51. /******************************************************************************
  52.                A P P L I C A T I O N - S P E C I F I C   C O D E
  53.  ******************************************************************************/
  54. #define NUM_DATA      3
  55. #define IN_CHARS      5
  56. #define OUT_CHARS     7
  57. #define BITS_PER_CHAR 6
  58. #define FIRST_CHAR    ' '
  59. #define N             (IN_CHARS  * BITS_PER_CHAR)
  60. #define M             (OUT_CHARS * BITS_PER_CHAR)
  61. CHAR                  Names [NUM_DATA][IN_CHARS]  = { "TINA ",
  62.                                                       "ANTJE", 
  63.                                                       "LISA "  };
  64.                                      
  65. CHAR                  Names_[NUM_DATA][IN_CHARS]  = { "TINE ",
  66.                                                       "ANNJE", 
  67.                                                       "RITA "  };
  68. CHAR                  Phones[NUM_DATA][OUT_CHARS] = { "6843726",
  69.                                                       "8034673",
  70.                                                       "7260915"  };
  71. INT                   Input [NUM_DATA][N];
  72. INT                   Input_[NUM_DATA][N];
  73. INT                   Output[NUM_DATA][M];
  74. FILE*                 f;
  75. void InitializeApplication(NET* Net)
  76. {
  77.   INT n,i,j,a,a_;
  78.   for (n=0; n<NUM_DATA; n++) {
  79.     for (i=0; i<IN_CHARS; i++) {
  80.       a  = Names [n][i] - FIRST_CHAR;
  81.       a_ = Names_[n][i] - FIRST_CHAR;
  82.       for (j=0; j<BITS_PER_CHAR; j++) {
  83.         Input [n][i*BITS_PER_CHAR+j] = BIPOLAR(a  % 2);
  84.         Input_[n][i*BITS_PER_CHAR+j] = BIPOLAR(a_ % 2);
  85.         a  /= 2;
  86.         a_ /= 2;
  87.       }
  88.     }
  89.     for (i=0; i<OUT_CHARS; i++) {
  90.       a = Phones[n][i] - FIRST_CHAR;
  91.       for (j=0; j<BITS_PER_CHAR; j++) {
  92.         Output[n][i*BITS_PER_CHAR+j] = BIPOLAR(a % 2);
  93.         a /= 2;
  94.       }
  95.     }
  96.   }
  97.   f = fopen("BAM.txt", "w");
  98. }
  99. void WriteLayer(LAYER* Layer)
  100. {
  101.   INT i,j,a,p;
  102.    
  103.   for (i=0; i<(Layer->Units / BITS_PER_CHAR); i++) {
  104.     a = 0;
  105.     p = 1;
  106.     for (j=0; j<BITS_PER_CHAR; j++) {
  107.       a += BINARY(Layer->Output[i*BITS_PER_CHAR+j]) * p;
  108.       p *= 2;  
  109.     }
  110.     fprintf(f, "%c", a + FIRST_CHAR);
  111.   }
  112. }
  113. void FinalizeApplication(NET* Net)
  114. {
  115.   fclose(f);
  116. }
  117. /******************************************************************************
  118.                           I N I T I A L I Z A T I O N
  119.  ******************************************************************************/
  120. void GenerateNetwork(NET* Net)
  121. {
  122.   INT i;
  123.   Net->X = (LAYER*) malloc(sizeof(LAYER));
  124.   Net->Y = (LAYER*) malloc(sizeof(LAYER));
  125.       
  126.   Net->X->Units  = N;
  127.   Net->X->Output = (INT*)  calloc(N, sizeof(INT));
  128.   Net->X->Weight = (INT**) calloc(N, sizeof(INT*));
  129.   Net->Y->Units  = M;
  130.   Net->Y->Output = (INT*)  calloc(M, sizeof(INT));
  131.   Net->Y->Weight = (INT**) calloc(M, sizeof(INT*));
  132.   for (i=0; i<N; i++) {
  133.     Net->X->Weight[i] = (INT*) calloc(M, sizeof(INT));
  134.   }
  135.   for (i=0; i<M; i++) {
  136.     Net->Y->Weight[i] = (INT*) calloc(N, sizeof(INT));
  137.   }
  138. }
  139. void CalculateWeights(NET* Net)
  140. {
  141.   INT i,j,n;
  142.   INT Weight;
  143.   for (i=0; i<Net->X->Units; i++) {
  144.     for (j=0; j<Net->Y->Units; j++) {
  145.       Weight = 0;
  146.       for (n=0; n<NUM_DATA; n++) {
  147.         Weight += Input[n][i] * Output[n][j];
  148.       }
  149.       Net->X->Weight[i][j] = Weight;
  150.       Net->Y->Weight[j][i] = Weight;
  151.     }
  152.   }
  153. }
  154. void SetInput(LAYER* Layer, INT* Input)
  155. {
  156.   INT i;
  157.    
  158.   for (i=0; i<Layer->Units; i++) {
  159.     Layer->Output[i] = Input[i];
  160.   }
  161.   WriteLayer(Layer);
  162. }
  163. void SetRandom(LAYER* Layer)
  164. {
  165.   INT i;
  166.    
  167.   for (i=0; i<Layer->Units; i++) {
  168.     Layer->Output[i] = BIPOLAR(RandomEqualBOOL());
  169.   }
  170.   WriteLayer(Layer);
  171. }
  172. void GetOutput(LAYER* Layer, INT* Output)
  173. {
  174.   INT i;
  175.    
  176.   for (i=0; i<Layer->Units; i++) {
  177.     Output[i] = Layer->Output[i];
  178.   }
  179.   WriteLayer(Layer);
  180. }
  181. /******************************************************************************
  182.                      P R O P A G A T I N G   S I G N A L S
  183.  ******************************************************************************/
  184. BOOL PropagateLayer(LAYER* From, LAYER* To)
  185. {
  186.   INT  i,j;
  187.   INT  Sum, Out;
  188.   BOOL Stable;
  189.   Stable = TRUE;
  190.   for (i=0; i<To->Units; i++) {
  191.     Sum = 0;
  192.     for (j=0; j<From->Units; j++) {
  193.       Sum += To->Weight[i][j] * From->Output[j];
  194.     }
  195.     if (Sum != 0) {
  196.       if (Sum < 0) Out = LO;
  197.       if (Sum > 0) Out = HI;
  198.       if (Out != To->Output[i]) {
  199.         Stable = FALSE;
  200.         To->Output[i] = Out;
  201.       }
  202.     }
  203.   }
  204.   return Stable;
  205. }
  206. void PropagateNet(LAYER* From, LAYER* To)
  207. {
  208.   BOOL Stable1, Stable2;
  209.   do {
  210.     Stable1 = PropagateLayer(From, To);
  211.     Stable2 = PropagateLayer(To, From);
  212.   } while (NOT (Stable1 AND Stable2));
  213. }
  214. /******************************************************************************
  215.                       S I M U L A T I N G   T H E   N E T
  216.  ******************************************************************************/
  217. void SimulateNet(LAYER* From, LAYER* To, INT* Pattern, INT* Input, INT* Output)
  218. {
  219.   SetInput(From, Pattern); fprintf(f, " -> ");
  220.   SetRandom(To);           fprintf(f, "  |  ");
  221.   PropagateNet(From, To);
  222.   GetOutput(From, Input);  fprintf(f, " -> ");
  223.   GetOutput(To, Output);   fprintf(f, "nn");
  224. }
  225. /******************************************************************************
  226.                                     M A I N
  227.  ******************************************************************************/
  228. void main()
  229. {
  230.   NET Net;
  231.   INT n;
  232.   INT I[N], O[M];
  233.   InitializeRandoms();
  234.   GenerateNetwork(&Net);
  235.   InitializeApplication(&Net);
  236.   CalculateWeights(&Net);
  237.    
  238.   for (n=0; n<NUM_DATA; n++) {
  239.     SimulateNet(Net.X, Net.Y, Input[n],  I, O);
  240.   }
  241.   for (n=0; n<NUM_DATA; n++) {
  242.     SimulateNet(Net.Y, Net.X, Output[n], O, I);
  243.   }
  244.   for (n=0; n<NUM_DATA; n++) {
  245.     SimulateNet(Net.X, Net.Y, Input_[n], I, O);
  246.   }
  247.    
  248.   FinalizeApplication(&Net);
  249. }