Esempio n. 1
0
        //--------------------------------------------------------------

        // For the current stand, enqueue all the eligible sites onto
        // the harvestableSites queue
        private bool EnqueueEligibleSites(ActiveSite startingSite, Stand crntStand)
        {
            Queue <ActiveSite> sitesConsidered = new Queue <ActiveSite>();
            Queue <ActiveSite> sitesToConsider = new Queue <ActiveSite>();
            bool rtrnVal = false;

            ActiveSite crntSite = startingSite;

            //The following case could happen if prevent establishment
            //generates empty stands.
            if (crntStand.GetActiveSites().Count <= 0)
            {
                return(false);
            }

            if (crntSite != null)
            {
                sitesToConsider.Enqueue(crntSite);
            }

            while (sitesToConsider.Count > 0 && areaSelected < maxTargetSize)
            {
                // Get the site to work with for this loop iteration
                crntSite = sitesToConsider.Dequeue();

                // Enqueue and increment area if sight is harvestable
                sitesConsidered.Enqueue(crntSite);
                if (SiteVars.TimeSinceLastDamage(crntSite) >= minTimeSinceDamage)
                {
                    harvestableSites.Enqueue(crntSite);
                    areaSelected += Model.Core.CellArea;
                    rtrnVal       = true;
                }

                // Put those neighbors on the sightsToConsider queue
                foreach (RelativeLocation loc in all_neighbor_locations)
                {
                    // get a neighbor site
                    Site tempSite = crntSite.GetNeighbor(loc);
                    if (tempSite != null && tempSite.IsActive)
                    {
                        //get a neighbor site (if it's active and non-null)
                        //if (crntSite.GetNeighbor(loc) != null && crntSite.GetNeighbor(loc).IsActive)
                        //{
                        ActiveSite neighborSite = (ActiveSite)tempSite;  // (ActiveSite)crntSite.GetNeighbor(loc);

                        // check if in the same stand and management area
                        // and if it has not been looked at
                        if (SiteVars.Stand[neighborSite] == SiteVars.Stand[crntSite] &&
                            SiteVars.ManagementArea[neighborSite] == SiteVars.ManagementArea[crntSite] &&
                            !sitesConsidered.Contains(neighborSite) &&
                            !sitesToConsider.Contains(neighborSite))
                        {
                            sitesToConsider.Enqueue(neighborSite);
                        }
                    }
                }
            }

            return(rtrnVal);
        }
        //---------------------------------------------------------------------
        // Re-written by R. Scheller to simplify and speed the stand processing.
        private bool CheckRule(Stand stand, InclusionRule rule)
        {
            //bool meets = false;
            int numCellsValid  = 0;
            int numActiveCells = 0;

            int[] numCellsOtherSpecies = new int[Model.Core.Species.Count];

            foreach (ActiveSite site in stand.GetActiveSites())
            {
                //if(!site.IsActive)
                //    continue;

                numActiveCells++;

                bool goodSite = false;
                //bool otherSpecies = false;

                //Landis.Library.BaseCohorts.ISiteCohorts siteCohorts = (Landis.Library.BaseCohorts.ISiteCohorts) Model.Core.SuccessionCohorts[site];

                foreach (ISpecies species in Model.Core.Species)
                {
                    if (SiteVars.Cohorts[site][species] != null)
                    {
                        foreach (ICohort cohort in SiteVars.Cohorts[site][species])
                        {
                            if (rule.SpeciesList.Contains(species.Name) && rule.RuleAgeRange.Contains(cohort.Age))
                            {
                                goodSite = true;
                            }

                            // Some other species, NOT in the list
                            if (!rule.SpeciesList.Contains(species.Name) && rule.RuleAgeRange.Contains(cohort.Age))
                            {
                                //otherSpecies = true;
                                numCellsOtherSpecies[species.Index]++;
                            }
                        }
                    }
                }

                if (goodSite)
                {
                    numCellsValid++;
                }

                //if(otherSpecies)
                //numCellsOtherSpecies[species.Index]++;
            }  // done looping through sites

            if (numCellsValid == 0) // There are no good cells whatsoever.
            {
                return(false);
            }

            bool highest = true;

            //If percent != -1, compare to the Percent of Cells
            if (rule.PercentOfCells != -1)
            {
                double targetNumCells = (double)numActiveCells * rule.PercentOfCells;

                if (targetNumCells > numActiveCells)
                {
                    string message = string.Format("  Harvest Inclusion Rule Error:  target number of cells {0} exceeds number in stand {1}", targetNumCells, numActiveCells);
                    throw new ApplicationException(message);
                }
                if (numCellsValid >= targetNumCells)
                {
                    //Model.Core.UI.WriteLine("       numGoodSites={0}, targetNumCells={1}", numCellsValid, targetNumCells);
                    return(true);
                }
            }

            //If percent == -1, use 'highest' evaluation algorithm
            else
            {
                for (int i = 0; i < Model.Core.Species.Count; i++)
                {
                    if (numCellsValid < numCellsOtherSpecies[i])
                    {
                        highest = false;
                    }
                    //Model.Core.UI.WriteLine("       numGoodSites={0}, otherSppCnt={1}, true? {2}", numCellsValid, otherSpeciesCount[i], highest);
                }
            }

            return(highest);
        }
