예제 #1
0
        public void Plot14ImmediateThin()
        {
            int  thinPeriod      = 1;
            int  lastPeriod      = 4;
            bool useScaledVolume = false;

            PlotsWithHeight      plot14        = PublicApi.GetPlot14();
            OrganonConfiguration configuration = OrganonTest.CreateOrganonConfiguration(new OrganonVariantNwo());
            OrganonStand         stand         = plot14.ToOrganonStand(configuration, 30, 130.0F);

            stand.PlantingDensityInTreesPerHectare = TestConstant.Plot14ReplantingDensityInTreesPerHectare;

            configuration.Treatments.Harvests.Add(new ThinByPrescription(thinPeriod)
            {
                FromAbovePercentage    = 0.0F,
                ProportionalPercentage = 30.0F,
                FromBelowPercentage    = 0.0F
            });
            OrganonStandTrajectory thinnedTrajectory = new OrganonStandTrajectory(stand, configuration, TimberValue.Default, lastPeriod, useScaledVolume);

            AssertNullable.IsNotNull(thinnedTrajectory.StandByPeriod[0]);
            Assert.IsTrue(thinnedTrajectory.StandByPeriod[0] !.GetTreeRecordCount() == 222);
            thinnedTrajectory.Simulate();

            // verify thinned trajectory
            //                                        0      1       2       3       4
            float[] minimumThinnedQmd = new float[] { 9.16F, 10.47F, 11.64F, 12.64F, 13.52F };       // in
            //                                              0      1       2       3       4
            float[] minimumThinnedTopHeight = new float[] { 92.9F, 101.4F, 110.4F, 118.9F, 126.7F }; // ft
            float[] minimumThinnedVolume;
            if (thinnedTrajectory.UseScaledVolume)
            {
                minimumThinnedVolume = new float[] { 51.59F, 51.75F, 66.71F, 81.88F, 97.72F }; // Poudel 2018 + Scribner long log net MBF/ha
            }
            else
            {
                //                                   0       1       2       3       4
                minimumThinnedVolume = new float[] { 43.74F, 49.00F, 68.86F, 87.95F, 105.8F }; // Browning 1977 (FIA) MBF/ha
            }

            PublicApi.Verify(thinnedTrajectory, minimumThinnedQmd, minimumThinnedTopHeight, minimumThinnedVolume, thinPeriod, lastPeriod, 65, 70, configuration.Variant.TimeStepInYears);
            PublicApi.Verify(thinnedTrajectory, minimumThinnedVolume, thinPeriod);
            Assert.IsTrue(thinnedTrajectory.GetFirstHarvestAge() == 30);
        }
