public ChordChainGeneticFunction(
            DiscreteNeuralNetworkByChord dnn,
            NGramGraphMarkovChain <Chord> chord,
            INGramWeightAssigner <Chord> assigner,
            ChordRandomFunctionType type = ChordRandomFunctionType.NoRandomSelection,
            ChordCrossFunctionType cross = ChordCrossFunctionType.DiscreteChoice)
        {
            dnn.NullCheck();
            chord.NullCheck();
            assigner.NullCheck();

            this.NeuralNetwork      = dnn;
            this.NGramGraph         = chord;
            this.RandomFunctionType = type;
            this.CrossFunctionType  = cross;
            this.ChordDepth         = this.NeuralNetwork.InputsCount * 2;
            this.NGramDepth         = 10;
            this.MutateCoefficient  = 0.05D;
            this.Assigner           = assigner;

            this.random = new Random();

            switch (type)
            {
            case ChordRandomFunctionType.AllowRandomSelection:
                this.RandomSelectionCoefficient = .05D;
                return;
            }
        }
        public NGramBaseRandomGraphWalker(INGramWeightAssigner <T> assighner)
        {
            assighner.NullCheck();

            this.WeightAssigner = assighner;
            this.Depth          = 3;
        }
        private async void startMusicGeneration_Click(object sender, EventArgs e)
        {
            this.model = TemperaryVariables.Graph;
            if (null == this.model || null == this.neuralNetwork)
            {
                MessageBox.Show("Load neccessary files");
            }
            INGramWeightAssigner <Chord> assi = null;

            if (this.useWeightAssignerCheckBox.Checked)
            {
                NGramLinearSizeVsTimeWeightAssigner <Chord> sizetime = new NGramLinearSizeVsTimeWeightAssigner <Chord>(1F);
                NGramLinearSizeDistrubutionAssigner <Chord> size     = new NGramLinearSizeDistrubutionAssigner <Chord>(this.model);

                Dictionary <INGramWeightAssigner <Chord>, float> dic = new Dictionary <INGramWeightAssigner <Chord>, float>()
                {
                    { sizetime, this.sizeVsWeightAssigner.Value / 100F },
                    { size, this.countDistAssigner.Value / 100F }
                };
                assi = new NGramMetaWeightAssigner <Chord>(dic);
            }
            else
            {
                assi = new NGramIDWeightAssigner <Chord>(this.model);
            }
            this.trainingThread = new Thread(this.GeneticSearch);
            this.trainingThread.Start(assi);
        }
        public IReadOnlyCollection <NGram <Chord>[]> Themes(INGramWeightAssigner <Chord> assigner)
        {
            NGramGraphChainRetriever <Chord> mostProbable = new NGramGraphChainRetriever <Chord>(this.MarkovGraph);

            var chains = mostProbable.FromEachNodeRandom(assigner, this.WalkerDepth, 3);


            //KMeans<NGram<Chord>> cluster = new KMeans<NGram<Chord>>(chains.ToArray(), new LevenshteinDistance<NGram<Chord>>(), 500);
            //cluster.RunFrames(2);

            DiscreteNeuralNetworkByChord teacher = DiscreteNeuralNetworkByChord.Load(@"C:\Users\armen_000\Documents\Visual Studio 2013\Projects\Improvisation\Improvisation\bin\Debug\Learning\eminemNN.txt");

            ChordChainGeneticFunction function = new ChordChainGeneticFunction(
                teacher,
                this.MarkovGraph,
                assigner,
                ChordChainGeneticFunction.ChordRandomFunctionType.AllowRandomSelection,
                ChordChainGeneticFunction.ChordCrossFunctionType.DiscreteChoice)
            {
                RandomSelectionCoefficient = 0.3D
            };

            GeneticAlgorithm <NGram <Chord>[]> genetic = new GeneticAlgorithm <NGram <Chord>[]>(
                function,
                new GeneticSettings(0.1F, 0.05f, 5000, GeneticSettings.OrderOfEvolution.MutateCrossover),
                chains.Take(500));

            for (int i = 0; i < 3; i++)
            {
                try
                {
                    var l = genetic.SingleEvolutionaryCycle();
                }
                catch (Exception e)
                {
                    continue;
                }

                // KMeans<NGram<Chord>> chords = new KMeans<NGram<Chord>>(
                // genetic.CurrentPopulation.Select(x => x.Value).RandomValues(1000),
                // new GaussianNoiseDistance<NGram<Chord>>(new ChordHammingDistance(), 010F), 1000);

                // chords.RunFrames(3);
                // genetic.SubstitutePopulation(chords.Centers);
            }

            return(genetic.ToList().AsReadOnly());
        }
        private NGram <T>[] NodeRandom(INGramWeightAssigner <T> assigner, NGram <T> nGram, int depth)
        {
            List <NGram <T> > ret = new List <NGram <T> >(depth);

            ret.Add(nGram);
            if (depth <= 0)
            {
                return(ret.ToArray());
            }
            else
            {
                var assign = assigner.NextPossibleStateAssignment(nGram.AsEnumerableObject().ToArray(), this.graph);
                if (!assign.Any())
                {
                    return(ret.ToArray());
                }
                ret.AddRange(this.NodeRandom(assigner, assign.PickRandomFromProbabilityDistrubutionsSafe(), --depth));

                return(ret.ToArray());
            }
        }
        public List <NGram <T>[]> FromEachNodeRandom(INGramWeightAssigner <T> assigner, int depth, int perNode)
        {
            ConcurrentBag <NGram <T>[]> ret = new ConcurrentBag <NGram <T>[]>();

            Parallel.ForEach(this.graph, (item, breaka) =>
            {
                if (ret.Count < this.Max)
                {
                    for (int i = 0; i < perNode; i++)
                    {
                        ret.Add(this.NodeRandom(assigner, item.Key, depth));
                    }
                }
                else
                {
                    breaka.Break();
                }
            });

            return(ret.ToList());
        }
 public List <NGram <T>[]> FromEachNodeRandom(INGramWeightAssigner <T> assigner, int depth)
 {
     return(this.FromEachNodeRandom(assigner, depth, 1));
 }