public TWEANNGenotype(TWEANN tweann) { numInputs = tweann.NumInputs(); numOutputs = tweann.NumOutputs(); archetypeIndex = tweann.ArchetypeIndex; ID = EvolutionaryHistory.NextGenotypeID(); Links = new List <LinkGene>(); Nodes = new List <NodeGene>(tweann.GetNodes().Count); List <TWEANNNode> tweannNodeList = tweann.GetNodes(); for (int i = 0; i < tweann.GetNodes().Count; i++) { NodeGene ng = new NodeGene(tweannNodeList[i].GetNType(), tweannNodeList[i].GetFType(), tweannNodeList[i].GetInnovation()); Nodes.Add(ng); List <LinkGene> tempLinks = new List <LinkGene>(); foreach (TWEANNLink l in tweannNodeList[i].GetOutputs()) { LinkGene lg = new LinkGene(tweannNodeList[i].GetInnovation(), l.GetTarget().GetInnovation(), l.GetWeight(), l.GetInnovation()); tempLinks.Add(lg); } for (int j = 0; j < tempLinks.Count; j++) { Links.Add(tempLinks[j]); } } }
public void PerturbLink(LinkGene lg, float delta) { if (ArtGallery.DEBUG_LEVEL > ArtGallery.DEBUG.NONE) { Debug.Log("Perturbing link: " + lg.Innovation + " by " + delta); } lg.SetWeight(lg.GetWeight() + delta); // TODO PerturbLink(LinkGene lg, float delta) - Do we want the weight to be bounded in any way? }
public void AddLink(long sourceInnovation, long targetInnovation, float weight, long innovation) { if (GetLinkBetween(sourceInnovation, targetInnovation) == null) { // TODO indexOfNodeinnovation(long innovation), but this is for recurrence //int target = IndexOfNodeInnovation(targetInnovation); //int source = IndexOfNodeInnovation(sourceInnovation); LinkGene lg = new LinkGene(sourceInnovation, targetInnovation, weight, innovation /*, target <= source*/); Links.Add(lg); } }
private void CrossIndexLinks(LinkGene leftGene, LinkGene rightGene, List <LinkGene> crossedLeft, List <LinkGene> crossedRight) { bool swap = RandomGenerator.NextBool();; if (swap) { Pair <LinkGene, LinkGene> p = SwapLinks(leftGene, rightGene); leftGene = p.t1; rightGene = p.t2; } crossedLeft.Add(leftGene); crossedRight.Add(rightGene); }
private List <List <LinkGene> > CrossLinks(List <LinkGene> left, List <LinkGene> right) { if (left.Count != right.Count) { throw new Exception("Cannot cross lists of different sizes!"); } List <LinkGene> crossedLeft = new List <LinkGene>(left.Count); List <LinkGene> crossedRight = new List <LinkGene>(right.Count); for (int i = 0; i < left.Count; i++) { LinkGene leftGene = left[i]; LinkGene rightGene = right[i]; if (leftGene != null && rightGene != null) { CrossIndexLinks((LinkGene)leftGene.CopyGene(), (LinkGene)rightGene.CopyGene(), crossedLeft, crossedRight); } else { if (leftGene != null) { crossedLeft.Add((LinkGene)leftGene.CopyGene()); if (includeExcess) { crossedRight.Add((LinkGene)leftGene.CopyGene()); } } if (rightGene != null) { crossedRight.Add((LinkGene)rightGene.CopyGene()); if (includeExcess) { crossedLeft.Add((LinkGene)rightGene.CopyGene()); } } } } List <List <LinkGene> > pair = new List <List <LinkGene> >(2) { crossedLeft, crossedRight }; return(pair); }
public LinkGene GetLinkBetween(long sourceInnovation, long targetInnovation) { LinkGene result = null; if (Links == null) { throw new System.Exception("links is null"); } foreach (LinkGene lg in Links) { if (lg.GetSourceInnovation() == sourceInnovation && lg.GetTargetInnovation() == targetInnovation) { result = lg; } } return(result); }
private void SpliceMutation(FTYPE fType) // TODO add a factor to change the weights impact (maybe a single factor or one for each weight) { LinkGene lg = GetLinkByInnovationID(GetRandomLinkInnovation()); long sourceInnovation = lg.GetSourceInnovation(); long targetInnovation = lg.GetTargetInnovation(); long newNode = EvolutionaryHistory.NextInnovationID(); float weight1 = RandomGenerator.NextGaussian(); float weight2 = RandomGenerator.NextGaussian(); long toLink = EvolutionaryHistory.NextInnovationID(); long fromLink = EvolutionaryHistory.NextInnovationID(); string debugMsg = "SpliceMutation between " + sourceInnovation + " and " + targetInnovation + ". Adding a node with an innovation of " + newNode + " and an activation function of " + fType; if (ArtGallery.DEBUG_LEVEL > ArtGallery.DEBUG.NONE) { Debug.Log(debugMsg); } SpliceNode(fType, newNode, sourceInnovation, targetInnovation, weight1, weight2, toLink, fromLink); }
public LinkGene GetLinkByInnovationID(long innovation) { LinkGene result = null; bool found = false; foreach (LinkGene lg in Links) { if (lg.Innovation == innovation) { result = lg; found = true; break; } } if (!found) { throw new System.ArgumentException("Link innovation not found: " + innovation); } return(result); }
public void SpliceNode(FTYPE fType, long newNodeInnovation, long sourceInnovation, long targetInnovation, float weight1, float weight2, long toLinkInnovation, long fromLinkInnovation) { NodeGene ng = new NodeGene(NTYPE.HIDDEN, fType, newNodeInnovation); LinkGene lg = GetLinkBetween(sourceInnovation, targetInnovation); //lg.SetActive(false); // TODO active bool is not in use // HACK Links should not be removed when splicing in a new node, but active is not in use yet //links.Remove(lg); // HACK if this fails then it will be because the index is either < 0 or > count - add fixes or write a container w/ helper methods Nodes.Insert(System.Math.Min(OutputStartIndex(), System.Math.Max(numInputs, IndexOfNodeInnovation(sourceInnovation) + 1)), ng); //int index = EvolutionaryHistory.IndexOfArchetypeInnovation(archetypeIndex, sourceInnovation); //int pos = System.Math.Min(EvolutionaryHistory.FirstArchetypeOutputIndex(archetypeIndex), System.Math.Max(numInputs, index + 1)); EvolutionaryHistory.AddArchetype(archetypeIndex, Nodes.IndexOf(ng), ng.Clone(), "origin"); LinkGene toNew = new LinkGene(sourceInnovation, newNodeInnovation, weight1, toLinkInnovation); LinkGene fromNew = new LinkGene(newNodeInnovation, targetInnovation, weight2, fromLinkInnovation); Links.Add(toNew); Links.Add(fromNew); }
private Pair <LinkGene, LinkGene> SwapLinks(LinkGene left, LinkGene right) { return(new Pair <LinkGene, LinkGene>(right, left)); }