This commit is contained in:
2014-10-02 17:52:56 +02:00
commit 8c1b406259
23 changed files with 525 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
NN.kdev4
.kdev4

29
Makefile Normal file
View File

@@ -0,0 +1,29 @@
LIBS=input constant element integrator system simulation
OBJFILES=./src/Solution.o ./src/Problem.o ./src/Network.o ./src/Neuron.o ./src/Genetics.o
include ./Makefile.const
.PHONY: all
all: lib
test: all
make -C tests
lib: $(LIBNAME).a $(LIBNAME).so
clean:
rm -f ./src/*.o
rm -f ./$(LIBNAME).so ./$(LIBNAME).a ./$(LIBNAME).nm
%.o : %.cpp %.h
$(CXX) $(CXXFLAGS) -c $< -o $@
$(LIBNAME).so: $(OBJFILES)
$(CXX) -shared $(CXXFLAGS) $(OBJFILES) -o $(LIBNAME).so
$(LIBNAME).a: $(OBJFILES)
rm -f $(LIBNAME).a # create new library
ar rcv $(LIBNAME).a $(OBJFILES)
ranlib $(LIBNAME).a
nm --demangle $(LIBNAME).a > $(LIBNAME).nm

8
Makefile.const Normal file
View File

@@ -0,0 +1,8 @@
CXX=g++ -m64
CXXFLAGS+= -Wall -std=c++14
CXXFLAGS+= -g
CXXFLAGS+= -O2
#CXXFLAGS+= -pg -fPIC
CXXFLAGS+= -fPIC
LIBNAME=NN

15
src/Genetics Normal file
View File

@@ -0,0 +1,15 @@
#ifndef _GENETICS_H_
#define _GENETICS_H_
namespace S
{
class Genetics
{
public:
protected:
private:
};
}
#endif

2
src/Genetics.cpp Normal file
View File

@@ -0,0 +1,2 @@
#include "Genetics"

1
src/Genetics.h Symbolic link
View File

@@ -0,0 +1 @@
./Genetics

61
src/Network Normal file
View File

@@ -0,0 +1,61 @@
#ifndef _NN_H_
#define _NN_H_
#include "Problem"
#include "Solution"
#include "Neuron"
#include <cstdarg>
#include <vector>
namespace S
{
class Network
{
public:
virtual Solution solve(const S::Problem&)=0;
virtual void learn(const S::Problem & p, const S::Solution &s)=0;
protected:
private:
};
class ACyclicNetwork : public Network
{
public:
protected:
private:
};
class Layer
{
public:
Layer(int a);
~Layer();
Solution solve(const std::vector<bool> &input);
Neuron* operator[](int neuron) const;
int size() const {return neurons.size();};
protected:
std::vector<Neuron*> neurons;
};
// template <typename _NT>
class FeedForwardNetwork : public ACyclicNetwork
{
public:
template<typename... Args>inline FeedForwardNetwork(Args &&... args) {pass((addLayer(args),1)...);};
//inline FeedForwardNetwork(std::vector<int> q);
~FeedForwardNetwork();
virtual Solution solve(const S::Problem& p) override;
virtual void learn(const S::Problem & p, const S::Solution &s) override;
const Layer* operator[](int layer);
protected:
template<typename... Args> inline void pass(Args&&...) {};
void addLayer(int neurons);
private:
Layer* first;
Layer* last ;
std::vector<Layer*> layers;
};
}
#endif

67
src/Network.cpp Normal file
View File

@@ -0,0 +1,67 @@
#include "Network"
S::FeedForwardNetwork::~FeedForwardNetwork()
{
for(Layer *l:layers)
{
delete l;
}
}
S::Solution S::FeedForwardNetwork::solve(const S::Problem& p)
{
Solution s=Solution(p);
for (Layer *l:layers)
{
s=l->solve(s);
}
return s;
}
void S::FeedForwardNetwork::learn(const S::Problem & problem, const S::Solution &actual)
{
//S::Solution s= solve(p);
}
const S::Layer* S::FeedForwardNetwork::operator[](int layer)
{
return layers[layer];
}
void S::FeedForwardNetwork::addLayer(int neurons)
{
layers.push_back(new Layer(neurons));
}
S::Layer::Layer(int a):neurons()
{
while(a--)
{
neurons.push_back(new Neuron());
}
}
S::Layer::~Layer()
{
for(Neuron *n:neurons)
{
delete n;
}
}
S::Solution S::Layer::solve(const std::vector<bool> &input)
{
std::vector <bool> ret;
for(Neuron *n:neurons)
{
ret.push_back(n->activates(input));
}
return ret;
}
S::Neuron* S::Layer::operator[](int neuron) const
{
return neurons[neuron];
}

1
src/Network.h Symbolic link
View File

@@ -0,0 +1 @@
./Network

25
src/Neuron Normal file
View File

@@ -0,0 +1,25 @@
#ifndef _NEURON_H_
#define _NEURON_H_
#include <vector>
namespace S{
class Neuron
{
public:
Neuron();
double getPotential() const;
void setPotential(double p);
double getWeight(unsigned int) const;
void setWeight(unsigned int i,double p);
bool activates(const std::vector<bool>);
protected:
double potential;
private:
std::vector<double> weights;
};
class SimpleNeuron: public Neuron
{
};
}
#endif

51
src/Neuron.cpp Normal file
View File

@@ -0,0 +1,51 @@
#include "./Neuron"
#include <iostream>
S::Neuron::Neuron(): potential(1),weights()
{
}
double S::Neuron::getPotential() const
{
return potential;
}
void S::Neuron::setPotential(double p)
{
potential=p;
}
double S::Neuron::getWeight(unsigned int i) const
{
if(i >= weights.size())
{
return 1.0;
}
return weights[0];
}
void S::Neuron::setWeight(unsigned int i,double p)
{
if(i >= weights.size())
{
// std::cout << "resize to " << i;
weights.resize(i+1);
}
// std::cerr << "Set " << i << " to " << p << "\n";
weights[i]=p;
}
bool S::Neuron::activates(std::vector<bool> input)
{
double sum=0;
for(unsigned int i=0;i<input.size();i++)
{
// std::cerr << "W: " << getWeight(i) <<"\n";
sum+=getWeight(i)*input[i];
}
//std::cerr << "X: " << sum <<"\n";
if(sum <= getPotential())
return 0;
return 1;
}

1
src/Neuron.h Symbolic link
View File

@@ -0,0 +1 @@
./Neuron

19
src/Problem Normal file
View File

@@ -0,0 +1,19 @@
#ifndef _P_H_
#define _P_H_
#include <vector>
namespace S
{
class Problem
{
public:
Problem();
operator std::vector<bool>() const;
protected:
virtual std::vector<bool> representation() const =0;
private:
};
}
#endif

11
src/Problem.cpp Normal file
View File

@@ -0,0 +1,11 @@
#include "Problem"
S::Problem::Problem()
{
}
S::Problem::operator std::vector<bool>() const
{
return representation();
}

1
src/Problem.h Symbolic link
View File

@@ -0,0 +1 @@
./Problem

21
src/Solution Normal file
View File

@@ -0,0 +1,21 @@
#ifndef _SOL_H_
#define _SOL_H_
#include <vector>
#include "Problem"
namespace S
{
class Solution
{
public:
Solution(std::vector<bool> solution);
int size();
bool operator[] (int pos);
operator std::vector<bool>();
protected:
std::vector<bool> solution;
};
}
#endif

21
src/Solution.cpp Normal file
View File

@@ -0,0 +1,21 @@
#include "./Solution"
S::Solution::Solution(std::vector<bool>solution):solution(solution)
{
}
bool S::Solution::operator[](int pos)
{
return solution[pos];
}
int S::Solution::size()
{
return solution.size();
}
S::Solution::operator std::vector<bool>()
{
return solution;
}

1
src/Solution.h Symbolic link
View File

@@ -0,0 +1 @@
./Solution

34
tests/01.cpp Normal file
View File

@@ -0,0 +1,34 @@
#include "../src/Network"
#include "../src/Problem"
#include <iostream>
class X: public S::Problem
{
protected:
std::vector<bool> representation() const
{
return std::vector<bool>({1,1});
}
};
int main()
{
S::FeedForwardNetwork n(2,3,2);
S::Solution s =n.solve(X());
if(s.size()!=2)
{
std::cout << "1";
return 1;
}
if(s[0]!=1)
{
std::cout << "2";
return 1;
}
if(s[1]!=1)
{
std::cout << "3";
return 1;
}
return 0;
}

1
tests/01.out Normal file
View File

@@ -0,0 +1 @@
1

61
tests/02.cpp Normal file
View File

@@ -0,0 +1,61 @@
#include "../src/Network"
#include "../src/Problem"
#include <iostream>
class X: public S::Problem
{
protected:
std::vector<bool> representation() const
{
return std::vector<bool>({1,1});
}
};
int main()
{
S::FeedForwardNetwork n(2,4,2);
if(n[1]->size() != 4)
{
std::cout << "ACtual size:" << n[0]->size();
return 1;
}
n[2]->operator[](0)->setPotential(25);
std::cout << "Potential: " << n[2]->operator[](0)->getPotential() << "\n";
S::Solution s =n.solve(X());
if(s.size()!=2)
{
std::cout << "1";
return 1;
}
if(s[0]!=0)
{
std::cout << "2";
return 1;
}
if(s[1]!=1)
{
std::cout << "3";
return 1;
}
n[2]->operator[](0)->setWeight(0,26.0);
s =n.solve(X());
if(s.size()!=2)
{
std::cout << "a1";
return 1;
}
if(s[0]!=1)
{
std::cout << "a2";
return 1;
}
if(s[1]!=1)
{
std::cout << "a3";
return 1;
}
return 0;
}

75
tests/03.cpp Normal file
View File

@@ -0,0 +1,75 @@
#include "../src/Network"
#include "../src/Problem"
#include <iostream>
class X: public S::Problem
{
public: X(bool x,bool y):x(x),y(y) {}
protected: std::vector<bool> representation() const { return std::vector<bool>({x,y}); }
private:
bool x;
bool y;
};
int main()
{
srand(time(NULL));
int lm=5;
S::FeedForwardNetwork net(2,lm,1);
bool x=1;
int prev_err=0;
int err=0;
int l;
int n;
int w;
int pot;
int wei;
int c=0;
std::cout << "\ntest 1 & 1 -" << net.solve(X(1,1))[0];
std::cout << "\ntest 1 & 0 -" << net.solve(X(1,0))[0];
std::cout << "\ntest 0 & 1 - " << net.solve(X(0,1))[0];
std::cout << "\ntest 0 & 0- " << net.solve(X(0,0))[0];
std::cout << "\n---------------------------------------";
do{
if(c%10000 ==1)
{
std::cout << "\nmixed";
srand(time(NULL));
}
err=0;
c++;
l=rand()%2+1;
n=rand()%lm;
w=rand()%2;
if(l==2)
n=0;
pot=net[l]->operator[](n)->getPotential();
net[l]->operator[](n)->setPotential(pot*(rand()%21+90)/100);
wei=net[l]->operator[](n)->getWeight(w);
net[l]->operator[](n)->setWeight(w,wei*(rand()%21+90)/100);
for(int i=0;i<100;i++)
{
bool x= rand()%2;
bool y=rand()%2;
S::Solution s =net.solve(X(x,y));
if(s[0]!= (x xor y))
err++;
}
if(err > prev_err)
{
net[l]->operator[](n)->setPotential(pot);
net[l]->operator[](n)->setWeight(w,wei);
};
// std::cout << "C: " << c << " err: " << err << " prev: "<<prev_err << "\n";
prev_err=err;
if(err <1)
x=0;
}while(x);
std::cout << "\ntest 1 & 1 -" << net.solve(X(1,1))[0];
std::cout << "\ntest 1 & 0 -" << net.solve(X(1,0))[0];
std::cout << "\ntest 0 & 1 - " << net.solve(X(0,1))[0];
std::cout << "\ntest 0 & 0- " << net.solve(X(0,0))[0];
std::cout << "\nTotaly: " << c << "\n";
}

17
tests/Makefile Normal file
View File

@@ -0,0 +1,17 @@
include ../Makefile.const
LIB_DIR = ..
ALL_TESTS=01 02 03
CXXFLAGS += -I$(LIB_DIR)
all:| lib $(ALL_TESTS);
test: all
@for i in $(ALL_TESTS); do echo -n ./$$i; echo -n " - "; ./$$i; echo ""; done
%: %.cpp $(LIB_DIR)/$(LIBNAME).a
$(CXX) $(CXXFLAGS) -o $@ $< $ $(LIB_DIR)/$(LIBNAME).a -lm
lib:
make -C ../