コード例 #1
0
        private void Solve_Click(object sender, RoutedEventArgs e)
        {
            FEM fem = new FEM(obj);

            fem.RunSimulation();
            DataContext = new ExObjectView(fem.DefformatedObject, obj.Width, obj.Length, obj.Height);
        }
コード例 #2
0
        public static List <string> Function(Population pop, Dictionary <int, Matrix <double> > outputs, Matrix <double> coords, Matrix <double> outputTargets, int subdivisions, Metrics metrics)
        {
            //can manually specify a target occupancy using this function
            //occupancyTarget = CreateTargetOccupancy(outputs[pop.Genomes[0].ID].RowCount, outputs[pop.Genomes[0].ID].ColumnCount, coords);

            //convert to binary
            //var occupancy = Fitness.OccupancyFromOutputs(outputs);
            var occupancy = outputs;

            var fitnesses      = new List <double>();
            var fitnessStrings = new List <string>();

            Accord.Math.Random.Generator.Seed = 0;

            //loop over each member of the population and calculate fitness components
            Parallel.ForEach(occupancy.Keys, (key) =>
                             //foreach (KeyValuePair<int, Matrix<double> > output in occupancy)
            {
                //All Weights are Max 10, Min 0

                var outputID     = key;
                var outputValues = occupancy[key];

                var totalFitness  = 0.0;
                var fitnessString = "";

                //flatten occupancy matrix
                var vals = outputValues.ToRowMajorArray();


                if ((metrics & Metrics.Luminance) == Metrics.Luminance)
                {
                    var outputLum = ImageProcessing.Image.GetMeanLuminance(outputValues, subdivisions);
                    var targetLum = ImageProcessing.Image.GetMeanLuminance(outputTargets, subdivisions);

                    var absdiff = Math.Abs(outputLum - targetLum);

                    absdiff = Utils.Map(absdiff, 0, 1.0, 0, 10);

                    totalFitness  += Math.Pow(absdiff, 2);
                    fitnessString += $" | Luminance : {Math.Round(Math.Pow(absdiff, 2), 2)}";
                }


                if ((metrics & Metrics.Contrast) == Metrics.Contrast)
                {
                    var outputContrast = ImageProcessing.Image.GetContrast(outputValues, subdivisions);
                    var targetContrast = ImageProcessing.Image.GetContrast(outputTargets, subdivisions);

                    var absdiff = Math.Abs(outputContrast - targetContrast);

                    absdiff = Utils.Map(absdiff, 0, 1.0, 0, 10);

                    totalFitness  += Math.Pow(absdiff, 2);
                    fitnessString += $" | Contrast : {Math.Round(Math.Pow(absdiff, 2), 2)}";
                }


                if ((metrics & Metrics.Hue) == Metrics.Hue)
                {
                    //var outputHue = ImageAnalysis.GetHue(outputValues, subdivisions);
                    //var targetHue = ImageAnalysis.GetHue(outputTargets, subdivisions);
                    var temp = ImageProcessing.Image.GetHueDist(outputValues, outputTargets, subdivisions);

                    //var outputHue = outputValues.Column(0).Average();
                    //var targetHue = outputTargets.Column(0).Average();
                    //var absdiff = Math.Abs(outputHue - targetHue);

                    //var outputa = MathNet.Numerics.Statistics.Statistics.StandardDeviation(outputValues.Column(0));
                    //var targeta = MathNet.Numerics.Statistics.Statistics.StandardDeviation(outputTargets.Column(0));
                    //absdiff += Math.Abs(outputa - targeta);

                    //absdiff = Utils.Map(absdiff, 0, 255, 0, 10);
                    var absdiff = Utils.Map(temp, 0, 1.0, 0, 10);

                    totalFitness  += absdiff;
                    fitnessString += $" | Hue : {Math.Round(absdiff, 2)}";
                }

                if ((metrics & Metrics.HueVar) == Metrics.HueVar)
                {
                    var outputHue = ImageProcessing.Image.GetHueVar(outputValues, subdivisions);
                    var targetHue = ImageProcessing.Image.GetHueVar(outputTargets, subdivisions);



                    var absdiff = Math.Abs(outputHue - targetHue);

                    absdiff = Utils.Map(absdiff, 0, 100, 0, 10);

                    totalFitness  += Math.Pow(absdiff, 2);
                    fitnessString += $" | HueVar : {Math.Round(Math.Pow(absdiff, 2), 2)}";
                }

                if ((metrics & Metrics.Sat) == Metrics.Sat)
                {
                    var outputHue = ImageProcessing.Image.GetSat(outputValues, subdivisions);
                    var targetHue = ImageProcessing.Image.GetSat(outputTargets, subdivisions);

                    var absdiff = Math.Abs(outputHue - targetHue);

                    absdiff = Utils.Map(absdiff, 0, 1.0, 0, 10);

                    totalFitness  += Math.Pow(absdiff, 2);
                    fitnessString += $" | Sat : {Math.Round(Math.Pow(absdiff, 2), 2)}";
                }

                if ((metrics & Metrics.SatVar) == Metrics.SatVar)
                {
                    var outputHue = ImageProcessing.Image.GetSatVar(outputValues, subdivisions);
                    var targetHue = ImageProcessing.Image.GetSatVar(outputTargets, subdivisions);

                    var absdiff = Math.Abs(outputHue - targetHue);

                    absdiff = Utils.Map(absdiff, 0, 1.0, 0, 10);

                    totalFitness  += Math.Pow(absdiff, 2);
                    fitnessString += $" | SatVar : {Math.Round(Math.Pow(absdiff, 2), 2)}";
                }

                if ((metrics & Metrics.Height) == Metrics.Height)
                {
                    //Height
                    var fitnessHeight = 0.0;
                    for (int i = 0; i < subdivisions; i++)
                    {
                        var cellsInHoriz = vals.Skip(i * subdivisions * subdivisions).Take(subdivisions * subdivisions).Sum();

                        if (cellsInHoriz > 0)
                        {
                            fitnessHeight++;
                        }
                    }

                    fitnessHeight = Utils.Map(fitnessHeight, 0, subdivisions, 0, 10);

                    totalFitness  += fitnessHeight;
                    fitnessString += $" | Height : {Math.Round(fitnessHeight, 2)}";
                }


                if ((metrics & Metrics.Depth) == Metrics.Depth)
                {
                    var fitnessDepth = 0.0;

                    for (int i = 0; i < subdivisions; i++)
                    {
                        var cellsInVert = 0.0;

                        for (int j = 0; j < subdivisions; j++)
                        {
                            cellsInVert += vals.Skip(j * subdivisions * subdivisions + i * subdivisions).Take(subdivisions).Sum();
                        }

                        if (cellsInVert > 0)
                        {
                            fitnessDepth++;
                        }
                    }

                    fitnessDepth = Utils.Map(fitnessDepth, 0, subdivisions, 0, 10);

                    totalFitness  += fitnessDepth;
                    fitnessString += $" | Depth : {Math.Round(fitnessDepth, 2)}";
                }

                if ((metrics & Metrics.Size) == Metrics.Size)
                {
                    //Cell Count
                    var occupancyCount = vals.Sum();
                    var fitnessSize    = (10.0 - (10.0 * occupancyCount / (Math.Pow(subdivisions, coords.ColumnCount)))); //punish high cell count

                    totalFitness  += fitnessSize;
                    fitnessString += $" | Size : {Math.Round(fitnessSize, 2)}";
                }

                if ((metrics & Metrics.Displacement) == Metrics.Displacement)
                {
                    //FEM
                    var fitnessDisplacement = 0.0;
                    try
                    {
                        var FEMModel = FEM.CreateModel(coords, outputValues, subdivisions, subdivisions, subdivisions);
                        pop.GetGenomeByID(outputID).FEMModel = FEMModel;
                        var displacements = FEM.GetDisplacements(FEMModel);
                        var scaled        = displacements.Max(i => Math.Abs(i)) * 10e7;
                        var standardised  = 10 - Utils.Map(scaled, 0.01, 1.00, 0, 10);

                        if (standardised > 10)
                        {
                            standardised = 10.0;
                        }
                        if (standardised < 0)
                        {
                            standardised = 0.0;
                        }

                        fitnessDisplacement = standardised;
                    }
                    catch
                    {
                        fitnessDisplacement = -10.0;
                    }

                    totalFitness  += fitnessDisplacement;
                    fitnessString += $" | Displacement : {Math.Round(fitnessDisplacement, 2)}";
                }


                if ((metrics & Metrics.BottomLayer) == Metrics.BottomLayer)
                {
                    //Bottom  Layer
                    var bottomLayerCount = vals.Take(subdivisions * subdivisions).Sum();

                    var fitnessBottomLayer = 0.0;

                    if (bottomLayerCount > 50.0)
                    {
                        fitnessBottomLayer = 10.0;
                    }
                    else
                    {
                        fitnessBottomLayer = bottomLayerCount / 5.0;
                    }

                    totalFitness  += fitnessBottomLayer;
                    fitnessString += $" | BottomLayer : {Math.Round(fitnessBottomLayer, 2)}";
                }

                if ((metrics & Metrics.TopLayer) == Metrics.TopLayer)
                {
                    //Top Layer
                    var topLayerCount = vals.Skip(subdivisions * subdivisions * (subdivisions - 1)).Take(subdivisions * subdivisions).Sum();

                    var fitnessTopLayer = 0.0;

                    if (topLayerCount > 60.0)
                    {
                        fitnessTopLayer = 10.0;
                    }
                    else
                    {
                        fitnessTopLayer = topLayerCount / 6.0;
                    }

                    totalFitness  += fitnessTopLayer;
                    fitnessString += $" | TopLayer : {Math.Round(fitnessTopLayer, 2)}";
                }

                //could tidy this error checking
                if ((metrics & Metrics.L1) == Metrics.L1 & outputTargets != null)
                {
                    var fitnessL1Norm = (outputValues - outputTargets).PointwiseAbs().ToRowMajorArray().Sum();
                    fitnessL1Norm     = Utils.Map(fitnessL1Norm, 0.00, subdivisions * subdivisions * outputTargets.ColumnCount, 0, 10.0);
                    totalFitness     += fitnessL1Norm;
                    fitnessString    += $" | L1Norm : {Math.Round(fitnessL1Norm, 2)}";
                }


                if ((metrics & Metrics.L2) == Metrics.L2 & outputTargets != null)
                {
                    var fitnessL2Norm = Math.Sqrt((outputValues - outputTargets).PointwisePower(2).ToRowMajorArray().Sum());
                    fitnessL2Norm     = Utils.Map(fitnessL2Norm, 0.00, Math.Sqrt(subdivisions * subdivisions * outputTargets.ColumnCount), 0, 10.0);
                    totalFitness     += fitnessL2Norm;
                    fitnessString    += $" | L2Norm : {Math.Round(fitnessL2Norm, 2)}";
                }


                if ((metrics & Metrics.Gabor) == Metrics.Gabor & outputTargets != null)
                {
                    var gaborFitness = Superimpose(outputTargets, outputValues, 4 * subdivisions, subdivisions);
                    gaborFitness     = Utils.Map(gaborFitness, 0, 40.0, 0.0, 10.0);
                    totalFitness    += gaborFitness;
                    fitnessString   += $" | Gabor : {Math.Round(gaborFitness, 2)}";
                }



                // fitnessString += $" | Total : {Math.Round(totalFitness, 2)}";
                pop.GetGenomeByID(outputID).Fitness         = totalFitness;
                pop.GetGenomeByID(outputID).FitnessAsString = fitnessString;
            }
                             );

            if ((metrics & Metrics.Pattern) == Metrics.Pattern)
            {
                if (Fitness.bowModel == null)
                {
                    Fitness.bowModel = ImageProcessing.Image.CreateBowModel();
                }

                var featDistance = ImageProcessing.Image.GetFeatureDistances(occupancy, subdivisions, Fitness.bowModel);

                foreach (var key in featDistance.Keys)
                {
                    var featCorrect = featDistance[key];
                    featCorrect = Utils.Map(featCorrect, 0, 40.0, 0.0, 10.0);
                    pop.GetGenomeByID(key).Fitness += featCorrect;
                    var fitnessString = $" | Pattern : {Math.Round(featCorrect, 2)}";
                    pop.GetGenomeByID(key).FitnessAsString += fitnessString;
                }
            }



            Parallel.ForEach(occupancy.Keys, (key) =>
            {
                pop.GetGenomeByID(key).FitnessAsString += $" | Total : {Math.Round(pop.GetGenomeByID(key).Fitness, 2)}";
            });

            //need to figure out total fitness

            SortByFitness(pop);

            fitnesses = pop.Genomes.Select(i => i.Fitness).ToList();

            fitnessStrings = pop.Genomes.Select(i => i.FitnessAsString).ToList();

            return(fitnessStrings);
            //have a config setting for min max fitnesses
        }
コード例 #3
0
 public CommandWindowTests()
 {
     cmd = main.Cmd;
     fem = main.Fem;
 }