📄 bam.c
字号:
/******************************************************************************
================================
Network: Bidirectional Associative Memory
================================
Application: Heteroassociative Memory
Association of Names and Phone Numbers
Author: Karsten Kutza
Date: 24.1.96
Reference: B. Kosko
Bidirectional Associative Memories
IEEE Transactions on Systems, Man, and Cybernetics, 18,
pp. 49-60, 1988
******************************************************************************/
/******************************************************************************
D E C L A R A T I O N S
******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
typedef int BOOL;
typedef char CHAR;
typedef int INT;
#define FALSE 0
#define TRUE 1
#define NOT !
#define AND &&
#define OR ||
#define LO -1
#define HI +1
#define BINARY(x) ((x)==LO ? FALSE : TRUE)
#define BIPOLAR(x) ((x)==FALSE ? LO : HI)
typedef struct { /* A LAYER OF A NET: */
INT Units; /* - number of units in this layer */
INT* Output; /* - output of ith unit */
INT** Weight; /* - connection weights to ith unit */
} LAYER;
typedef struct { /* A NET: */
LAYER* X; /* - X layer */
LAYER* Y; /* - Y layer */
} NET;
/******************************************************************************
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
******************************************************************************/
void InitializeRandoms()
{
srand(4711);
}
BOOL RandomEqualBOOL()
{
return rand() % 2;
}
/******************************************************************************
A P P L I C A T I O N - S P E C I F I C C O D E
******************************************************************************/
#define NUM_DATA 3
#define IN_CHARS 5
#define OUT_CHARS 7
#define BITS_PER_CHAR 6
#define FIRST_CHAR ' '
#define N (IN_CHARS * BITS_PER_CHAR)
#define M (OUT_CHARS * BITS_PER_CHAR)
CHAR Names [NUM_DATA][IN_CHARS] = { "TINA ",
"ANTJE",
"LISA " };
CHAR Names_[NUM_DATA][IN_CHARS] = { "TINE ",
"ANNJE",
"RITA " };
CHAR Phones[NUM_DATA][OUT_CHARS] = { "6843726",
"8034673",
"7260915" };
INT Input [NUM_DATA][N];
INT Input_[NUM_DATA][N];
INT Output[NUM_DATA][M];
FILE* f;
void InitializeApplication(NET* Net)
{
INT n,i,j,a,a_;
for (n=0; n<NUM_DATA; n++) {
for (i=0; i<IN_CHARS; i++) {
a = Names [n][i] - FIRST_CHAR;
a_ = Names_[n][i] - FIRST_CHAR;
for (j=0; j<BITS_PER_CHAR; j++) {
Input [n][i*BITS_PER_CHAR+j] = BIPOLAR(a % 2);
Input_[n][i*BITS_PER_CHAR+j] = BIPOLAR(a_ % 2);
a /= 2;
a_ /= 2;
}
}
for (i=0; i<OUT_CHARS; i++) {
a = Phones[n][i] - FIRST_CHAR;
for (j=0; j<BITS_PER_CHAR; j++) {
Output[n][i*BITS_PER_CHAR+j] = BIPOLAR(a % 2);
a /= 2;
}
}
}
f = fopen("BAM.txt", "w");
}
void WriteLayer(LAYER* Layer)
{
INT i,j,a,p;
for (i=0; i<(Layer->Units / BITS_PER_CHAR); i++) {
a = 0;
p = 1;
for (j=0; j<BITS_PER_CHAR; j++) {
a += BINARY(Layer->Output[i*BITS_PER_CHAR+j]) * p;
p *= 2;
}
fprintf(f, "%c", a + FIRST_CHAR);
}
}
void FinalizeApplication(NET* Net)
{
fclose(f);
}
/******************************************************************************
I N I T I A L I Z A T I O N
******************************************************************************/
void GenerateNetwork(NET* Net)
{
INT i;
Net->X = (LAYER*) malloc(sizeof(LAYER));
Net->Y = (LAYER*) malloc(sizeof(LAYER));
Net->X->Units = N;
Net->X->Output = (INT*) calloc(N, sizeof(INT));
Net->X->Weight = (INT**) calloc(N, sizeof(INT*));
Net->Y->Units = M;
Net->Y->Output = (INT*) calloc(M, sizeof(INT));
Net->Y->Weight = (INT**) calloc(M, sizeof(INT*));
for (i=0; i<N; i++) {
Net->X->Weight[i] = (INT*) calloc(M, sizeof(INT));
}
for (i=0; i<M; i++) {
Net->Y->Weight[i] = (INT*) calloc(N, sizeof(INT));
}
}
void CalculateWeights(NET* Net)
{
INT i,j,n;
INT Weight;
for (i=0; i<Net->X->Units; i++) {
for (j=0; j<Net->Y->Units; j++) {
Weight = 0;
for (n=0; n<NUM_DATA; n++) {
Weight += Input[n][i] * Output[n][j];
}
Net->X->Weight[i][j] = Weight;
Net->Y->Weight[j][i] = Weight;
}
}
}
void SetInput(LAYER* Layer, INT* Input)
{
INT i;
for (i=0; i<Layer->Units; i++) {
Layer->Output[i] = Input[i];
}
WriteLayer(Layer);
}
void SetRandom(LAYER* Layer)
{
INT i;
for (i=0; i<Layer->Units; i++) {
Layer->Output[i] = BIPOLAR(RandomEqualBOOL());
}
WriteLayer(Layer);
}
void GetOutput(LAYER* Layer, INT* Output)
{
INT i;
for (i=0; i<Layer->Units; i++) {
Output[i] = Layer->Output[i];
}
WriteLayer(Layer);
}
/******************************************************************************
P R O P A G A T I N G S I G N A L S
******************************************************************************/
BOOL PropagateLayer(LAYER* From, LAYER* To)
{
INT i,j;
INT Sum, Out;
BOOL Stable;
Stable = TRUE;
for (i=0; i<To->Units; i++) {
Sum = 0;
for (j=0; j<From->Units; j++) {
Sum += To->Weight[i][j] * From->Output[j];
}
if (Sum != 0) {
if (Sum < 0) Out = LO;
if (Sum > 0) Out = HI;
if (Out != To->Output[i]) {
Stable = FALSE;
To->Output[i] = Out;
}
}
}
return Stable;
}
void PropagateNet(LAYER* From, LAYER* To)
{
BOOL Stable1, Stable2;
do {
Stable1 = PropagateLayer(From, To);
Stable2 = PropagateLayer(To, From);
} while (NOT (Stable1 AND Stable2));
}
/******************************************************************************
S I M U L A T I N G T H E N E T
******************************************************************************/
void SimulateNet(LAYER* From, LAYER* To, INT* Pattern, INT* Input, INT* Output)
{
SetInput(From, Pattern); fprintf(f, " -> ");
SetRandom(To); fprintf(f, " | ");
PropagateNet(From, To);
GetOutput(From, Input); fprintf(f, " -> ");
GetOutput(To, Output); fprintf(f, "\n\n");
}
/******************************************************************************
M A I N
******************************************************************************/
void main()
{
NET Net;
INT n;
INT I[N], O[M];
InitializeRandoms();
GenerateNetwork(&Net);
InitializeApplication(&Net);
CalculateWeights(&Net);
for (n=0; n<NUM_DATA; n++) {
SimulateNet(Net.X, Net.Y, Input[n], I, O);
}
for (n=0; n<NUM_DATA; n++) {
SimulateNet(Net.Y, Net.X, Output[n], O, I);
}
for (n=0; n<NUM_DATA; n++) {
SimulateNet(Net.X, Net.Y, Input_[n], I, O);
}
FinalizeApplication(&Net);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -