diff --git a/.gitignore b/.gitignore index f28f2b5..1ec14b6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ AdversarialSearch/Minimax/Main AdversarialSearch/Minimax/Main.dSYM/ cmake-build-debug +cmake-build-release build *.asta *.asta.lock diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d8a7ee..beb581b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ project(AIEngine) set(CMAKE_CXX_STANDARD 14) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/build) add_subdirectory(AdversarialSearch/Minimax) -add_subdirectory(NeuralNetwork/Common) +add_subdirectory(Common) add_subdirectory(NeuralNetwork/Perceptron) add_subdirectory(NeuralNetwork/MLP) +add_subdirectory("Search Heuristic/Genetic Algorithm") diff --git a/NeuralNetwork/Common/CMakeLists.txt b/Common/CMakeLists.txt similarity index 100% rename from NeuralNetwork/Common/CMakeLists.txt rename to Common/CMakeLists.txt diff --git a/NeuralNetwork/Common/Matrix.cpp b/Common/Matrix.cpp similarity index 100% rename from NeuralNetwork/Common/Matrix.cpp rename to Common/Matrix.cpp diff --git a/NeuralNetwork/Common/Matrix.h b/Common/Matrix.h similarity index 100% rename from NeuralNetwork/Common/Matrix.h rename to Common/Matrix.h diff --git a/NeuralNetwork/Common/MatrixTests.cpp b/Common/MatrixTests.cpp similarity index 100% rename from NeuralNetwork/Common/MatrixTests.cpp rename to Common/MatrixTests.cpp diff --git a/Common/Random.cpp b/Common/Random.cpp new file mode 100644 index 0000000..c0f0bdc --- /dev/null +++ b/Common/Random.cpp @@ -0,0 +1,15 @@ +#include +#include + +#include "Random.h" + +unsigned int RandomUtils::GetTime() +{ + const auto currentTime = static_cast(time(nullptr)); + return currentTime; +} + +void RandomUtils::InitSeed(const unsigned int seed) +{ + srand(seed); +} diff --git a/Common/Random.h b/Common/Random.h new file mode 100644 index 0000000..5069ac9 --- /dev/null +++ b/Common/Random.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +namespace RandomUtils +{ + unsigned int GetTime(); + + void InitSeed(unsigned int seed); + + template ::value, TArithmeticType>::type> + TArithmeticType range(const TArithmeticType minValue, const TArithmeticType maxValue) + { + const float randomValue = (std::rand() / (float) RAND_MAX); + const TArithmeticType result = minValue + randomValue * (maxValue - minValue); + return result; + } +} diff --git a/NeuralNetwork/Common/Random.cpp b/NeuralNetwork/Common/Random.cpp deleted file mode 100644 index 69e66fc..0000000 --- a/NeuralNetwork/Common/Random.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -#include "Random.h" - -void random::initRandomSeed() -{ - unsigned int seed = static_cast(time(NULL)); - srand(seed); -} - -float random::range(float a, float b) -{ - float randomValue = ((float) std::rand()) / (float) RAND_MAX; - float difference = b - a; - float result = randomValue * difference; - return a + result; -} diff --git a/NeuralNetwork/Common/Random.h b/NeuralNetwork/Common/Random.h deleted file mode 100644 index fc7a352..0000000 --- a/NeuralNetwork/Common/Random.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef AIENGINE_RANDOM_H -#define AIENGINE_RANDOM_H -namespace random -{ - void initRandomSeed(); - float range(float a, float b); -} -#endif //AIENGINE_RANDOM_H diff --git a/NeuralNetwork/MLP/CMakeLists.txt b/NeuralNetwork/MLP/CMakeLists.txt index 254cb1c..a357e8a 100644 --- a/NeuralNetwork/MLP/CMakeLists.txt +++ b/NeuralNetwork/MLP/CMakeLists.txt @@ -1,7 +1,7 @@ set(FILES ../Common/ActivationFunctions.cpp - ../Common/Random.cpp - ../Common/Matrix.cpp + ../../Common/Random.cpp + ../../Common/Matrix.cpp ../Perceptron/Neuron.cpp ../Perceptron/Perceptron.cpp Layer.cpp diff --git a/NeuralNetwork/MLP/Main.cpp b/NeuralNetwork/MLP/Main.cpp index e1a9d30..f98c6f3 100644 --- a/NeuralNetwork/MLP/Main.cpp +++ b/NeuralNetwork/MLP/Main.cpp @@ -1,6 +1,6 @@ #include #include -#include "../Common/Random.h" +#include "../../Common/Random.h" #include "MLP.h" int propagate(MultiLayerPerceptron& mlp, std::vector inputs, bool printResult) @@ -37,7 +37,7 @@ void loadWeightsFromFile(const char* filePath, MultiLayerPerceptron& mlp) void trainXor2LayersMLP(const char* filePath) { std::cout << "XOR - 2 Layers (2, 1)" << std::endl; - random::initRandomSeed(); + RandomUtils::InitSeed(RandomUtils::GetTime()); std::vector neuronsByLayerArr = std::vector {2,1}; bool isNetworkTrained = false; unsigned long iterations = 0; @@ -65,7 +65,7 @@ void trainXor2LayersMLP(const char* filePath) void trainXor3LayersMLP(const char* filePath) { std::cout << "XOR - 3 Layers (2, 2, 1)" << std::endl; - random::initRandomSeed(); + RandomUtils::InitSeed(RandomUtils::GetTime()); std::vector neuronsByLayerArr = std::vector {2,2,1}; bool isNetworkTrained = false; unsigned long iterations = 0; diff --git a/NeuralNetwork/Perceptron/CMakeLists.txt b/NeuralNetwork/Perceptron/CMakeLists.txt index 39c891e..a8f0b2f 100644 --- a/NeuralNetwork/Perceptron/CMakeLists.txt +++ b/NeuralNetwork/Perceptron/CMakeLists.txt @@ -1,7 +1,7 @@ set(FILES ../Common/ActivationFunctions.cpp - ../Common/Random.cpp - ../Common/Matrix.cpp + ../../Common/Random.cpp + ../../Common/Matrix.cpp Neuron.cpp Perceptron.cpp PerceptronTests.cpp diff --git a/NeuralNetwork/Perceptron/Neuron.h b/NeuralNetwork/Perceptron/Neuron.h index c7afb1f..5065786 100644 --- a/NeuralNetwork/Perceptron/Neuron.h +++ b/NeuralNetwork/Perceptron/Neuron.h @@ -1,7 +1,7 @@ #ifndef NEURALNETWORK_NEURON_H #define NEURALNETWORK_NEURON_H -#include "../Common/Matrix.h" +#include "../../Common/Matrix.h" class Neuron { diff --git a/NeuralNetwork/Perceptron/Perceptron.cpp b/NeuralNetwork/Perceptron/Perceptron.cpp index 76c93e4..3448f77 100644 --- a/NeuralNetwork/Perceptron/Perceptron.cpp +++ b/NeuralNetwork/Perceptron/Perceptron.cpp @@ -1,5 +1,5 @@ #include "Perceptron.h" -#include "../Common/Random.h" +#include "../../Common/Random.h" Perceptron::Perceptron(int weightsLength) { @@ -7,11 +7,11 @@ Perceptron::Perceptron(int weightsLength) auto weights = std::make_unique(1, weightsLength); for (int c = 0; c < weights->getColumns(); ++c) { - float randomValue = random::range(-1.0f, 1.0f); + float randomValue = RandomUtils::range(-1.0f, 1.0f); weights->set(0,c,randomValue); } _neuron->setWeights(*weights); - float randomBias = random::range(-0.1f,0.1f); + float randomBias = RandomUtils::range(-0.1f, 0.1f); _neuron->setBias(randomBias); _activationFunction = noActivation; } diff --git a/NeuralNetwork/Perceptron/PerceptronTests.cpp b/NeuralNetwork/Perceptron/PerceptronTests.cpp index 64bc6e2..f8d58fa 100644 --- a/NeuralNetwork/Perceptron/PerceptronTests.cpp +++ b/NeuralNetwork/Perceptron/PerceptronTests.cpp @@ -1,5 +1,5 @@ #include "Perceptron.h" -#include "../Common/Random.h" +#include "../../Common/Random.h" ///returns the expected output from given inputs float toExpectedOutput(Matrix& inputs) @@ -11,19 +11,19 @@ float toExpectedOutput(Matrix& inputs) return 1.0f; } -///Populate 'matrix' with random inputs in range -500.0/500.0 +///Populate 'matrix' with RandomUtils inputs in range -500.0/500.0 void populateRandomInput(Matrix& matrix) { for (int r = 0; r < matrix.getRows(); ++r) { - float value = random::range(-500.0f, 500.0f); + float value = RandomUtils::range(-500.0f, 500.0f); matrix.set(r,0,value); } } int main(int argc, char* argv[]) { - random::initRandomSeed(); + RandomUtils::InitSeed(RandomUtils::GetTime()); auto perceptron = std::make_unique(2); perceptron->setActivationFunction(sign); int correctGuesses = 0; diff --git a/Search Heuristic/Genetic Algorithm/CMakeLists.txt b/Search Heuristic/Genetic Algorithm/CMakeLists.txt new file mode 100644 index 0000000..a1ae609 --- /dev/null +++ b/Search Heuristic/Genetic Algorithm/CMakeLists.txt @@ -0,0 +1,3 @@ +set(FILES Main.cpp + ../../Common/Random.cpp GeneticAlgorithm.cpp GeneticAlgorithm.h) +add_executable(GeneticAlgorithm ${FILES}) diff --git a/Search Heuristic/Genetic Algorithm/GeneticAlgorithm.cpp b/Search Heuristic/Genetic Algorithm/GeneticAlgorithm.cpp new file mode 100644 index 0000000..334f085 --- /dev/null +++ b/Search Heuristic/Genetic Algorithm/GeneticAlgorithm.cpp @@ -0,0 +1,5 @@ +// +// Created by andrei.schuch on 1/30/2022. +// + +#include "GeneticAlgorithm.h" diff --git a/Search Heuristic/Genetic Algorithm/GeneticAlgorithm.h b/Search Heuristic/Genetic Algorithm/GeneticAlgorithm.h new file mode 100644 index 0000000..536f88a --- /dev/null +++ b/Search Heuristic/Genetic Algorithm/GeneticAlgorithm.h @@ -0,0 +1,39 @@ +#pragma once + +#include "../../Common/Random.h" + +class GeneticAlgorithm +{ +public: + void Crossover(int& lhs, int& rhs, const int index) + { + const int leftMask = 0xffffffff >> index; + const int rightMask = ~leftMask; + + const int newLhs = (lhs & leftMask) | (rhs & rightMask); + const int newRhs = (rhs & leftMask) | (lhs & rightMask); + + lhs = newLhs; + rhs = newRhs; + } + + void Mutate(int& chromossome) + { + for (int i = 0; i < 32; i++) + { + if (RandomUtils::range(0.0, 1.0) > 0.001) continue; + const int geneMask = 1 << i; + + //TODO + } + } + + //void generateInitialPopulation(std::vector& population); + //int getFitnessScore(int& chromosome); + //Order list elements based on fitness score (first == best, last == worst) + //void orderByFitnessScore(std::vector& population); + //void selection(std::vector& population); + //void farrow(std::vector& population); + //void crossover(std::vector& population); + //void mutation(std::vector& population); +}; diff --git a/Search Heuristic/Genetic Algorithm/Main.cpp b/Search Heuristic/Genetic Algorithm/Main.cpp new file mode 100644 index 0000000..fd09732 --- /dev/null +++ b/Search Heuristic/Genetic Algorithm/Main.cpp @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +#include "../../Common/Random.h" +#include "bitset" +#include "GeneticAlgorithm.h" + +// Population { [010], [1100], [1010] } +// -> Chromosome [0001] +// -> Gene [0] + +int main() +{ + RandomUtils::InitSeed(RandomUtils::GetTime()); + /* + * 1. Initial population + * 2. Fitness function + * 3. Selection + * 4. Crossover + * 5. Mutation + */ + + GeneticAlgorithm genericAlgorithm; + int lhs = 0xffff; + int rhs = 0xffff << 16; + + std::cout << std::bitset<32>(lhs) << std::endl; + std::cout << std::bitset<32>(rhs) << std::endl << std::endl; + + genericAlgorithm.Crossover(lhs, rhs, 1); + + std::cout << std::bitset<32>(lhs) << std::endl; + std::cout << std::bitset<32>(rhs) << std::endl; + + return 0; +}