/// <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));
        }
示例#2
0
        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);
        }
示例#3
0
        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));
        }
示例#4
0
        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);
        }
示例#5
0
        /// <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.
            }
        }
示例#8
0
        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);
        }