예제 #1
0
        public PopulationItem mutate(PopulationItem p)
        {
            var clone = new PopulationItem();

            clone.placements = p.placements.ToArray().ToList();
            clone.Rotation   = p.Rotation.Clone() as float[];
            for (int i = 0; i < clone.placements.Count(); i++)
            {
                var rand = r.NextDouble();
                if (rand < 0.01 * Config.mutationRate)
                {
                    var j = i + 1;
                    if (j < clone.placements.Count)
                    {
                        var temp = clone.placements[i];
                        clone.placements[i] = clone.placements[j];
                        clone.placements[j] = temp;
                    }
                }
                rand = r.NextDouble();
                if (rand < 0.01 * Config.mutationRate)
                {
                    clone.Rotation[i] = (float)Math.Floor(r.NextDouble() * Config.rotations) * (360f / Config.rotations);
                }
            }


            return(clone);
        }
예제 #2
0
        // returns a random individual from the population, weighted to the front of the list (lower fitness value is more likely to be selected)
        public PopulationItem randomWeightedIndividual(PopulationItem exclude = null)
        {
            //var pop = this.population.slice(0);
            var pop = this.population.ToArray();

            if (exclude != null && Array.IndexOf(pop, exclude) >= 0)
            {
                pop.splice(Array.IndexOf(pop, exclude), 1);
            }

            var rand = r.NextDouble();

            float lower  = 0;
            var   weight = 1 / (float)pop.Length;
            float upper  = weight;

            for (var i = 0; i < pop.Length; i++)
            {
                // if the random number falls between lower and upper bounds, select this individual
                if (rand > lower && rand < upper)
                {
                    return(pop[i]);
                }
                lower  = upper;
                upper += 2 * weight * ((pop.Length - i) / (float)pop.Length);
            }

            return(pop[0]);
        }
예제 #3
0
        // single point crossover
        public PopulationItem[] mate(PopulationItem male, PopulationItem female)
        {
            var cutpoint = (int)Math.Round(Math.Min(Math.Max(r.NextDouble(), 0.1), 0.9) * (male.placements.Count - 1));

            var gene1 = new List <NFP>(male.placements.Take(cutpoint).ToArray());
            var rot1  = new List <float>(male.Rotation.Take(cutpoint).ToArray());

            var gene2 = new List <NFP>(female.placements.Take(cutpoint).ToArray());
            var rot2  = new List <float>(female.Rotation.Take(cutpoint).ToArray());

            int i = 0;

            for (i = 0; i < female.placements.Count; i++)
            {
                if (!gene1.Any(z => z.id == female.placements[i].id))
                {
                    gene1.Add(female.placements[i]);
                    rot1.Add(female.Rotation[i]);
                }
            }

            for (i = 0; i < male.placements.Count; i++)
            {
                if (!gene2.Any(z => z.id == male.placements[i].id))
                {
                    gene2.Add(male.placements[i]);
                    rot2.Add(male.Rotation[i]);
                }
            }



            return(new[] { new  PopulationItem()
                           {
                               placements = gene1, Rotation = rot1.ToArray()
                           },
                           new PopulationItem()
                           {
                               placements = gene2, Rotation = rot2.ToArray()
                           } });
        }
예제 #4
0
        public void launchWorkers(NestItem[] parts)
        {
            background.ResponseAction = ResponseProcessor;
            if (ga == null)
            {
                List <NFP> adam = new List <NFP>();
                var        id   = 0;
                for (int i = 0; i < parts.Count(); i++)
                {
                    if (!parts[i].IsSheet)
                    {
                        for (int j = 0; j < parts[i].Quanity; j++)
                        {
                            var poly = cloneTree(parts[i].Polygon); // deep copy
                            poly.id     = id;                       // id is the unique id of all parts that will be nested, including cloned duplicates
                            poly.source = i;                        // source is the id of each unique part from the main part list

                            adam.Add(poly);
                            id++;
                        }
                    }
                }

                adam = adam.OrderByDescending(z => Math.Abs(GeometryUtil.polygonArea(z))).ToList();

                /*List<NFP> shuffle = new List<NFP>();
                 * Random r = new Random(DateTime.Now.Millisecond);
                 * while (adam.Any())
                 * {
                 *  var rr = r.Next(adam.Count);
                 *  shuffle.Add(adam[rr]);
                 *  adam.RemoveAt(rr);
                 * }
                 * adam = shuffle;*/

                /*#region special case
                 * var temp = adam[1];
                 * adam.RemoveAt(1);
                 * adam.Insert(9, temp);
                 *
                 #endregion*/
                ga = new GeneticAlgorithm(adam.ToArray(), Config);
            }
            individual = null;

            // check if current generation is finished
            var finished = true;

            for (int i = 0; i < ga.population.Count; i++)
            {
                if (ga.population[i].fitness == null)
                {
                    finished = false;
                    break;
                }
            }
            if (finished)
            {
                //console.log('new generation!');
                // all individuals have been evaluated, start next generation
                ga.generation();
            }

            var running = ga.population.Where((p) =>
            {
                return(p.processing != null);
            }).Count();

            List <NFP>         sheets        = new List <NFP>();
            List <int>         sheetids      = new List <int>();
            List <int>         sheetsources  = new List <int>();
            List <List <NFP> > sheetchildren = new List <List <NFP> >();
            var sid = 0;

            for (int i = 0; i < parts.Count(); i++)
            {
                if (parts[i].IsSheet)
                {
                    var poly = parts[i].Polygon;
                    for (int j = 0; j < parts[i].Quanity; j++)
                    {
                        var cln = cloneTree(poly);
                        cln.id     = sid;         // id is the unique id of all parts that will be nested, including cloned duplicates
                        cln.source = poly.source; // source is the id of each unique part from the main part list

                        sheets.Add(cln);
                        sheetids.Add(sid);
                        sheetsources.Add(i);
                        sheetchildren.Add(poly.children);
                        sid++;
                    }
                }
            }
            for (int i = 0; i < ga.population.Count; i++)
            {
                //if(running < config.threads && !GA.population[i].processing && !GA.population[i].fitness){
                // only one background window now...
                if (running < 1 && ga.population[i].processing == null && ga.population[i].fitness == null)
                {
                    ga.population[i].processing = true;

                    // hash values on arrays don't make it across ipc, store them in an array and reassemble on the other side....
                    List <int>         ids      = new List <int>();
                    List <int>         sources  = new List <int>();
                    List <List <NFP> > children = new List <List <NFP> >();

                    for (int j = 0; j < ga.population[i].placements.Count; j++)
                    {
                        var id     = ga.population[i].placements[j].id;
                        var source = ga.population[i].placements[j].source;
                        var child  = ga.population[i].placements[j].children;
                        //ids[j] = id;
                        ids.Add(id);
                        //sources[j] = source;
                        sources.Add(source.Value);
                        //children[j] = child;
                        children.Add(child);
                    }

                    DataInfo data = new DataInfo()
                    {
                        index         = i,
                        sheets        = sheets,
                        sheetids      = sheetids.ToArray(),
                        sheetsources  = sheetsources.ToArray(),
                        sheetchildren = sheetchildren,
                        individual    = ga.population[i],
                        config        = Config,
                        ids           = ids.ToArray(),
                        sources       = sources.ToArray(),
                        children      = children
                    };

                    background.BackgroundStart(data);
                    //ipcRenderer.send('background-start', { index: i, sheets: sheets, sheetids: sheetids, sheetsources: sheetsources, sheetchildren: sheetchildren, individual: GA.population[i], config: config, ids: ids, sources: sources, children: children});
                    running++;
                }
            }
        }