// Добавление связи между включающимся и рассогласованным нейроном - вес связи зависит от типа рассогласования - возвращает добавлена ли связь или просто изменена int AddInterPoolConnection(TNeuron* ActivatedNeuron, TNeuron* MismatchNeuron, int SynapsesQuantity, double WeightValue) { TSynapse* CurrentSynapse = MismatchNeuron->InSynapses; while ((CurrentSynapse != NULL) && (CurrentSynapse->PreNeuron->ID != ActivatedNeuron->ID)) // Пытаемся найти связь между этими нейронами, если она уже есть CurrentSynapse = CurrentSynapse->next; int CreatedSynapseCheck = 0; // Признак того, то мы создали синапс, а не изменили2 if (CurrentSynapse != NULL) // Если такая связь найдена { CurrentSynapse->Enabled = 1; // На всякий случай включаем связь CurrentSynapse->Weight = WeightValue; } else // Иначе создаем связь { CurrentSynapse = MismatchNeuron->InSynapses; if (CurrentSynapse != NULL) { while (CurrentSynapse->next != NULL) CurrentSynapse = CurrentSynapse->next; CurrentSynapse->next = CreateSynapse(SynapsesQuantity+1, WeightValue, 1, ActivatedNeuron, MismatchNeuron, NULL); } else MismatchNeuron->InSynapses = CreateSynapse(SynapsesQuantity+1, WeightValue, 1, ActivatedNeuron, MismatchNeuron, NULL); ++CreatedSynapseCheck; } return CreatedSynapseCheck; }
CStdSerialize *ClassFactory::CreateObject(std::string strClassType, std::string strObjectType, bool bThrowError) { CStdSerialize *lpObject=NULL; strClassType = Std_ToUpper(Std_Trim(strClassType)); if(strClassType == "EXTERNALSTIMULUS") lpObject = CreateExternalStimulus(strObjectType, bThrowError); else if(strClassType == "NEURALMODULE") lpObject = CreateNeuralModule(strObjectType, bThrowError); else if(strClassType == "DATACOLUMN") lpObject = CreateDataColumn(strObjectType, bThrowError); else if(strClassType == "GAIN") lpObject = CreateGain(strObjectType, bThrowError); else if(strClassType == "NEURON") lpObject = CreateNeuron(strObjectType, bThrowError); else if(strClassType == "SYNAPSE") lpObject = CreateSynapse(strObjectType, bThrowError); else if(strClassType == "SYNAPSETYPE") lpObject = CreateSynapseType(strObjectType, bThrowError); else if(strClassType == "IONCHANNEL") lpObject = CreateIonChannel(strObjectType, bThrowError); else { lpObject = NULL; if(bThrowError) THROW_PARAM_ERROR(Std_Err_lInvalidClassType, Std_Err_strInvalidClassType, "ClassType", strClassType); } return lpObject; }
// Процедура линейного системогенеза, которая преобразует сеть из пулов в сеть из нейронов, как будто это одно и тоже (эволюция нейронных сетей, а не пулов) void AgentLinearPrimarySystemogenesis(TNeuralNetwork* PrimaryNetwork, TPoolNetwork* PoolNetwork) { EraseNeuralNetwork(PrimaryNetwork); TNeuralPool* CurrentPool = PoolNetwork->PoolsStructure; TNeuron* CurrentNeuron = PrimaryNetwork->NetworkStructure; int NeuronsQuantity = 0; // Проходим по всем пулам и создаем нейроны while (CurrentPool != NULL) { if (CurrentNeuron == NULL) { PrimaryNetwork->NetworkStructure = CreateNeuron(++NeuronsQuantity, CurrentPool->Type, CurrentPool->BiasMean, CurrentPool->Layer, true, CurrentPool, CurrentPool->ID, NULL, NULL, NULL); CurrentNeuron = PrimaryNetwork->NetworkStructure; } else { CurrentNeuron->next = CreateNeuron(++NeuronsQuantity, CurrentPool->Type, CurrentPool->BiasMean, CurrentPool->Layer, true, CurrentPool, CurrentPool->ID, NULL, NULL, NULL); CurrentNeuron = CurrentNeuron->next; } CurrentPool = CurrentPool->next; } CurrentPool = PoolNetwork->PoolsStructure; CurrentNeuron = PrimaryNetwork->NetworkStructure; int SynapsesQuantity = 0; // Количество синапсов сети int PredConnectionQuantity = 0; // Количество предикторных связей while (CurrentPool != NULL) { // Создаем синапсы TPoolConnection* CurrentConnection = CurrentPool->ConnectednessSet; TSynapse* CurrentSynapse = CurrentNeuron->InSynapses; // Пока мы не прошли все входные связи текущего пула while (CurrentConnection != NULL) { if (CurrentConnection->Enabled) { if (CurrentSynapse == NULL) // Если нет еще ни одного синапса у текущего нейрона { CurrentNeuron->InSynapses = CreateSynapse(++SynapsesQuantity, CurrentConnection->WeightMean, CurrentConnection->Enabled, GetPointer2Neuron(PrimaryNetwork, CurrentConnection->PrePool->ID), CurrentNeuron, NULL); CurrentSynapse = CurrentNeuron->InSynapses; } else { CurrentSynapse->next = CreateSynapse(++SynapsesQuantity, CurrentConnection->WeightMean, CurrentConnection->Enabled, GetPointer2Neuron(PrimaryNetwork, CurrentConnection->PrePool->ID), CurrentNeuron, NULL); CurrentSynapse = CurrentSynapse->next; } } CurrentConnection = CurrentConnection->next; } // Создаем все предикторные связи TPoolPredConnection* CurrentPoolPredConnection = CurrentPool->PredConnectednessSet; TPredConnection* CurrentPredConnection= CurrentNeuron->PredConnections; // Пока мы не прошли все входные связи текущего пула while (CurrentPoolPredConnection != NULL) { if (CurrentPoolPredConnection->Enabled) { if (CurrentPredConnection == NULL) // Если нет еще ни одной связи у текущего нейрона { CurrentNeuron->PredConnections = CreatePredConnection(++PredConnectionQuantity, CurrentPoolPredConnection->Enabled, GetPointer2Neuron(PrimaryNetwork, CurrentPoolPredConnection->PrePool->ID), CurrentNeuron, NULL); CurrentPredConnection = CurrentNeuron->PredConnections; } else { CurrentPredConnection->next = CreatePredConnection(++PredConnectionQuantity, CurrentPoolPredConnection->Enabled, GetPointer2Neuron(PrimaryNetwork, CurrentPoolPredConnection->PrePool->ID), CurrentNeuron, NULL); CurrentPredConnection = CurrentPredConnection->next; } } CurrentPoolPredConnection = CurrentPoolPredConnection->next; } CurrentPool = CurrentPool->next; CurrentNeuron = CurrentNeuron->next; } // Заполняем данные про построенную сеть PrimaryNetwork->NeuronQuantity = NeuronsQuantity; PrimaryNetwork->SynapseQuantity = SynapsesQuantity; PrimaryNetwork->PredConnectionQuantity = PredConnectionQuantity; }
// Построение ПОЛНОЙ (без отбора) первичной нейронной сети из генотипа (структуры пулов) void BuildPrimaryNetwork(TNeuralNetwork* PrimaryNetwork, TPoolNetwork* PoolNetwork, double DevelopSynapseProbability, double DevelopPredConnectionProbability) { int NeuronsQuantity = 0; // Количество нейронов в первичной сети TNeuralPool* CurrentPool= PoolNetwork->PoolsStructure; // Ссылка на текущий пул TNeuron* CurrentNeuron = PrimaryNetwork->NetworkStructure; // Ссылка на текущий нейрон int MaxCapacity = 0; // Максимальная размерность пула // Находим максимальную размерность пула for (int PoolNumber = 0; PoolNumber < PoolNetwork->PoolQuantity; PoolNumber++) { if (CurrentPool->Capacity > MaxCapacity) MaxCapacity = CurrentPool->Capacity; CurrentPool = CurrentPool->next; } // Создаем двумерный массив ссылок на все нейроны первичной сети, разбитых на принадлежность к пулу (чтобы потом их не искать, когда добавляем связи) //printf("%i ", MaxCapacity); //TNeuron* PoolAndNetworkStructure[PoolNetwork->PoolQuantity][MaxCapacity]; TNeuron*** PoolAndNetworkStructure = new TNeuron**[PoolNetwork->PoolQuantity]; for (int i=0; i<PoolNetwork->PoolQuantity; ++i) PoolAndNetworkStructure[i] = new TNeuron*[MaxCapacity]; CurrentPool = PoolNetwork->PoolsStructure; // Проходим по всем пулам и создаем нейроны for (int PoolNumber = 0; PoolNumber < PoolNetwork->PoolQuantity; PoolNumber++) { // Создаем все нейроны пула for (int NeuronNumber = 0; NeuronNumber < CurrentPool->Capacity; NeuronNumber++) { if (CurrentNeuron == NULL) // Если в сети нет еще ни одного нейрона { PrimaryNetwork->NetworkStructure = CreateNeuron(++NeuronsQuantity, CurrentPool->Type, NormalDistribution(CurrentPool->BiasMean, CurrentPool->BiasVariance), CurrentPool->Layer, true, CurrentPool, CurrentPool->ID, NULL, NULL, NULL); CurrentNeuron = PrimaryNetwork->NetworkStructure; } else { CurrentNeuron->next = CreateNeuron(++NeuronsQuantity, CurrentPool->Type, NormalDistribution(CurrentPool->BiasMean, CurrentPool->BiasVariance), CurrentPool->Layer, true, CurrentPool, CurrentPool->ID, NULL, NULL, NULL); CurrentNeuron = CurrentNeuron->next; } PoolAndNetworkStructure[PoolNumber][NeuronNumber] = CurrentNeuron; } CurrentPool = CurrentPool->next; } CurrentPool = PoolNetwork->PoolsStructure; CurrentNeuron = PrimaryNetwork->NetworkStructure; int SynapsesQuantity = 0; // Количество синапсов сети int PredConnectionQuantity = 0; // Количество предикторных связей // Проходимсся по всем пулам и создаем синапсы for (int PoolNumber = 0; PoolNumber < PoolNetwork->PoolQuantity; ++PoolNumber) { for (int NeuronNumber = 0; NeuronNumber < CurrentPool->Capacity; ++NeuronNumber) { // Создаем синапсы TPoolConnection* CurrentConnection = CurrentPool->ConnectednessSet; TSynapse* CurrentSynapse = CurrentNeuron->InSynapses; // Пока мы не прошли все входные связи текущего пула while (CurrentConnection != NULL) { /*// Определяем количество входных связей для текущего нейрона от нейронов пресинаптического пула int CurrentSynapsesQuantity = rand() % 0.2*CurrentConnection->PrePool->Capacity; int PreNeuronNumber[CurrentSynapsesQuantity]; // Номера пресинаптических нейронов из текущего пресинаптического пула GenerateRandomNumbers(1, CurrentConnection->PrePool->Capacity, CurrentSynapsesQuantity, PreNeuronNumber); BubbleSort(PreNeuronNumber, CurrentSynapsesQuantity); for (int i=0; i<CurrentSynapsesQuantity; i++) // Создаем все текущие синапсы { if (CurrentSynapse = NULL) // Если нет еще ни одного синапса у текущего нейрона { CurrentNeuron->InSynapses = CreateSynapse(++SynapsesQuantity, NormalDistribution(CurrentConnection->WeightMean, CurrentConnection->WeightVariance), CurrentConnection->Enabled, PoolAndNetworkStructure[CurrentConnection->PrePool->ID-1][PreNeuronNumber[i]-1], CurrentNeuron, NULL); CurrentSynapse = CurrentNeuron->InSynapses; } else { CurrentSynapse->next = CreateSynapse(++SynapsesQuantity, NormalDistribution(CurrentConnection->WeightMean, CurrentConnection->WeightVariance), CurrentConnection->Enabled, PoolAndNetworkStructure[CurrentConnection->PrePool->ID-1][PreNeuronNumber[i]-1], CurrentNeuron, NULL); CurrentSynapse = CurrentSynapse->next; } }*/ // Проходимся по всем потенциальным пресинаптическим нейронам и определяем развивается ли связь if (CurrentConnection->Enabled) for (int CurrentPreNeuronNumber = 0; CurrentPreNeuronNumber < CurrentConnection->PrePool->Capacity; ++CurrentPreNeuronNumber ) { if (UniformDistribution(0, 1) <= DevelopSynapseProbability) { if (CurrentSynapse == NULL) // Если нет еще ни одного синапса у текущего нейрона { CurrentNeuron->InSynapses = CreateSynapse(++SynapsesQuantity, NormalDistribution(CurrentConnection->WeightMean, CurrentConnection->WeightVariance), CurrentConnection->Enabled, PoolAndNetworkStructure[CurrentConnection->PrePool->ID-1][CurrentPreNeuronNumber], CurrentNeuron, NULL); CurrentSynapse = CurrentNeuron->InSynapses; } else { CurrentSynapse->next = CreateSynapse(++SynapsesQuantity, NormalDistribution(CurrentConnection->WeightMean, CurrentConnection->WeightVariance), CurrentConnection->Enabled, PoolAndNetworkStructure[CurrentConnection->PrePool->ID-1][CurrentPreNeuronNumber], CurrentNeuron, NULL); CurrentSynapse = CurrentSynapse->next; } } } CurrentConnection = CurrentConnection->next; } //Создаем предикторные связи TPoolPredConnection* CurrentPredConnection = CurrentPool->PredConnectednessSet; TPredConnection* CurrentPredSynapse = CurrentNeuron->PredConnections; // Пока мы не прошли все входные предикторные связи текущего пула while (CurrentPredConnection != NULL) { /*// Определяем количество входных предикторных связей для текущего нейрона от нейронов пресинаптического пула int CurrentPredSynapsesQuantity = rand() % 0.2*CurrentPredConnection->PrePool->Capacity; int PreNeuronNumber[CurrentPredSynapsesQuantity]; // Номера пресинаптических нейронов из текущего пресинаптического пула GenerateRandomNumbers(1, CurrentPredConnection->PrePool->Capacity, CurrentPredSynapsesQuantity, PreNeuronNumber); BubbleSort(PreNeuronNumber, CurrentPredSynapsesQuantity); for (int i=0; i<CurrentPredSynapsesQuantity; i++) // Создаем все текущие предикторные связи { if (CurrentPredSynapse = NULL) // Если нет еще ни одной предикторной связи у текущего нейрона { CurrentNeuron->PredConnections = CreatePredConnection(++PredConnectionQuantity, CurrentPredConnection->Enabled, PoolAndNetworkStructure[CurrentPredConnection->PrePool->ID-1][PreNeuronNumber[i]-1], CurrentNeuron, NULL); CurrentPredSynapse = CurrentNeuron->PredConnections; } else { CurrentPredSynapse->next = CreatePredConnection(++PredConnectionQuantity, CurrentPredConnection->Enabled, PoolAndNetworkStructure[CurrentPredConnection->PrePool->ID-1][PreNeuronNumber[i]-1], CurrentNeuron, NULL); CurrentPredSynapse = CurrentPredSynapse->next; } }*/ // Проходимся по всем потенциальным пресинаптическим нейронам для текущей предикторной связи и определяем развивается ли связь if (CurrentPredConnection->Enabled) for (int CurrentPreNeuronNumber = 0; CurrentPreNeuronNumber < CurrentPredConnection->PrePool->Capacity; ++CurrentPreNeuronNumber) { if (UniformDistribution(0, 1) <= DevelopPredConnectionProbability) { if (CurrentPredSynapse == NULL) // Если нет еще ни одного синапса у текущего нейрона { CurrentNeuron->PredConnections = CreatePredConnection(++PredConnectionQuantity, CurrentPredConnection->Enabled, PoolAndNetworkStructure[CurrentPredConnection->PrePool->ID-1][CurrentPreNeuronNumber], CurrentNeuron, NULL); CurrentPredSynapse = CurrentNeuron->PredConnections; } else { CurrentPredSynapse->next = CreatePredConnection(++PredConnectionQuantity, CurrentPredConnection->Enabled, PoolAndNetworkStructure[CurrentPredConnection->PrePool->ID-1][CurrentPreNeuronNumber], CurrentNeuron, NULL); CurrentPredSynapse = CurrentPredSynapse->next; } } } CurrentPredConnection = CurrentPredConnection->next; } CurrentNeuron = CurrentNeuron->next; } CurrentPool = CurrentPool->next; } for (int i=0; i<PoolNetwork->PoolQuantity; ++i) delete [](PoolAndNetworkStructure[i]); delete []PoolAndNetworkStructure; // Заполняем данные про построенную сеть PrimaryNetwork->NeuronQuantity = NeuronsQuantity; PrimaryNetwork->SynapseQuantity = SynapsesQuantity; PrimaryNetwork->PredConnectionQuantity = PredConnectionQuantity; }