예제 #2
0
        protected override void ProcessRecord()
        {
            if (this.Runs !.Count < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(this.Runs));
            }

            using StreamWriter writer = this.GetWriter();

            // for now, perform no reduction when Object.ReferenceEquals(lowestSolution, highestSolution) is true
            StringBuilder line = new StringBuilder();

            if (this.ShouldWriteHeader())
            {
                if ((this.Runs[0].HighestSolution == null) || (this.Runs[0].HighestHeuristicParameters == null) || (this.Runs[0].LowestSolution == null))
                {
                    throw new NotSupportedException("Cannot generate header because first run is missing a highest solution, lowest solution, or highest solution parameters.");
                }

                line.Append("stand,heuristic,thin age,rotation," + this.Runs[0].HighestHeuristicParameters !.GetCsvHeader() + ",iteration,count");

                string            lowestMoveLogHeader = "lowest move log";
                IHeuristicMoveLog?lowestMoveLog       = this.Runs[0].LowestSolution !.GetMoveLog();
                if (lowestMoveLog != null)
                {
                    lowestMoveLogHeader = lowestMoveLog.GetCsvHeader("lowest ");
                }
                line.Append("," + lowestMoveLogHeader);

                line.Append(",lowest,lowest candidate,min,percentile 2.5,percentile 5,lower quartile,median,mean,upper quartile,percentile 95,percentile 97.5,max");

                string            highestMoveLogHeader = "highest move log";
                IHeuristicMoveLog?highestMoveLog       = this.Runs[0].HighestSolution !.GetMoveLog();
                if (highestMoveLog != null)
                {
                    highestMoveLogHeader = highestMoveLog.GetCsvHeader("highest ");
                }
                line.Append("," + highestMoveLogHeader);

                line.Append(",highest,highest candidate");
                writer.WriteLine(line);
            }

            for (int runIndex = 0; runIndex < this.Runs.Count; ++runIndex)
            {
                HeuristicSolutionDistribution distribution = this.Runs[runIndex];
                Heuristic?highestHeuristic = distribution.HighestSolution;
                Heuristic?lowestHeuristic  = distribution.LowestSolution;
                if ((distribution.HighestHeuristicParameters == null) || (highestHeuristic == null) || (lowestHeuristic == null))
                {
                    throw new NotSupportedException("Solution distribution for run " + runIndex + " is missing a highest or lowest solution or highest solution parameters.");
                }
                IHeuristicMoveLog?highestMoveLog = highestHeuristic.GetMoveLog();
                IHeuristicMoveLog?lowestMoveLog  = lowestHeuristic.GetMoveLog();
                // for now, assume highest and lowest solutions used the same parameters
                OrganonStandTrajectory highestTrajectory = highestHeuristic.BestTrajectory;
                string runPrefix = highestTrajectory.Name + "," + highestHeuristic.GetName() + "," + highestTrajectory.GetFirstHarvestAge() + "," + highestTrajectory.GetRotationLength() + "," + distribution.HighestHeuristicParameters.GetCsvValues();

                Debug.Assert(distribution.CountByMove.Count >= lowestHeuristic.AcceptedObjectiveFunctionByMove.Count);
                Debug.Assert(distribution.CountByMove.Count == distribution.MinimumObjectiveFunctionByMove.Count);
                Debug.Assert(distribution.CountByMove.Count >= distribution.TwoPointFivePercentileByMove.Count);
                Debug.Assert(distribution.CountByMove.Count >= distribution.FifthPercentileByMove.Count);
                Debug.Assert(distribution.CountByMove.Count >= distribution.LowerQuartileByMove.Count);
                Debug.Assert(distribution.CountByMove.Count >= distribution.MedianObjectiveFunctionByMove.Count);
                Debug.Assert(distribution.CountByMove.Count == distribution.MeanObjectiveFunctionByMove.Count);
                Debug.Assert(distribution.CountByMove.Count >= distribution.NinetyFifthPercentileByMove.Count);
                Debug.Assert(distribution.CountByMove.Count >= distribution.NinetySevenPointFivePercentileByMove.Count);
                Debug.Assert(distribution.CountByMove.Count >= distribution.UpperQuartileByMove.Count);
                Debug.Assert(distribution.CountByMove.Count == distribution.MaximumObjectiveFunctionByMove.Count);
                Debug.Assert(distribution.CountByMove.Count >= highestHeuristic.AcceptedObjectiveFunctionByMove.Count);
                for (int moveIndex = 0; moveIndex < distribution.CountByMove.Count; moveIndex += this.Step)
                {
                    line.Clear();

                    string runsWithMoveAtIndex = distribution.CountByMove[moveIndex].ToString(CultureInfo.InvariantCulture);

                    string?lowestMove = null;
                    if ((lowestMoveLog != null) && (lowestMoveLog.Count > moveIndex))
                    {
                        lowestMove = lowestMoveLog.GetCsvValues(moveIndex);
                    }
                    string?lowestObjectiveFunction = null;
                    if (lowestHeuristic.AcceptedObjectiveFunctionByMove.Count > moveIndex)
                    {
                        lowestObjectiveFunction = lowestHeuristic.AcceptedObjectiveFunctionByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    }
                    string?lowestObjectiveFunctionForMove = null;
                    if (lowestHeuristic.CandidateObjectiveFunctionByMove.Count > moveIndex)
                    {
                        lowestObjectiveFunctionForMove = lowestHeuristic.CandidateObjectiveFunctionByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    }

                    string minObjectiveFunction           = distribution.MinimumObjectiveFunctionByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    string?lowerQuartileObjectiveFunction = null;
                    if (moveIndex < distribution.LowerQuartileByMove.Count)
                    {
                        lowerQuartileObjectiveFunction = distribution.LowerQuartileByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    }
                    string?twoPointFivePercentileObjectiveFunction = null;
                    if (moveIndex < distribution.TwoPointFivePercentileByMove.Count)
                    {
                        twoPointFivePercentileObjectiveFunction = distribution.TwoPointFivePercentileByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    }
                    string?fifthPercentileObjectiveFunction = null;
                    if (moveIndex < distribution.FifthPercentileByMove.Count)
                    {
                        fifthPercentileObjectiveFunction = distribution.FifthPercentileByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    }
                    string?medianObjectiveFunction = null;
                    if (moveIndex < distribution.MedianObjectiveFunctionByMove.Count)
                    {
                        medianObjectiveFunction = distribution.MedianObjectiveFunctionByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    }
                    string meanObjectiveFunction          = distribution.MeanObjectiveFunctionByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    string?upperQuartileObjectiveFunction = null;
                    if (moveIndex < distribution.UpperQuartileByMove.Count)
                    {
                        upperQuartileObjectiveFunction = distribution.UpperQuartileByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    }
                    string?ninetyFifthPercentileObjectiveFunction = null;
                    if (moveIndex < distribution.NinetyFifthPercentileByMove.Count)
                    {
                        ninetyFifthPercentileObjectiveFunction = distribution.NinetyFifthPercentileByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    }
                    string?ninetySevenPointFivePercentileObjectiveFunction = null;
                    if (moveIndex < distribution.NinetySevenPointFivePercentileByMove.Count)
                    {
                        ninetySevenPointFivePercentileObjectiveFunction = distribution.NinetySevenPointFivePercentileByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    }
                    string maxObjectiveFunction = distribution.MaximumObjectiveFunctionByMove[moveIndex].ToString(CultureInfo.InvariantCulture);

                    string?highestMove = null;
                    if ((highestMoveLog != null) && (highestMoveLog.Count > moveIndex))
                    {
                        highestMove = highestMoveLog.GetCsvValues(moveIndex);
                    }
                    string highestObjectiveFunction = String.Empty;
                    if (highestHeuristic.AcceptedObjectiveFunctionByMove.Count > moveIndex)
                    {
                        highestObjectiveFunction = highestHeuristic.AcceptedObjectiveFunctionByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    }
                    string?highestObjectiveFunctionForMove = null;
                    if (highestHeuristic.CandidateObjectiveFunctionByMove.Count > moveIndex)
                    {
                        highestObjectiveFunctionForMove = highestHeuristic.CandidateObjectiveFunctionByMove[moveIndex].ToString(CultureInfo.InvariantCulture);
                    }

                    line.Append(runPrefix + "," +
                                moveIndex + "," +
                                runsWithMoveAtIndex + "," +
                                lowestMove + "," +
                                lowestObjectiveFunction + "," +
                                lowestObjectiveFunctionForMove + "," +
                                minObjectiveFunction + "," +
                                twoPointFivePercentileObjectiveFunction + "," +
                                fifthPercentileObjectiveFunction + "," +
                                lowerQuartileObjectiveFunction + "," +
                                medianObjectiveFunction + "," +
                                meanObjectiveFunction + "," +
                                upperQuartileObjectiveFunction + "," +
                                ninetyFifthPercentileObjectiveFunction + "," +
                                ninetySevenPointFivePercentileObjectiveFunction + "," +
                                maxObjectiveFunction + "," +
                                highestMove + "," +
                                highestObjectiveFunction + "," +
                                highestObjectiveFunctionForMove);
                    writer.WriteLine(line);
                }
            }
        }
