示例#1
0
        /// <summary>
        /// Compute the similarity between this contour and the given contour.
        /// </summary>
        /// <param name="mc2"></param>
        /// <returns></returns>
        public float ComputeSimilarity(MelodyContour mc2)
        {
            string strC1  = this.ToStringSimple();
            string strC2  = mc2.ToStringSimple();
            int    lenMax = Math.Max(strC1.Length, strC2.Length);

            if (lenMax == 0)
            {
                return(0);
            }

            int distNormal = Utilities.EditDistance(strC1, strC2);

            string strC2Inverted = InvertContourString(strC2);
            int    distInverted  = Utilities.EditDistance(strC1, strC2Inverted) + Constants.INVERT_CONTOUR_COST;

            int dist = Math.Min(distNormal, distInverted);

            return(100f * (((float)lenMax - dist) / lenMax));
        }
示例#2
0
        public override void Run()
        {
            if (ge1 == null)
            {
                ge1 = workspace.PickRandomGroupElementByRecencyAndStrength();
            }

            if (ge1 == null)
            {
                return;
            }

            // Pick 2 more elements to the right if we can.
            // TODO: be smarter about adjacent picking -- go for same-level/same-size groups?
            GroupElement ge2 = workspace.PickRandomGroupElementRightOf(ge1);

            if (ge2 == null)
            {
                return;
            }

            GroupElement ge3 = workspace.PickRandomGroupElementRightOf(ge2);

            if (ge3 == null)
            {
                return;
            }


            if (!workspace.GroupElements.Contains(ge1) || !workspace.GroupElements.Contains(ge2) || !workspace.GroupElements.Contains(ge3))
            {
                return;
            }

            //Make sure they are both of same level, or we can't group.
            // TODO: relax this appropriately for ge3
            if (ge1.Level != ge2.Level)
            {
                return;
            }
            if (Math.Abs(ge2.Level - ge3.Level) > 1)
            {
                return;
            }

            // Add to attention history.
            workspace.RecordCodeletAttentionHistory(this, ge1.MinLocation, ge3.MaxLocation);

            // Check if sequence already exists!
            foreach (Group g in workspace.groups)
            {
                if (g is Sequence)
                {
                    Sequence s = (Sequence)g;
                    if (s.SequenceElements.Contains(ge1) && s.SequenceElements.Contains(ge2) && s.SequenceElements.Contains(ge3))
                    {
                        return;                         // already exists.
                    }
                }
            }

            // Estimate the sequence's score.
            MelodyContour mc1 = new MelodyContour(ge1);
            MelodyContour mc2 = new MelodyContour(ge2);
            MelodyContour mc3 = new MelodyContour(ge3);

            // Need exact matches for first 2 elements.
            string contourStart = mc1.ToStringSimple();

            if (contourStart != mc2.ToStringSimple())
            {
                return;
            }

            // Need initial match for elements 2 and 3 (in case 3 is longer).
            if (!mc3.ToStringSimple().StartsWith(contourStart))
            {
                return;
            }

            // Strength based on # elements.
            double score = Math.Min(100, contourStart.Length * 30);

            double r = Utilities.rand.NextDouble() * 100;

            if (r < score)
            {
                Sequence s = new Sequence(workspace, ge1, ge2, ge3, score);
                workspace.AddSequence(s, score);                        // TODO: hack: forcing score in.... but should be computed from reasons...
            }
        }
        public override void Run()
        {
            if (ge1 == null)
            {
                ge1 = workspace.PickRandomGroupByStrength();
            }

            if (ge1 == null)
            {
                return;
            }

            if (ge2 == null)
            {
                ge2 = workspace.PickRandomGroupByRecencyAndStrength();
            }

            if (ge2 == null || ge2 == ge1)
            {
                return;
            }

            // Reorder in time if out-of-order. m1 comes first.
            if (ge1.Location > ge2.Location)
            {
                GroupElement tmp = ge1;
                ge1 = ge2;
                ge2 = tmp;
            }

            // Add to attention history.
            workspace.RecordCodeletAttentionHistory(this, ge1.MinLocation, ge1.MaxLocation);
            workspace.RecordCodeletAttentionHistory(this, ge2.MinLocation, ge2.MaxLocation);

            // Compute and compare melody contours.
            //TODO! currently we require groups!
            //if (!(ge1 is Group && ge2 is Group))
            //	return;

            // Make sure contours are non-overlapping!!!
            //Group g1 = (Group)ge1;
            //Group g2 = (Group)ge2;

//			if (g1.Overlaps(g2))
//				return;

            if (ge1.Overlaps(ge2))
            {
                return;
            }

            //MelodyContour mc1 = new MelodyContour(g1);
            //MelodyContour mc2 = new MelodyContour(g2);

            MelodyContour mc1 = new MelodyContour(ge1);
            MelodyContour mc2 = new MelodyContour(ge2);

            ////////////////
            float similarity = mc1.ComputeSimilarity(mc2);

//			if (similarity < 75)
            //			return;

            double r = Utilities.rand.NextDouble() * 100;

            if (r < similarity)
            {
                workspace.AddRelationship(new RelationshipMelodyContour(ge1, ge2, similarity));
            }
        }