summaryrefslogtreecommitdiff
path: root/src/brain/neural_network.cpp
blob: 906119403b3529292fabe0cceb20105a99c74223 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "brain/neural_network.h"
#include "brain/neuron.h"
#include <limits>

NeuralNetwork::NeuralNetwork(std::istream &&networkConfigFile, int numberOfSensors, int numberOfOutputs)
{
    _biasNode = std::make_shared<BiasNode>();
    
    for (int i=0; i<numberOfSensors; ++i)
    {
	_sensors[i] = std::make_shared<Sensor>(i);
    }
    for (int i=0; i<numberOfOutputs; ++i)
    {
	auto output = std::make_shared<Neuron>(i);
	_outputs.push_back(output);
	_neurons[i] = output;
    }

    parseFile(std::move(networkConfigFile));
}

NeuralNetwork::NeuralNetwork(std::istream &&networkConfigFile, std::vector<bool> sensorInitialValues, int numberOfOutputs)
{
    _biasNode = std::make_shared<BiasNode>();
    
    for (unsigned int i=0; i<sensorInitialValues.size(); ++i)
    {
	auto sensor = std::make_shared<Sensor>(i);
	sensor->setActivation(sensorInitialValues[i] ? 1 : 0);
	_sensors[i] = sensor;
    }
    for (int i=0; i<numberOfOutputs; ++i)
    {
	auto output = std::make_shared<Neuron>(i);
	_outputs.push_back(output);
	_neurons[i] = output;
    }

    parseFile(std::move(networkConfigFile));
}

void NeuralNetwork::parseFile(std::istream &&file)
{
    double weight;
    char srcType;
    int srcId;
    int destId;

    while (file.get(srcType) &&
	   file >> srcId &&
	   file.ignore(std::numeric_limits<std::streamsize>::max(), 'n') &&
	   file >> destId &&
	   file >> weight &&
	   file.ignore(std::numeric_limits<std::streamsize>::max(), '\n'))
    {
	
	std::shared_ptr<NeuralNode> source;
	std::shared_ptr<Neuron> destination;
	switch (srcType)
	{
	case 's':
	    source = findOrAddSensor(srcId);
	    break;
	case 'b':
	    source = _biasNode;
	    break;
	default:
	    source = findOrAddNeuron(srcId);
	}
	destination = findOrAddNeuron(destId);
	
	addLink(source, destination, weight);
    }
	 
}

void NeuralNetwork::addLink(std::shared_ptr<NeuralNode> source, std::shared_ptr<Neuron> destination, double weight)
{
    std::unique_ptr<NeuralLink> link(new NeuralLink(source, weight));
    destination->addInput(std::move(link));
}

std::shared_ptr<Sensor> NeuralNetwork::findOrAddSensor(int id)
{
    auto sensor = _sensors[id];
    if (!sensor)
    {
	sensor = std::make_shared<Sensor>(id);
	_sensors[id] = sensor;
    }
    return sensor;
}

std::shared_ptr<Neuron> NeuralNetwork::findOrAddNeuron(int id)
{
    auto neuron = _neurons[id];
    if (!neuron)
    {
	neuron = std::make_shared<Neuron>(id);
	_neurons[id] = neuron;
    }
    return neuron;
}

void NeuralNetwork::setInput(int inputIndex, double activation)
{
    _sensors.at(inputIndex)->setActivation(activation);
}

int NeuralNetwork::findMaxOutputIndex() const
{
    double currentMaxActivation = 0;
    int currentMaxIndex = 0;
    for (unsigned int i=0; i<_outputs.size(); ++i)
    {
	double activation = _outputs[i]->activation();
	if (activation >= currentMaxActivation)
	{
	    currentMaxActivation = activation;
	    currentMaxIndex = i;
	}
    }
    return currentMaxIndex;
}