예제 #3
0
        protected override void ProcessRecord()
        {
            if (this.Runs !.Count < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(this.Runs));
            }

            using StreamWriter writer = this.GetWriter();

            StringBuilder line = new StringBuilder();

            if (this.ShouldWriteHeader())
            {
                HeuristicParameters?highestParameters = this.Runs[0].HighestHeuristicParameters;
                if (highestParameters == null)
                {
                    throw new NotSupportedException("Cannot generate header because first run is missing highest solution parameters.");
                }

                line.Append("stand,heuristic," + highestParameters.GetCsvHeader() + ",thin age,rotation,solution,objective,runtime");
                writer.WriteLine(line);
            }

            for (int runIndex = 0; runIndex < this.Runs.Count; ++runIndex)
            {
                HeuristicSolutionDistribution distribution = this.Runs[runIndex];
                Heuristic?highestHeuristic = distribution.HighestSolution;
                if ((highestHeuristic == null) || (distribution.HighestHeuristicParameters == null))
                {
                    throw new NotSupportedException("Run " + runIndex + " is missing a highest solution or highest solution parameters.");
                }
                OrganonStandTrajectory highestTrajectory = highestHeuristic.BestTrajectory;
                string linePrefix = highestTrajectory.Name + "," + highestHeuristic.GetName() + "," + distribution.HighestHeuristicParameters.GetCsvValues() + "," + highestTrajectory.GetFirstHarvestAge() + "," + highestTrajectory.GetRotationLength();

                List <float> bestSolutions = distribution.BestObjectiveFunctionBySolution;
                for (int solutionIndex = 0; solutionIndex < bestSolutions.Count; ++solutionIndex)
                {
                    line.Clear();

                    string objectiveFunction = bestSolutions[solutionIndex].ToString(CultureInfo.InvariantCulture);
                    string runtime           = distribution.RuntimeBySolution[solutionIndex].TotalSeconds.ToString("0.000", CultureInfo.InvariantCulture);
                    line.Append(linePrefix + "," + solutionIndex + "," + objectiveFunction + "," + runtime);
                    writer.WriteLine(line);
                }
            }
        }