示例#1
0
 /// <summary>
 /// Creates a new instance.
 /// </summary>
 /// <param name="site">The prescription that just finished its repeat harvest</param>
 public Args(AppliedPrescription prescription, ManagementArea mgmtArea, uint repeatNumber, bool lastHarvest)
 {
     Prescription = prescription;
     MgmtArea     = mgmtArea;
     RepeatNumber = repeatNumber;
     LastHarvest  = lastHarvest;
 }
 /// <summary>
 /// Signals that a prescription is finished with a repeat step
 /// </summary>
 public static void OnRepeatHarvestFinished(object sender,
                                            AppliedPrescription prescription,
                                            ManagementArea mgmtArea,
                                            uint repeatNumber,
                                            bool lastHarvest)
 {
     if (RepeatPrescriptionFinishedEvent != null)
     {
         RepeatPrescriptionFinishedEvent(sender, new RepeatHarvestPrescriptionFinishedEvent.Args(prescription, mgmtArea, repeatNumber, lastHarvest));
     }
 }
        //---------------------------------------------------------------------

        /// <summary>
        /// Harvest the area's stands according to its prescriptions.
        /// </summary>
        public void HarvestStands()
        {
            //Model.Core.UI.WriteLine("BaseHarvest: ManagementArea.cs: HarvestStands: Harvesting management area {0} ...", mapCode);

            //initialize each stand for harvesting (setting harvested = false)
            foreach (Stand stand in stands)
            {
                stand.InitializeForHarvesting();
            }

            //  Determine which are prescriptions are active.
            List <AppliedPrescription> activePrescriptions = new List <AppliedPrescription>();

            foreach (AppliedPrescription prescription in prescriptions)
            {
                // Decide whether or not to apply prescription

                // tjs 2009.01.10 - prescription application
                // This has been modified so that if the prescription is AppliedRepeatHarvest
                // AND has not been harvested once, it is set to harvest. If it has been set
                // to harvest the first time, it will automatically be harvested by the logic
                // having to do with the setAside member variable (see AppliedRepeatHarvest.cs)

                prescription.ApplyPrescription = false;

                if (prescription.BeginTime <= Model.Core.CurrentTime &&
                    prescription.EndTime >= Model.Core.CurrentTime)
                {
                    if (!(prescription is AppliedRepeatHarvest) || prescription.Prescription is SingleRepeatHarvest)
                    {
                        prescription.ApplyPrescription = true;
                    }
                    else if (prescription is AppliedRepeatHarvest &&
                             Model.Core.CurrentTime > 0 && ((AppliedRepeatHarvest)prescription).IsMultipleRepeatHarvest)
                    {
                        prescription.ApplyPrescription = true;
                        ((AppliedRepeatHarvest)prescription).HasBeenHarvested = true;
                    }
                } // if(prescription.BeginTime <= Model.Core.CurrentTime...

                if (prescription.ApplyPrescription)
                {
                    //Model.Core.UI.WriteLine("   Applying Prescription: {0}  Model.Core.CurrentTime: {1}", prescription.Prescription.Name, Model.Core.CurrentTime);

                    if (isDebugEnabled)
                    {
                        log.DebugFormat("  Initializing prescription {0} ...", prescription.Prescription.Name);
                    }

                    //Model.Core.UI.WriteLine("   Initializing prescription {0} ...", prescription.Prescription.Name);

                    //set harvesting areas, rank stands (by user choice method)
                    prescription.InitializeForHarvest(stands);

                    if (prescription.AnyUnharvestedStandsRankedAbove0)
                    {
                        //Model.Core.UI.WriteLine("   Adding {0}", prescription.Prescription.Name);
                        foreach (StandRanking sr in prescription.Rankings)
                        {
                            //Model.Core.UI.WriteLine("   Stand {0} ranked {1}", sr.Stand.MapCode, sr.Rank);
                        }
                        activePrescriptions.Add(prescription);
                    }
                }
            }

            if (isDebugEnabled)
            {
                Model.Core.UI.WriteLine("   Number of active prescriptions: {0}", activePrescriptions.Count);
                for (int i = 0; i < activePrescriptions.Count; i++)
                {
                    Model.Core.UI.WriteLine("    {0})  {1}", i + 1, activePrescriptions[i].Prescription.Name);
                }
            }

            foreach (AppliedPrescription prescription in prescriptions)
            {
                //Model.Core.UI.WriteLine("      Looping through prescriptions... {0}.", prescription.Prescription.Name);

                if (prescription is AppliedRepeatHarvest)
                {
                    //prescription.Prescription.SiteSelectionMethod = new CompleteStand();
                    //Model.Core.UI.WriteLine("      Attempting to Re-Harvest {0}.", prescription.Prescription.Name);
                    ((AppliedRepeatHarvest)prescription).ActiveMgmtArea = this;
                    ((AppliedRepeatHarvest)prescription).HarvestReservedStands();
                    ((AppliedRepeatHarvest)prescription).ActiveMgmtArea = null;
                }
            }

            //  Loop while there are still active prescriptions that haven't
            //  reached their target harvest areas and that still have
            //  at least one unharvested stand ranked above 0.

            while (activePrescriptions.Count > 0)
            {
                double[] endProbability = new double[activePrescriptions.Count + 1];

                //  Assign a part of the probability interval [0, 1) to each
                //  prescription based on how the ratio of the area remaining to
                //  be harvested to the total area to be harvested
                double ratioTotal = 0.0;

                foreach (AppliedPrescription prescription in activePrescriptions)
                {
                    ratioTotal += Math.Min(prescription.AreaRemainingRatio, prescription.StandsRemainingRatio);
                }

                if (ratioTotal > 0)
                {
                    for (int i = 0; i < activePrescriptions.Count; ++i)
                    {
                        AppliedPrescription prescription = activePrescriptions[i];
                        //first prescription, start at 0
                        if (i == 0)
                        {
                            endProbability[i] = Math.Min(prescription.AreaRemainingRatio, prescription.StandsRemainingRatio) / ratioTotal;
                        }

                        //last prescription, end at 1.0
                        else if (i == activePrescriptions.Count - 1)
                        {
                            endProbability[i] = 1.0;
                        }

                        //
                        else
                        {
                            double startProbability = endProbability[i - 1];
                            double intervalWidth    = Math.Min(prescription.AreaRemainingRatio, prescription.StandsRemainingRatio) / ratioTotal;
                            endProbability[i] = startProbability + intervalWidth;
                        }
                    } // for (int i = 0; i < activePrescriptions.Count; ++i)

                    //  Randomly select one of the active prescriptions and harvest the stand ranked highest by that prescription.
                    AppliedPrescription selectedPrescription = null;

                    double randomNum = Model.Core.GenerateUniform();
                    for (int i = 0; i < activePrescriptions.Count; ++i)
                    {
                        if (randomNum < endProbability[i])
                        {
                            selectedPrescription = activePrescriptions[i];
                            //Model.Core.UI.WriteLine("\nSELECTED PRESCRIPTION = {0}\n", selectedPrescription.Prescription.Name);
                            break;
                        }
                    }

                    //actually harvest the stands: starting with highest ranked
                    if (selectedPrescription is AppliedRepeatHarvest)
                    {
                        ((AppliedRepeatHarvest)selectedPrescription).HarvestHighestRankedStand();
                    }
                    else
                    {
                        selectedPrescription.HarvestHighestRankedStand();
                    }

                    //Model.Core.UI.WriteLine("\nSELECTED PRESCRIPTION = {0}\n", selectedPrescription.Prescription.Name);

                    Stand stand = selectedPrescription.HighestRankedStand;

                    if (stand != null)
                    {
                        //if there was a stand-adjacency constraint on this stand, enforce:
                        foreach (IRequirement r in selectedPrescription.Prescription.StandRankingMethod.Requirements)
                        {
                            //look for stand-adacency constraint in list r ranking methods
                            if (r.ToString() == "Landis.Harvest.StandAdjacency")
                            {
                                StandAdjacency sa = (StandAdjacency)r;
                                //set-aside every stand in this stand's neighbor-list for the specified number of years

                                //IF siteselection = some type of spreading, freeze the spread-list of neighbors
                                if (selectedPrescription.Prescription.SiteSelectionMethod.ToString() == "Landis.Harvest.CompleteStandSpreading" ||
                                    selectedPrescription.Prescription.SiteSelectionMethod.ToString() == "Landis.Harvest.PartialStandSpreading")
                                {
                                    //freeze every stand in the neighbor list
                                    StandSpreading ss = (StandSpreading)selectedPrescription.Prescription.SiteSelectionMethod;

                                    //if it's spreading, go through the UnharvestedNeighbors list that was built during the site-selection spread
                                    foreach (Stand n_stand in ss.UnharvestedNeighbors)
                                    {
                                        //Model.Core.UI.WriteLine("SPREAD setting aside {0}", n_stand.MapCode);
                                        n_stand.SetAsideUntil(Model.Core.CurrentTime + sa.SetAside);
                                    }
                                }
                                else
                                {
                                    //if it's not a spreading, just take all of the stand's neighbors
                                    foreach (Stand n_stand in stand.Neighbors)
                                    {
                                        //Model.Core.UI.WriteLine("NON-SPREAD setting aside {0}", n_stand.MapCode);
                                        n_stand.SetAsideUntil(Model.Core.CurrentTime + sa.SetAside);
                                    }
                                }
                                //found and implemented the stand adjacency, so break out of the requirements list
                                break;
                            }
                        }
                    }
                    else
                    {
                        //Model.Core.UI.WriteLine("returned a null stand");
                    }

                    //  Check each prescription to see if there's at least one  unharvested stand that the prescription ranks higher than  0.
                    // The list is traversed in reverse order, so that the removal of items doesn't mess up the traversal.
                    for (int i = activePrescriptions.Count - 1; i >= 0; --i)
                    {
                        if (!activePrescriptions[i].AnyUnharvestedStandsRankedAbove0)
                        {
                            //Model.Core.UI.WriteLine("removing1 {0}", activePrescriptions[i].Prescription.Name);
                            activePrescriptions.RemoveAt(i);
                        }
                    }
                }

                else
                {
                    for (int i = activePrescriptions.Count - 1; i >= 0; --i)
                    {
                        //Model.Core.UI.WriteLine("removing2 {0}", activePrescriptions[i].Prescription.Name);
                        activePrescriptions.RemoveAt(i);
                    }
                }
            }  //endwhile
        }