Esempio n. 3
0
        //---------------------------------------------------------------------

        IEnumerator <ActiveSite> IEnumerable <ActiveSite> .GetEnumerator()
        {
            // initialize and declare variables
            areaSelected = 0;
            double             patchAreaSelected = 0;
            List <ActiveSite>  sites             = stand.GetActiveSites();   // this stand's sites
            Queue <ActiveSite> sitesToHarvest    = new Queue <ActiveSite>(); // for harvesting
            Queue <ActiveSite> sitesToConsider   = new Queue <ActiveSite>(); // sites to harvest
            Queue <ActiveSite> sitesConsidered   = new Queue <ActiveSite>(); // all considered
            ActiveSite         crntSite;
            int    random;
            double standTargetArea;

            //get a random site from the stand
            //random = (int) (Model.Core.GenerateUniform() *
            //    (stand.SiteCount - 1));

            //get a random active site from the stand
            random   = (int)(Model.Core.GenerateUniform() * (sites.Count - 1));
            crntSite = sites[random];

            //while (!(((Site)crntSite).IsActive) && sites.Count > 0) {
            //while (sites.Count > 0) {
            //    //Model.Core.UI.WriteLine("   ERROR:  Non-active site included in stand {0}.", stand.MapCode);
            //    sitesConsidered.Enqueue(crntSite);
            //    sites.Remove(crntSite);
            //    random = (int)(Model.Core.GenerateUniform() * (sites.Count - 1));
            //    crntSite = sites[random];
            //} // while (!(((Site)crntSite).IsActive) && sites.Count > 0)

            //put initial pivot site on queue
            sitesToConsider.Enqueue(crntSite);
            sites.Remove(crntSite);

            standTargetArea = Model.Core.CellArea * stand.SiteCount * percent;

            // loop through stand, harvesting patches of size patch_size at a time
            while (areaSelected < standTargetArea && sites.Count > 0)
            {
                while (patchAreaSelected < patch_size &&
                       areaSelected < standTargetArea &&
                       sites.Count > 0)
                {
                    //loop through the site's neighbors enqueueing them too
                    foreach (RelativeLocation loc in all_neighbor_locations)
                    {
                        // get a neighbor site
                        Site tempSite = crntSite.GetNeighbor(loc);
                        if (tempSite != null && tempSite.IsActive)
                        {
                            ActiveSite nbrSite = (ActiveSite)tempSite;

                            if (sites.Contains(nbrSite))
                            {
                                //get a neighbor site (if it's non-null and active)
                                if (!sitesToConsider.Contains(nbrSite) &&
                                    !sitesConsidered.Contains(nbrSite))
                                {
                                    //then enqueue the neighbor
                                    sitesToConsider.Enqueue(nbrSite);
                                }
                                //Always remove the site if it's in the sites list.
                                sites.Remove(nbrSite);
                            }
                        }
                    }

                    //check if there's anything left on the queue
                    if (sitesToConsider.Count > 1)
                    {
                        ActiveSite crntConsideredSite = sitesToConsider.Dequeue();
                        if (SiteVars.TimeSinceLastDamage(crntConsideredSite) >=
                            stand.MinTimeSinceDamage)
                        {
                            // now after looping through all of the current
                            // site's neighbors dequeue the current site and
                            // put it on the sitesToHarvest queue (used later)
                            sitesToHarvest.Enqueue(crntConsideredSite);

                            // increment area selected and total_areaSelected
                            patchAreaSelected += Model.Core.CellArea;
                            areaSelected      += Model.Core.CellArea;
                        }

                        // Whether harvestable or not, it has been considered
                        sitesConsidered.Enqueue(crntConsideredSite);
                        //and set the new crntSite to the head of the queue (by peeking)
                        crntSite = sitesToConsider.Peek();
                    }
                    else if (sitesToConsider.Count == 1)     //get another site from the queue

                    {
                        crntSite = sitesToConsider.Peek();

                        ActiveSite crntConsideredSite = sitesToConsider.Dequeue();
                        if (SiteVars.TimeSinceLastDamage(crntConsideredSite) >=
                            stand.MinTimeSinceDamage)
                        {
                            sitesToHarvest.Enqueue(crntConsideredSite);

                            //increment area selected and total_areaSelected
                            patchAreaSelected += Model.Core.CellArea;
                            areaSelected      += Model.Core.CellArea;
                        }

                        // Whether harvestable or not, it has been considered
                        sitesConsidered.Enqueue(crntConsideredSite);
                    }
                    else
                    {
                        // else just break out- if it's not big enough it's not big enough
                        //Model.Core.UI.WriteLine("patch isn't big enough ({0}), must BREAK.", areaSelected);
                        break;
                    } // if (sitesToConsider.Count > 1)
                }     // while (patchAreaSelected < patch_size &&

                //Model.Core.UI.WriteLine("Done with a patch.");

                //clear the sitesToConsider queue to get rid of old sites
                sitesToConsider.Clear();
                // get a new random site to start at (one that hasn't been
                // put on the sitesConsidered queue yet)
                // only allow a site-count # of tries
                bool found_site = false;
                int  tries      = 0;
                while (!found_site && tries < sites.Count)
                {
                    //increment the number of tries
                    tries++;
                    random   = (int)(Model.Core.GenerateUniform() * (sites.Count - 1));
                    crntSite = sites[random];

                    // Get an active site
                    //while (!(((Site)crntSite).IsActive) && sites.Count > 0) {
                    //while (sites.Count > 0) {
                    //Model.Core.UI.WriteLine("   ERROR:  Non-active site included in stand {0}.", stand.MapCode);
                    //    sitesConsidered.Enqueue(crntSite);
                    //    sites.Remove(crntSite);
                    //    random = (int)(Model.Core.GenerateUniform() *
                    //        (sites.Count - 1));
                    //    crntSite = sites[random];
                    //} // while (!(((Site)crntSite).IsActive) && sites.Count > 0)

                    if (sites.Count <= 0)
                    {
                        break;
                    }

                    //if it's not on the sitesConsidered queue already
                    if (!sitesConsidered.Contains(crntSite))
                    {
                        // now put this site on for consideration (which will
                        // later be put onto the sitesToHarvest queue).
                        sitesToConsider.Enqueue(crntSite);
                        sites.Remove(crntSite);
                        found_site = true;
                    }
                } // while (!found_site && tries < sites.Count)

                //if the site isn't found (prev loop was broken because
                // of too many tries) then break from this stand entirely
                if (!found_site)
                {
                    break;
                }
                //reset areaSelected = 0 to start over
                patchAreaSelected = 0;
                //Model.Core.UI.WriteLine("areaSelected = {0}", areaSelected);
            } // while (areaSelected < standTargetArea && sites.Count > 0)

            // if the stand met the criteria for the harvest, mark it
            // as harvested otherwise add the prescription name to the
            // stands rejected prescription list

            if (areaSelected >= standTargetArea)
            {
                stand.MarkAsHarvested();
                stand.EventId = EventId.MakeNewId();
            }
            else
            {
                //Model.Core.UI.WriteLine("Rejecting stand {0} for prescription {1}",stand.MapCode, stand.PrescriptionName);
                stand.RejectPrescriptionName(stand.PrescriptionName);
            }

            // if harvest criteria met, yield the sites, else, don't
            if (areaSelected >= standTargetArea)
            {
                while (sitesToHarvest.Count > 0)
                {
                    yield return(sitesToHarvest.Dequeue());
                }
            }
        } // IEnumerator<ActiveSite> IEnumerable<ActiveSite>.GetEnumerator()