예제 #1
0
        private Prefix PickRandomKey(MarkovTable frequencies)
        {
            var candidates = frequencies.Keys
                             .Where(key => char.IsUpper(key.Elements[0][0]))
                             .ToList();
            int    startIndex = RandomInt(0, candidates.Count);
            Prefix current    = candidates.ElementAt(startIndex);

            return(current);
        }
예제 #2
0
 /// <summary>
 /// Given a <see cref="MarkovTable"/> and an initial starting <see cref="Prefix"/>, looks up the
 /// prefix in the MarkovTable to construct a new prefix. This process continues until we reach
 /// the end of the original tokens (if ever!).
 /// </summary>
 private IEnumerable <string> RandomWalk(MarkovTable frequencies, Prefix initial)
 {
     return(EnumerableEx.Generate(
                initialState: initial,
                condition: prefix => !prefix.Elements.All(e => e == null),
                iterate: prefix =>
     {
         string suffix = ChooseRandomSuffix(frequencies, prefix);
         // slide suffix onto old prefix to create new prefix
         var newPrefix = prefix.Elements.Skip(1).Append(suffix).ToArray();
         return new Prefix(newPrefix);
     },
                resultSelector: prefixes => prefixes.Elements.First()
                ));
 }
예제 #3
0
 /// <summary>
 /// Create a new markov generator.
 /// </summary>
 /// <param name="tokens">source sequence of tokens to analyze</param>
 /// <param name="ngramSize">
 ///     The ngram size, i.e. how many consecutive tokens to group by. Larger values
 ///     result in more similarity to the <paramref name="tokens"/> source.
 ///     See https://en.wikipedia.org/wiki/N-gram
 /// </param>
 /// <param name="randomInt">
 ///     A function that produces a random int between two bounds.
 ///     If not provided, <see cref="Random.Next(int, int)"/> is used.
 ///     This parameter is intended to be used mostly in unit testing.
 /// </param>
 public MarkovGenerator(IReadOnlyCollection <string> tokens, int ngramSize, Func <int, int, int> randomInt = null)
 {
     frequencies = BuildMarkovTable(tokens, ngramSize);
     RandomInt   = randomInt ?? new Random().Next;
 }
예제 #4
0
 /// <summary>
 /// Look up the possible suffixes in <paramref name="frequencies"/> for the <paramref name="current"/> prefix.
 /// Each suffix has a weight -- randomly choose one based on the weighting.
 /// </summary>
 /// <returns>a randomly chosen string suffix</returns>
 private string ChooseRandomSuffix(MarkovTable frequencies, Prefix current)
 {
     if (!frequencies.TryGetValue(current, out SuffixFrequency[] nextFrequencies))
        void Add(CompositionCategory category)
        {
            table = new MarkovTable<Note>(ORDER);
            foreach (var c in category.Compositions)
            {
                if (c.Tracks.Count < 2)
                    continue;
                var mainSeq = NormalizeSequence((c.Tracks[0].GetMainSequence() as MelodySequence));

                for (int i = 1; i < c.Tracks.Count; i++)
                {
                    var accompSeq = NormalizeSequence(c.Tracks[i].GetMainSequence() as MelodySequence);
                    if (accompSeq.TotalRestDuration() > accompSeq.TotalNoteDuration())
                        continue;
                    Console.WriteLine("Adding comp {0}:{1}", c.NameTag,i);
                    table.Add(mainSeq.ToArray(), accompSeq.ToArray());
                   // Console.WriteLine("Adding track");
                }

            }
        }