Exemplo n.º 1
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Mesh          mesh          = new Mesh();
            List <double> initialValues = new List <double>();
            double        desiredWidth  = 0.0;
            double        lambda        = 0.0;
            double        nu            = 0.0;

            if (!DA.GetData(0, ref mesh))
            {
                return;
            }
            if (!DA.GetDataList(1, initialValues))
            {
                return;
            }
            if (!DA.GetData(2, ref desiredWidth))
            {
                return;
            }
            if (!DA.GetData(3, ref lambda))
            {
                return;
            }
            if (!DA.GetData(4, ref nu))
            {
                return;
            }


            mesh.FaceNormals.ComputeFaceNormals();

            GeodesicsFromLevelSets levelSets = new GeodesicsFromLevelSets(mesh, initialValues, desiredWidth, lambda, nu);

            var optimizer = new Bobyqa(mesh.Vertices.Count, levelSets.Compute);

            optimizer.MaximumFunctionCalls = 200;

            double[]      x           = initialValues.ToArray();
            var           result      = optimizer.FindMinimum(x);
            List <double> finalValues = new List <double>(result.X);

            List <double> divergence = levelSets.ComputeDivergence(false);

            DA.SetDataList(1, levelSets.Gradient);
            DA.SetDataList(2, divergence);
            DA.SetDataList(3, levelSets.VertexVoronoiArea);
            DA.SetData(4, result.F);
            DA.SetDataList(5, finalValues);
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Mesh          mesh          = new Mesh();
            List <double> initialValues = new List <double>();
            double        desiredWidth  = 0.0;
            double        lambda        = 0.0;
            double        nu            = 0.0;
            int           maxCalls      = 0;
            int           optim         = 0;
            double        objective     = 10;

            if (!DA.GetData(0, ref mesh))
            {
                return;
            }
            if (!DA.GetDataList(1, initialValues))
            {
                return;
            }
            if (!DA.GetData(2, ref desiredWidth))
            {
                return;
            }
            if (!DA.GetData(3, ref lambda))
            {
                return;
            }
            if (!DA.GetData(4, ref nu))
            {
                return;
            }
            if (!DA.GetData(5, ref maxCalls))
            {
                return;
            }
            if (!DA.GetData(6, ref optim))
            {
                return;
            }
            if (!DA.GetData(7, ref objective))
            {
                return;
            }

            mesh.FaceNormals.ComputeFaceNormals();

            GeodesicsFromLevelSets levelSets = new GeodesicsFromLevelSets(mesh, initialValues, desiredWidth, lambda, nu);

            var optimizer = new Bobyqa(mesh.Vertices.Count, levelSets.Compute);

            optimizer.MaximumFunctionCalls = maxCalls;
            double[] x = initialValues.ToArray();


            var func = new LevelSetOpt(levelSets);

            var opt = new clsOptNelderMead(func);

            //if (optim == 1) opt = new clsOptNelderMead(func);
            //if (optim == 2) opt = new clsOptSimulatedAnnealing(func);
            //if (optim == 3) opt = new clsFireFly(func);
            opt.IsUseCriterion  = false;
            opt.InitialPosition = initialValues.ToArray();
            opt.Iteration       = maxCalls;
            double finalError = 0;
            bool   retry      = false;

            do
            {
                double[] resultX = { };
                if (optim == 0)
                {
                    var result = optimizer.FindMinimum(x);
                    finalError = result.F;
                    resultX    = result.X;
                }
                else if (optim > 0)
                { // Nelder mead & simulated annealing
                    opt.Init();

                    while (opt.DoIteration(100) == false)
                    {
                        var eval = opt.Result.Eval;

                        //my criterion
                        if (eval < 10)
                        {
                            break;
                        }
                        Console.WriteLine("Iter: {0} Eval: {1}", opt.IterationCount, opt.Result.Eval);
                    }
                    finalError = opt.Result.Eval;
                    clsUtil.DebugValue(opt);
                }

                //if (optim == 0) {
                //    String str = "Optimization ended with an error of" + finalError + "\nDo you wish to run again using this results as input?";
                //    if (MessageBox.Show(str, "Optimization Ended", MessageBoxButtons.YesNo, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                //    {
                //        x = resultX;
                //        retry = true;
                //    }
                //    else
                //    {
                //        retry = false;
                //    }
                //}
            } while (retry == true);

            //levelSets = func.levelSets;

            List <double> desiredLevels = new List <double>();
            double        max           = 0.0;
            double        min           = 0.0;

            for (int i = 0; i < levelSets.VertexValues.Count; i++)
            {
                double value = levelSets.VertexValues[i];
                if (i == 0)
                {
                    max = value; min = value;
                }

                if (value < min)
                {
                    min = value;
                }
                if (value > max)
                {
                    max = value;
                }
            }

            double diff       = max - min;
            int    levelCount = (int)(diff / desiredWidth);

            for (int j = 0; j <= levelCount; j++)
            {
                desiredLevels.Add(min + (j * desiredWidth));
            }

            DataTree <Line> pattern        = levelSets.DrawLevelSetCurves(desiredLevels);
            List <double>   divergence     = levelSets.ComputeDivergence(false);
            List <double>   divergenceNorm = levelSets.ComputeDivergence(true);

            DA.SetDataTree(0, pattern);
            DA.SetDataList(1, levelSets.Gradient);
            DA.SetDataList(2, divergence);
            DA.SetDataList(3, levelSets.VertexVoronoiArea);
            DA.SetData(4, finalError);
            DA.SetDataList(5, levelSets.VertexValues);
            DA.SetDataList(6, divergenceNorm);
        }