这里有一个简单的Hopfield网络,我是在我正在读的一本书的帮助下写的。我想让你回顾一下,并给我你的建议,特别是关于节点更新部分(主要功能的最后一部分)。
示例:
网络应该记住这些模式: 1111,1010,0101,1001,0110。
如果你进入:
1100
网络将回忆起这种模式:
0110
#include <stdio.h>
#include <iostream>
#include <math.h>
class Hopfield_neuron
{
protected:
int activation;
friend class Hopfield_network;
public:
int weight[4];
Hopfield_neuron() {};
Hopfield_neuron(int *j);
int act(int , int*);
};
class Hopfield_network
{
public:
Hopfield_neuron neuron[4];
int output[4];
int threshold(int);
void update(int, int*, int*);
void activation(int j[4]);
Hopfield_network(int*, int*, int*, int*);
};#include "Hopfield.h";
Hopfield_neuron::Hopfield_neuron(int *j)
{
for(int i=0; i<4; i++)
{
weight[i] = *(j+i);
}
}
int Hopfield_neuron::act(int m, int *pattern)
{
int a = 0;
for(int i=0; i<4; i++)
{
a += pattern[i] * weight[i];
}
return a;
}
int Hopfield_network::threshold(int k)
{
if ( k >= 0)
return 1;
else
return 0;
}
void Hopfield_network::update(int node, int *pattern, int *weight)
{
int vin = 0;
for(int i=0; i<4; i++)
{
vin += pattern[i] * weight[i];
}
if(threshold(vin) != pattern[node])
{
pattern[node] = threshold(vin);
}
}
Hopfield_network::Hopfield_network(int nrn0[4], int nrn1[4], int nrn2[4], int nrn3[4])
{
neuron[0] = Hopfield_neuron(nrn0);
neuron[1] = Hopfield_neuron(nrn1);
neuron[2] = Hopfield_neuron(nrn2);
neuron[3] = Hopfield_neuron(nrn3);
}
void Hopfield_network::activation(int *pattern)
{
for(int i=0; i<4; i++)
{
neuron[i].activation = neuron[i].act(4, pattern);
output[i] = threshold(neuron[i].activation);
}
}
void main()
{
int pattern1[] = {1,1,0,0};
int weight1[] = { 0, -5, 4, 4};
int weight2[] = {-5, 0, 4, 4};
int weight3[] = { 4, 4, 0, -5};
int weight4[] = { 4, 4, -5, 0};
std::cout<<"This is hopfield network with a single layer of 4";
std::cout<<"\nfully interconnected neurons. The network should recall the \nPatterns 1111, 1010, 0101, 1001, 0110 correctly.\n";
Hopfield_network h1(weight1, weight2, weight3, weight4);
h1.activation(pattern1);
for(int i=0; i<4; i++)
{
if(h1.output[i] == pattern1[i])
{
std::cout<<"\n pattern = "<<pattern1[i]<<" output = "<<h1.output[i]<<" component matches";
}
else
{
std::cout<<"\n pattern = "<<pattern1[i]<<" output = "<<h1.output[i]<<" discrepancy occured";
}
}
int choosedNodes[8] = {1,2,3,4,1,2,3,4};
int weight[4];
for(int i=0; i<8; i++)
{
switch(choosedNodes[i])
{
case 1: weight[0] = 0; weight[1] = -5; weight[2] = 4; weight[3] = 4;
break;
case 2: weight[0] = -5; weight[1] = 0; weight[2] = 4; weight[3] = 4;
break;
case 3: weight[0] = 4; weight[1] = 4; weight[2] = 0; weight[3] = -5;
break;
case 4: weight[0] = 4; weight[1] = 4; weight[2] = -5; weight[3] = 0;
break;
}
h1.update(choosedNodes[i]-1, pattern1, weight);
}
std::cout<<"\n\n The recalled Pattern\n";
for(int i=0; i<4; i++)
{
std::cout<<"\n pattern = "<<pattern1[i];
}
std::cin.get();
}发布于 2015-07-04 01:22:45
你的压痕很不一致。为缩进选择一些空格,并坚持它。
<stdio.h>和<math.h>)在C++中。他们应该分别是<cstdio>和<cmath>。您也可以删除它们,因为它们似乎并不在使用。最后,您应该将<iostream>移动到.cpp文件,因为它不在头文件中使用。一般来说,头文件应该有尽可能少的链接,因为其他文件依赖于它们,并且可能会受到它们的影响和破坏。Hopfield_neuron中,您应该使用private而不是protected。只有当另一个类要从它继承时,才需要后者。而且,weight不应该是public,因为它是数据成员。Hopfield_network不应该完全是public。前三个数据成员应该是private,而成员函数可以保留public。void作为main()的S返回类型。它可能被一些不兼容的编译器所允许,但它仍然被认为是不标准的。它应该只返回int。threshold()只需使用单行三元语句:返回(k >= 0)?1: 0;您还应该使其为const,因为它不修改任何数据成员: int Hopfield_network::threshold(int k) const {}Hopfield_network()参数行的末尾删除多余的空格: Hopfield_network::Hopfield_network(int nrn04.,int nrn14.,int nrn24.,int nrn34.)std::vector之类的存储容器来代替C样式数组。如果可能的话,不应该在C++中使用后者。原因之一是将它们传递给函数会导致它们衰变为指针。这已经发生在您的许多功能中。switch中。这有助于提高可读性,防止水平线字符数量增加。https://codereview.stackexchange.com/questions/84318
复制相似问题