/// <summary> /// Find a group element strictly in the given range, close to the given size. /// </summary> /// <param name="gapMin"></param> /// <param name="gapMax"></param> /// <param name="sizeRHS"></param> /// <returns></returns> private GroupElement FindGroupElementInRange(int min, int max, int size) { if (size == 1) { // return a measure int n = Utilities.rand.Next(min, max + 1); return(workspace.measures[n]); } if (workspace.groups.Count == 0) { return(null); } List <Utilities.ObjectValuePair> pairs = new List <Utilities.ObjectValuePair>(); foreach (Group group in workspace.groups) { if (group.MinLocation < min || group.MaxLocation > max) { continue; } double sizeScore = Math.Max(0, 1.0 - Math.Abs(group.LengthInMeasures - size) / (double)size); Utilities.ObjectValuePair pair = new Utilities.ObjectValuePair(group, sizeScore); pairs.Add(pair); } return((Group)Utilities.PickItemWeighted(pairs)); }
public override void Run() { double weight; if (group == null) { // Pick the *largest* group ending in the final measure and expect it to repeat, // with probability based on group strength and hierarchy strength. List <Utilities.ObjectValuePair> pairs = new List <Utilities.ObjectValuePair>(); foreach (Group g in workspace.groups) { // Skip groups that don't end on the final measure. if (g.MaxLocation != workspace.MaxLocation) { continue; // TODO test } double grpWeight = ComputeWeight(g); Utilities.ObjectValuePair pair = new Utilities.ObjectValuePair(g, grpWeight); pairs.Add(pair); } //Utilities.ObjectValuePair p = Utilities.PickItemWeightedReturnPair(pairs); Utilities.ObjectValuePair p = Utilities.PickLargestItemReturnPair(pairs); group = (Group)p.obj; weight = p.value; } else { if (!workspace.groups.Contains(group)) { return; } weight = ComputeWeight(group); } if (group == null) { return; } // We have an existing group. Try to make an expectation. // Note: It will have to compete with other existing expectations (handle hierarchy differences) int offset = workspace.MaxLocation + 1 - group.MinLocation; workspace.expectations.GenerateExpectedGroupBasedOn(group, offset, true); // Add to attention history. workspace.RecordCodeletAttentionHistory(this, group.MinLocation, group.MaxLocation); workspace.RecordCodeletAttentionHistory(this, group.MinLocation + offset, group.MaxLocation + offset); }
private Relationship FightItOut(List <Relationship> fighting) { List <Utilities.ObjectValuePair> pairs = new List <Utilities.ObjectValuePair>(); for (int i = 0; i < fighting.Count; i++) { Relationship r = fighting[i]; Utilities.ObjectValuePair pair = new Utilities.ObjectValuePair(r, r.Strength); pairs.Add(pair); } return((Relationship)Utilities.PickItemWeighted(pairs)); }
internal int GetARandomConcept() { // Do roulette wheel selection on concepts based on activation. //return Utilities.rand.Next(nodes.Count); List <Utilities.ObjectValuePair> pairs = new List <Utilities.ObjectValuePair>(); foreach (ConceptNode node in nodes) { Utilities.ObjectValuePair pair = new Utilities.ObjectValuePair(node, Math.Max(5, node.Activation)); pairs.Add(pair); } return(((ConceptNode)Utilities.PickItemWeighted(pairs)).Id); }
/// <summary> /// Returns a random analogy from the collection. /// Weights it by win/loss stats /// </summary> /// <returns></returns> public Analogy PickAnalogy() { if (analogies.Count == 0) { return(null); } List <Utilities.ObjectValuePair> pairs = new List <Utilities.ObjectValuePair>(); for (int i = 0; i < analogies.Count; i++) { Analogy a = analogies[i]; Utilities.ObjectValuePair pair = new Utilities.ObjectValuePair(analogies[i], analogyCompetitionStats[a].PercentWins); pairs.Add(pair); } return((Analogy)Utilities.PickItemWeighted(pairs)); }
/// <summary> /// Finds a Group Element near the given starting location, with an absolute maximum, and approx desired size. /// </summary> /// <param name="startPoint"></param> /// <param name="max"></param> /// <param name="size"></param> /// <returns></returns> private GroupElement FindGroupElementStartingNearPointWithMax(int startPoint, int max, int size) { if (startPoint < 0) { startPoint = 0; } if (size == 1) { // return a measure if (startPoint <= workspace.MaxLocation) { return(workspace.measures[startPoint]); } else { return(null); } } if (workspace.groups.Count == 0) { return(null); } List <Utilities.ObjectValuePair> pairs = new List <Utilities.ObjectValuePair>(); foreach (Group group in workspace.groups) { if (group.MaxLocation > max) { continue; } double sizeScore = Math.Max(0, 1.0 - Math.Abs(group.LengthInMeasures - size) / (double)size); double locScore = Math.Max(0, 1.0 - Math.Abs(group.MinLocation - startPoint) / (double)size); Utilities.ObjectValuePair pair = new Utilities.ObjectValuePair(group, sizeScore * locScore); pairs.Add(pair); } return((Group)Utilities.PickItemWeighted(pairs)); }
public override void Run() { if (e == null) { e = workspace.PickRandomGroupElementByRecency(); } if (e == null) { return; } if (!workspace.GroupElements.Contains(e)) { return; } // Add to attention history. workspace.RecordCodeletAttentionHistory(this, e.MinLocation, e.MaxLocation); // Find previous elements linking to this object. if (e is Measure) { Measure m = (Measure)e; // Special case: measure 1. Just call it "a". if (m.number == 0) { // TryToSetMeasureLabel(m, DEFAULT_LABEL_STRENGTH, workspace.GetNextFormLabel(0)); m.FormLabel = "a"; m.FormLabelStrength = 100; return; } // Find previous measures linking to this measure. List <Utilities.ObjectValuePair> pairs = new List <Utilities.ObjectValuePair>(); for (int i = 0; i < m.number; i++) { Measure m2 = workspace.measures[i]; // Find links. foreach (MeasureLink link in workspace.measureLinks) // TODO: speed up link lookup. { if ((link.m1 == m && link.m2 == m2) || link.m1 == m2 && link.m2 == m) { // If there is a 100% strength link, just use it and copy the label. if (link.strength > 99.999) { TryToSetMeasureLabel(m, 100, m2.FormLabel); return; } // Match. Utilities.ObjectValuePair pair = new Utilities.ObjectValuePair(link, link.strength); pairs.Add(pair); } } // If pairs is empty, try to make a new label of default strength, and quit. // If a label exists, we fight. if (pairs.Count == 0) { TryToMakeNewMeasureLabel(m, DEFAULT_LABEL_STRENGTH); return; } // Pick a link probabilistically based on weights. MeasureLink selectedLink = (MeasureLink)Utilities.PickItemWeighted(pairs); float similarity = m.ComputeRhythmicSimilarity(m2); if (similarity > 99.9) { // Use same label. TryToSetMeasureLabel(m, 100, m2.FormLabel); return; } // Decide whether or not to try to add label based on this link, probabilitically. double r = Utilities.rand.NextDouble() * 100; if (selectedLink.strength > 75 && r < selectedLink.strength) { // We're going to try to label. Should it be a duplicate of the former label or a "prime" version" or compeltely new? // If it's a different measure at all, don't use the origianl label. If it's different, decide based on strength of link whether to make ' version. // Make a prime version. MakeLinkedMeasureLabel(m, selectedLink); return; } else { //Link was too weak; just assign a new label. TryToMakeNewMeasureLabel(m, DEFAULT_LABEL_STRENGTH); //return; } } } else { // Group case. } }
public override void Run() { if (e == null) { // For now, just pick groups, not measures. //e = workspace.PickRandomGroupElementByRecency(); e = workspace.PickRandomGroupElementByRecency(); } if (e == null) { return; } if (!workspace.GroupElements.Contains(e)) { return; } // Only look at 1-4 measure long groups. if (e.LengthInMeasures < 1 || e.LengthInMeasures > 4) { return; } // Add to attention history. workspace.RecordCodeletAttentionHistory(this, e.MinLocation, e.MaxLocation); // Generate possible alphabets and scores. List <Tuple <Alphabet, float> > alphabets = e.GetAlphabetsWithLikelihoods(); // TODO: transition probs. // Is there an alphabet in the previous group? float[] transitionProbs = new float[alphabets.Count]; GroupElement ePrev = workspace.GetPreviousGroupElement(e); Alphabet aPrev = null; if (ePrev != null) { aPrev = ePrev.Alphabet; } if (aPrev == null) { // No previous alphabet. for (int i = 0; i < alphabets.Count; i++) { transitionProbs[i] = 1.0f; } } else { // Previous alphabet known. for (int i = 0; i < alphabets.Count; i++) { float prob = 1.0f; Alphabet a = alphabets[i].Item1; // Estimate transition probability. Weights dont' have to sum to 1. int diff = ((aPrev.RootPitchClass + 24) - a.RootPitchClass) % 12; if (diff == 0) { prob = 1.5f; // self transition is tricky. } else if (diff == 7) { prob = 3.0f; } else if (aPrev.RootScaleDegree.Number == 4 && a.RootScaleDegree.Number == 5) { prob = 3.0f; } else if (aPrev.RootScaleDegree.Number == 5 && a.RootScaleDegree.Number == 1) { prob = 5.0f; } else if ((aPrev.RootScaleDegree.Number + 7 - a.RootScaleDegree.Number) % 7 == 2) { prob = 2.0f; } transitionProbs[i] = prob; } } // Is there an alphabet already? Alphabet existing = e.Alphabet; if (existing == null) { // Multiply by transition probabilities from previous group. List <Utilities.ObjectValuePair> pairs = ConvertTupleListToPairsAndMultiplyByWeights(alphabets, transitionProbs); // Pick one! Utilities.ObjectValuePair pair = Utilities.PickItemWeightedReturnPair(pairs); e.Alphabet = (Alphabet)pair.obj; e.AlphabetStrength = pair.value; return; } // An alphabet already exists. Need to compeete. Also, take into account previous measure alphabet and transition probability. Utilities.ObjectValuePair choice = Utilities.PickItemWeightedReturnPair(ConvertTupleListToPairsAndMultiplyByWeights(alphabets, transitionProbs)); if (Utilities.FightItOut(choice.value, e.AlphabetStrength, workspace.Temperature)) { // The new alphabet won. Replace. e.Alphabet = (Alphabet)choice.obj; e.AlphabetStrength = choice.value; } }
public override void Run() { double weight; if (group == null) { // Pick the *largest* group ending in the final measure and expect it to repeat, // with probability based on group strength and hierarchy strength. List <Utilities.ObjectValuePair> pairs = new List <Utilities.ObjectValuePair>(); foreach (Group g in workspace.groups) { // Skip groups that don't end on the final measure. if (g.MaxLocation != workspace.MaxLocation) { continue; // TODO test } double grpWeight = ComputeWeight(g); Utilities.ObjectValuePair pair = new Utilities.ObjectValuePair(g, grpWeight); pairs.Add(pair); } //Utilities.ObjectValuePair p = Utilities.PickItemWeightedReturnPair(pairs); Utilities.ObjectValuePair p = Utilities.PickLargestItemReturnPair(pairs); group = (Group)p.obj; weight = p.value; } else { if (!workspace.groups.Contains(group)) { return; } weight = ComputeWeight(group); } if (group == null) { return; } // We have an existing group. Try to make an expectation. // Note: It will have to compete with other existing expectations (handle hierarchy differences) int startExpectationLocation = workspace.MaxLocation + 1; int offset = startExpectationLocation - group.MinLocation; // TODO expectation strength is higher for stronger groups, for now. // Set the max strength to be the group strength. // Decrease strength below this amount for non-well-placed groups with respect to barlines float expectationStrength = (float)group.ComputeStrength(); // Find the length of the group, and find the typical length of a group starting/ending at the barline we're starting on in the expectation. int groupLength = group.LengthInMeasures; // Don't generate expectations if we dont' have barlines in place yet. if (startExpectationLocation >= workspace.barlines.Count) { return; } int barlineHeight = workspace.barlines[startExpectationLocation]; int[] barlineDistances = workspace.FindPreviousBarlineDistances(startExpectationLocation); // Fails if barlines don't all exist yet. if (barlineDistances == null) { return; } // Find the distance closest to an existing distance. int min = Int32.MaxValue; int argmin = -1; for (int h = 0; h < barlineDistances.Length; h++) { // Ignore "-1" (unused heights) if (barlineDistances[h] == -1) { continue; } int dist = Math.Abs(barlineDistances[h] - groupLength); if (dist < min) { min = dist; argmin = h; } } int expectedHeight = argmin; // Penalize if the barline is too short for this group length. if (barlineHeight < expectedHeight) { expectationStrength *= 0.7f; } // Penalize if the group length is a weird number. if (min > 0) { expectationStrength *= (0.7f * ((float)min / barlineDistances[argmin])); } ExpectedGroup expectedGroup = workspace.expectations.GenerateExpectedGroupBasedOn(group, offset, expectationStrength, true); if (expectedGroup != null) { // Also make a large-scale analogy between the group and the expected groups. workspace.expectations.MakeNewExpectedAnalogy(group, expectedGroup, expectationStrength, group.Level + 1); // And add supporting analogies between the top-level components of the group and expected group. for (int i = 0; i < group.GroupElements.Count; i++) { if (group.GroupElements[i] is Group) { Group subgroup = (Group)group.GroupElements[i]; int startLocation = subgroup.MinLocation; int endLocation = subgroup.MaxLocation; // Find expected subgroup for this subgroup. // Note: we can't assume expected groups have elements; they just contain a start and endpoint. So we have to search. ExpectedGroup expectedSubgroup = null; foreach (ExpectedGroup eg in workspace.expectations.groups) { if (eg.MinLocation == startLocation + offset && eg.MaxLocation == endLocation + offset) { expectedSubgroup = eg; break; } } if (expectedSubgroup != null) { workspace.expectations.MakeNewExpectedAnalogy(subgroup, expectedSubgroup, expectationStrength, subgroup.Level + 1); } } } // Now, add expected within-future analogies and links, simply copies of existing analogies and relationships, shifted by offset. // Search for all analogies and relationships which take place within the timespan of the original group. // Links. foreach (Relationship rel in workspace.relationships) { // Skip relationships between non-measures for now. if (!(rel.LHS is Measure && rel.RHS is Measure)) { continue; } int idx1 = rel.LHS.Location; int idx2 = rel.RHS.Location; if (group.IncludesLocation(idx1) && group.IncludesLocation(idx2)) { workspace.expectations.MakeNewExpectedMeasureLink(idx1, idx2, offset, rel.Strength); } } // Analogies. foreach (Analogy analogy in workspace.analogies) { int idxLHS1 = analogy.LHS.MinLocation; int idxLHS2 = analogy.LHS.MaxLocation; int idxRHS1 = analogy.RHS.MinLocation; int idxRHS2 = analogy.RHS.MaxLocation; if (group.IncludesLocation(idxLHS1) && group.IncludesLocation(idxLHS2) && group.IncludesLocation(idxRHS1) && group.IncludesLocation(idxRHS2)) { // Find the future LHS and RHS groups. We have to search for each. ExpectedGroup futureLHS = null, futureRHS = null; foreach (ExpectedGroup eg in workspace.expectations.groups) { if (eg.MinLocation == idxLHS1 + offset && eg.MaxLocation == idxLHS2 + offset) { futureLHS = eg; } else if (eg.MinLocation == idxRHS1 + offset && eg.MaxLocation == idxRHS2 + offset) { futureRHS = eg; } if (futureLHS != null && futureRHS != null) { break; } } if (futureLHS != null && futureRHS != null) { workspace.expectations.MakeNewExpectedAnalogy(futureLHS, futureRHS, analogy.Strength, analogy.Level); } } } } // Add to attention history. workspace.RecordCodeletAttentionHistory(this, group.MinLocation, group.MaxLocation); workspace.RecordCodeletAttentionHistory(this, group.MinLocation + offset, group.MaxLocation + offset); }