Proper mutation with one parent

This commit is contained in:
Pascal Serrarens 2026-08-13 12:54:11 +02:00
parent 95a63d9f2d
commit 527abb5178
4 changed files with 85 additions and 3 deletions

View File

@ -556,7 +556,7 @@ namespace NanoBrain {
if (_computeOrders == null || _computeOrders.Count == 0) {
_computeOrders = new();
foreach (Nucleus nucleus in this.nuclei)
_computeOrders[nucleus] = TopologicalSort2(nucleus);
_computeOrders[nucleus] = TopologicalSort(nucleus);
}
return _computeOrders;
}
@ -568,7 +568,7 @@ namespace NanoBrain {
this._computeOrders = null;
}
private List<Nucleus> TopologicalSort2(Nucleus startNode) {
private List<Nucleus> TopologicalSort(Nucleus startNode) {
Dictionary<Nucleus, int> inDegree = new();
//HashSet<Nucleus> visited = new();
@ -796,6 +796,36 @@ namespace NanoBrain {
return true;
}
public static bool EqualStructure(Cluster cluster1, Cluster cluster2) {
int n1 = cluster1.nuclei.Count;
int n2 = cluster2.nuclei.Count;
if (n1 != n2)
return false;
for (int i = 0; i < cluster1.nuclei.Count; i++) {
if (EqualStructure(cluster1.nuclei[i], cluster2.nuclei[i]) == false)
return false;
}
return true;
}
public bool CopyWeightsTo(Cluster destination) {
if (EqualStructure(this, destination) == false) {
Debug.LogWarning("Tried to copy weight to a cluster with different structure. Copy is not executed.");
return false;
}
for (int i = 0; i < this.nuclei.Count; i++) {
if (this.nuclei[i] is Neuron thisNeuron &&
destination.nuclei[i] is Neuron destinationNeuron) {
thisNeuron.CopyWeightsTo(destinationNeuron);
}
}
return true;
}
#region Receivers
/// <summary>

View File

@ -300,6 +300,27 @@ namespace NanoBrain {
clone.breakOnUpdate = this.breakOnUpdate;
}
public static bool EqualStructure(Neuron neuron1, Neuron neuron2) {
int synapseCount1 = neuron1.synapses.Count;
int synapseCount2 = neuron2.synapses.Count;
if (synapseCount1 != synapseCount2)
return false;
for (int i = 0; i < synapseCount1; i++) {
if (Synapse.EqualStructure(neuron1.synapses[i], neuron2.synapses[i]) == false)
return false;
}
return true;
}
public void CopyWeightsTo(Neuron destination) {
for (int i = 0; i < this.synapses.Count; i++) {
Synapse thisSynapse = this.synapses[i];
Synapse destinationSynapse = destination.synapses[i];
destinationSynapse.weight = thisSynapse.weight;
}
}
/// <summary>
/// Delete the give neuron
/// </summary>
@ -771,7 +792,7 @@ namespace NanoBrain {
}
}
protected async void ResetStimulus() {
protected void ResetStimulus() {
//Debug.Log("reset stimulus");
this.bias = Vector3.zero;
this.parent?.UpdateFromNucleus(this);

View File

@ -50,6 +50,33 @@ namespace NanoBrain {
#endregion Update
public static bool EqualStructure(Nucleus nucleus1, Nucleus nucleus2) {
if (nucleus1.parent != null && nucleus2.parent != null) {
if (nucleus1.parent.baseName != nucleus2.parent.baseName)
return false;
} else {
// mainly to check one is null, other is not.
if (nucleus1.parent != nucleus2.parent)
return false;
}
if (nucleus1 is Neuron neuron1) {
if (nucleus2 is not Neuron neuron2)
return false;
if (neuron1.name != neuron2.name)
return false;
return Neuron.EqualStructure(neuron1, neuron2);
}
else if (nucleus1 is Cluster cluster1) {
if (nucleus2 is not Cluster cluster2)
return false;
if (cluster1.baseName != cluster2.baseName)
return false;
return Cluster.EqualStructure(cluster1, cluster2);
}
return false;
}
}
}

View File

@ -36,6 +36,10 @@ namespace NanoBrain {
this.weight = weight;
}
public static bool EqualStructure(Synapse synapse1, Synapse synapse2) {
return synapse1.neuron.name == synapse2.neuron.name;
}
public virtual void BackPropagation(Neuron receiver, float derivative, float learningRate) {
switch (receiver.activator) {
case Neuron.ActivationType.Linear: