public AnimalData Mate() { //krzyzowanie polega na "konkursie" wynialajacym dwoch rodzicow na jednego osobnika potomnego //osobniki o wiekszym fitness maja wieksza szanse na zostanie wybranym do krzyzowania //losowana jest wartosc pomiedzy minimalna wartoscia z fitness list a maksymalna wartoscia z fitness list //losowany index osobnika dopoki wylosowana wczesniej wartosc nie jest mniejsza od wartosci fitness danego indexu //losowani dwaj rodzice, rozmnazanie jak wczesniej float crossoverPower = 0.5f; AnimalData childData = new AnimalData(); int parent1Index = ChooseParent(); float parent1MGene = _currentGeneration[parent1Index].animalData.mGene; childData.mGene = parent1MGene; int parent2Index = ChooseParent(); float chance; int currentIteration = 0; while (true) { parent2Index = ChooseParent(); float parent2MGene = _currentGeneration[parent2Index].animalData.mGene; //jeden z rodzicow przekazuje mGene currentIteration++; if (parent1MGene != parent2MGene) //jesli to ten sam index to taki sam mGene, dlatego nie trzeba tego sprawdzac { break; } else if (currentIteration >= _matingMaxIterations) { if (parent1Index != parent2Index) { break; } } } AnimalBrain childBrain = new AnimalBrain(); childBrain.DeepCopyFrom(_currentGeneration[parent1Index].animalData.animalBrain); childData.partsMass = MixDictionaries <float>(_currentGeneration[parent1Index].animalData.partsMass, _currentGeneration[parent2Index].animalData.partsMass, crossoverPower); childData.partsScaleMultiplier = MixDictionaries <System.Numerics.Vector3>(_currentGeneration[parent1Index].animalData.partsScaleMultiplier, _currentGeneration[parent2Index].animalData.partsScaleMultiplier, crossoverPower); childData.targetJointsVelocity = MixDictionaries <System.Numerics.Vector3>(_currentGeneration[parent1Index].animalData.targetJointsVelocity, _currentGeneration[parent2Index].animalData.targetJointsVelocity, crossoverPower); childData.limbsPositionMultiplier = MixDictionaries <System.Numerics.Vector3>(_currentGeneration[parent1Index].animalData.limbsPositionMultiplier, _currentGeneration[parent2Index].animalData.limbsPositionMultiplier, crossoverPower); childBrain.mixWeights(_currentGeneration[parent2Index].animalData.animalBrain, crossoverPower); float mutationRate; float physicalMutationRate; if (_ifAdaptive) { physicalMutationRate = childData.physicalMutationRate; mutationRate = childData.weightsMutationRate; } else { physicalMutationRate = _globalPhyscialMutationRate; mutationRate = _globalMutationRate; } for (int i = 0; i < _numberOfWeightsMutations; i++) { chance = Random.Range(0.0f, 1.0f); if (chance < mutationRate) //obsluga mutacji - mutacja obejmuje zmiane indexu genu z losowym innym genem { childBrain.MutateWeights(); } } chance = Random.Range(0.0f, 1.0f); //szanse na mutacje wag i mutacje fizycznych wlasciwosci sa inne if (chance < physicalMutationRate) { childData.MutateData(); } childData.animalBrain = childBrain; return(childData); }