//--------------------------------------------------------------------- /// <summary> /// Computes the rank for a stand. /// </summary> protected override double ComputeRank(Stand stand, int i) { double standEconImportance = 0.0; //Model.Core.UI.WriteLine("Base Harvest: EconomicRank.cs: ComputeRank: there are {0} sites in this stand.", stand.SiteCount); foreach (ActiveSite site in stand) { double siteEconImportance = 0.0; foreach (ISpeciesCohorts speciesCohorts in SiteVars.Cohorts[site]) { EconomicRankParameters rankingParameters = rankTable[speciesCohorts.Species]; foreach (ICohort cohort in speciesCohorts) { if (rankingParameters.MinimumAge > 0 && rankingParameters.MinimumAge <= cohort.Age) { siteEconImportance += (double)rankingParameters.Rank / rankingParameters.MinimumAge * cohort.Age; } } } standEconImportance += siteEconImportance; } standEconImportance /= stand.SiteCount; return(standEconImportance); }
//--------------------------------------------------------------------- /// <summary> /// Harvests the highest-ranked stand which hasn't been harvested yet /// during the current timestep. /// </summary> public virtual void HarvestHighestRankedStand() { //Model.Core.UI.WriteLine(" Standard Harvest Highest Ranked Stand."); //get the highest ranked unharvested stand Stand stand = rankings[highestUnharvestedStand].Stand; if (rankings[highestUnharvestedStand].Rank > 0) { if (!stand.IsSetAside) { // set the global current rank so it can be taken by // Prescription.Harvest and applied // to this harvest event currentRank = rankings[highestUnharvestedStand].Rank; prescription.Harvest(stand); this.HighestRankedStand = stand; double harvestedArea = stand.LastAreaHarvested; areaHarvested += harvestedArea; //if all (or more ??) is harvested, set areaRemainingToHarvest to 0 if (harvestedArea >= areaRemainingToHarvest) { areaRemainingToHarvest = 0; } else { areaRemainingToHarvest -= harvestedArea; } areaRemainingRatio = areaRemainingToHarvest / areaToHarvest; } } }
//--------------------------------------------------------------------- /// <summary> /// Computes the rank for a stand. /// </summary> protected override double ComputeRank(Stand stand, int i) { SiteVars.ReInitialize(); //if (SiteVars.CFSFuelType == null) // throw new System.ApplicationException("Error: CFS Fuel Type NOT Initialized. Fuel extension MUST be active."); double standFireRisk = 0.0; //Model.Core.UI.WriteLine("Base Harvest: EconomicRank.cs: ComputeRank: there are {0} sites in this stand.", stand.SiteCount); foreach (ActiveSite site in stand) { //double siteFireRisk = 0.0; int fuelType = SiteVars.CFSFuelType[site]; //Model.Core.UI.WriteLine("Base Harvest: ComputeRank: FuelType = {0}.", fuelType); FireRiskParameters rankingParameters = rankTable[fuelType]; standFireRisk = (double)rankingParameters.Rank; //foreach (ISpeciesCohorts speciesCohorts in SiteVars.Cohorts[site]) //{ // FireRiskParameters rankingParameters = rankTable[speciesCohorts.Species]; // foreach (ICohort cohort in speciesCohorts) { // if (rankingParameters.MinimumAge > 0 && // rankingParameters.MinimumAge <= cohort.Age) // siteEconImportance += (double) rankingParameters.Rank / rankingParameters.MinimumAge * cohort.Age; // } //} //standEconImportance += siteEconImportance; } standFireRisk /= stand.SiteCount; return(standFireRisk); }
//--------------------------------------------------------------------- bool IRequirement.MetBy(Stand stand) { //Model.Core.UI.WriteLine("checking stand {0}", stand.MapCode); //get list of neighboring stands (must cast from enum) List <Stand> neighbor_stands = new List <Stand>(); neighbor_stands = (List <Stand>)stand.Neighbors; //add ma_neighbors to this list as well, to check with all the neighboring stands that are in a different management area foreach (Stand n_stand in stand.MaNeighbors) { neighbor_stands.Add(n_stand); } //loop through neighbor stands (including ma_neighbors), if one is too young then return false foreach (Stand n_stand in neighbor_stands) { //if n_stand is too young, return false (breaking out of loop as soon as one neighbor fails) if (type == "StandAge") { if (n_stand.Age < time) { return(false); } } //if type was mintimesincelastharvest else { if (n_stand.TimeSinceLastHarvested < time) { //Model.Core.UI.WriteLine("stand {0} NOT ranked.", stand.MapCode); return(false); } } } return(true); }
//--------------------------------------------------------------------- /// <summary> /// Adds a stand to the management area. /// </summary> public void Add(Stand stand) { stands.Add(stand); area += stand.ActiveArea; //Model.Core.UI.WriteLine("ma {0} now has area {1}", mapCode, area); stand.ManagementArea = this; }
/// <summary> /// Reads the input map of stands. /// </summary> /// <param name="path"> /// Path to the map. /// </param> public static void ReadMap(string path) { Stand stand; Dictionary <uint, Stand> stands = new Dictionary <uint, Stand>(); IInputRaster <UIntPixel> map; try { map = Model.Core.OpenRaster <UIntPixel>(path); } catch (FileNotFoundException) { string mesg = string.Format("Error: The file {0} does not exist", path); throw new System.ApplicationException(mesg); } if (map.Dimensions != Model.Core.Landscape.Dimensions) { string mesg = string.Format("Error: The input map {0} does not have the same dimension (row, column) as the ecoregions map", path); throw new System.ApplicationException(mesg); } using (map) { UIntPixel pixel = map.BufferPixel; foreach (Site site in Model.Core.Landscape.AllSites) { map.ReadBufferPixel(); uint mapCode = pixel.MapCode.Value; if (site.IsActive && SiteVars.ManagementArea[site] != null) { if (stands.TryGetValue(mapCode, out stand)) { //if the stand is already in the dictionary, check if it is in the same management area. //if it's not in the same MA, throw exception. if (SiteVars.ManagementArea[site] != stand.ManagementArea) { string mesg = string.Format("Stand {0} is in management areas {1} and {2}", stand.MapCode, stand.ManagementArea.MapCode, SiteVars.ManagementArea[site].MapCode); throw new System.ApplicationException(mesg); } } //valid site location which has not been keyed by the dictionary. else { //assign stand (trygetvalue set it to null when it wasn't found in the dictionary) stand = new Stand(mapCode); //add this stand to the correct management area (pointed to by the site) SiteVars.ManagementArea[site].Add(stand); stands[mapCode] = stand; } //add this site to this stand stand.Add((ActiveSite)site); } } } }
//--------------------------------------------------------------------- protected void AddMaNeighbor(Stand neighbor) { Require.ArgumentNotNull(neighbor); if (!ma_neighbors.Contains(neighbor)) { ma_neighbors.Add(neighbor); } }
//--------------------------------------------------------------------- //mark the whole area selected as harvested IEnumerable <ActiveSite> ISiteSelector.SelectSites(Stand stand) { areaSelected = stand.ActiveArea; stand.MarkAsHarvested(); //mark this stand's event id stand.EventId = EventId.MakeNewId(); return(stand); }
//--------------------------------------------------------------------- /// <summary> /// Schedules the next harvest for a stand that's been set aside /// (reserved). /// </summary> protected void ScheduleNextHarvest(Stand stand) { int nextTimeToHarvest = Model.Core.CurrentTime + repeatHarvest.Interval; if (nextTimeToHarvest <= EndTime) { reservedStands.Enqueue(new ReservedStand(stand, nextTimeToHarvest)); } }
//--------------------------------------------------------------------- /// <summary> /// Gets the ranking for an unharvested stand from among the whole set /// of stand rankings. /// </summary> public StandRanking GetRanking(Stand stand) { // Search backward through the stand rankings because unharvested // stands are at the end of the list. for (int i = rankings.Length - 1; i >= 0; i--) { if (rankings[i].Stand == stand) { return(rankings[i]); } } //throw new System.ApplicationException("ERROR: Stand not found in rankings"); //instead of throwing an exception, just return 0 rankings[0].Stand = stand; rankings[0].Rank = 0; return(rankings[0]); }
//--------------------------------------------------------------------- /// <summary> /// Harvests the stands that have repeat harvests scheduled for the /// current time step. /// </summary> public void HarvestReservedStands() { while (reservedStands.Count > 0 && reservedStands.Peek().NextTimeToHarvest <= Model.Core.CurrentTime) { //Stand stand = reservedStands.Dequeue().Stand; Stand stand = reservedStands.Peek().Stand; repeatHarvest.Harvest(stand); stand = reservedStands.Dequeue().Stand; if (isMultipleRepeatHarvest) { ScheduleNextHarvest(stand); } } }
//--------------------------------------------------------------------- void IStandRankingMethod.RankStands(List <Stand> stands, StandRanking[] rankings) { InitializeForRanking(stands, stands.Count); for (int i = 0; i < stands.Count; i++) { Stand stand = stands[i]; double rank = 0; if (!stand.IsSetAside) { //check if stand meets all the ranking requirements bool meetsAllRequirements = true; foreach (IRequirement requirement in requirements) { if (!requirement.MetBy(stand)) { meetsAllRequirements = false; //set stand rank to 0 rankings[i].Rank = 0; break; } } //if the stand meets all the requirements and is not set-aside,, get its rank if (meetsAllRequirements) { rank = ComputeRank(stand, i); } //otherwise, rank it 0 (so it will not be harvested.) else { rank = 0; //Model.Core.UI.WriteLine(" Stand {0} did not meet its requirements.", stand.MapCode); } } else { rankings[i].Rank = 0; } rankings[i].Stand = stand; rankings[i].Rank = rank; //assign rank to stand //Model.Core.UI.WriteLine(" Stand {0} rank = {1}.", rankings[i].Stand.MapCode, rankings[i].Rank); } }
//--------------------------------------------------------------------- public void Add(ActiveSite site) { siteLocations.Add(site.Location); this.activeArea = siteLocations.Count * Model.Core.CellArea; //set site var SiteVars.Stand[site] = this; //loop- really just 2 locations, relative (-1, 0) and relative (0, -1) foreach (RelativeLocation neighbor_loc in neighborsAboveAndLeft) { //check this site for neighbors that are different Site neighbor = site.GetNeighbor(neighbor_loc); if (neighbor != null && neighbor.IsActive) { //declare a stand with this site as its index. Stand neighbor_stand = SiteVars.Stand[neighbor]; //check for non-null stand //also, only allow stands in same management area to be called neighbors if (neighbor_stand != null && this.ManagementArea == neighbor_stand.ManagementArea) { //if neighbor_stand is different than this stand, then it is a true //neighbor. add it as a neighbor and add 'this' as a neighbor of that. if (this != neighbor_stand) { //add neighbor_stand as a neighboring stand to this AddNeighbor(neighbor_stand); //add this as a neighboring stand to neighbor_stand neighbor_stand.AddNeighbor(this); } } //take into account other management areas just for stand-adjacency issue else if (neighbor_stand != null && this.ManagementArea != neighbor_stand.ManagementArea) { if (this != neighbor_stand) { //add neighbor_stand as a ma-neighboring stand to this AddMaNeighbor(neighbor_stand); //add this as a ma-neighbor stand to neighbor_stand neighbor_stand.AddMaNeighbor(this); } } } } }
//--------------------------------------------------------------------- /// <summary> /// Harvests a stand (and possibly its neighbors) according to the /// repeat-harvest's site-selection method. /// </summary> /// <returns> /// The area that was harvested (units: hectares). /// </returns> public override void Harvest(Stand stand) { if (stand.IsSetAside) { CohortSelector = additionalCohortSelector; SpeciesToPlant = additionalSpeciesToPlant; SiteSelector = additionalSiteSelector; // new CompleteStand(); // //if(this.SiteSelectionMethod.GetType() == Landis.Extension.BiomassHarvest.PartialStandSpreading) // SiteSelector = BiomassHarvest.WrapSiteSelector(SiteSelector); } else { CohortSelector = initialCohortSelector; SpeciesToPlant = initialSpeciesToPlant; } base.Harvest(stand); return; }
//--------------------------------------------------------------------- /// <summary> /// Computes the rank for a stand. /// </summary> /// <remarks> /// Stands are ranked by age class so that over time harvesting will /// result in an even distribution of sites by age classes. /// </remarks> protected override double ComputeRank(Stand stand, int i) { double freq = 0.0; //find where the stands of this age are in the array //and return that frequency from the freq_array int k = 0; for (k = 0; k < age_count; k++) { if (stand.Age == age_array[k]) { freq = freq_array[k]; //Model.Core.UI.WriteLine("stand {0}.\nreturning age = {1} and freq = {2}", stand.MapCode, age_array[k], freq); //break loop when freq for this stand has been found break; } } //rank = freq * e^(age / 10) <-- using age / 10 to get a smaller number return(freq * (System.Math.Exp(stand.Age / 10))); }
//--------------------------------------------------------------------- /// <summary> /// Adds a stand's unharvested neighbors and their rankings to a /// sorted list of stand rankings. /// </summary> /// <remarks> /// The stand rankings are in highest to lowest order. A neighbor is /// only added to the list if its rank is > 0 and it isn't already in /// the list. /// </remarks> public void AddUnharvestedNeighbors(Stand stand, List <StandRanking> neighborRankings) { foreach (Stand neighbor in stand.Neighbors) { if (!neighbor.Harvested) { bool inList = false; foreach (StandRanking ranking in neighborRankings) { if (ranking.Stand == neighbor) { inList = true; break; } } if (inList) { continue; } StandRanking neighborRanking = GetRanking(neighbor); if (neighborRanking.Rank <= 0) { continue; } int i; for (i = 0; i < neighborRankings.Count; i++) { if (neighborRankings[i].Rank < neighborRanking.Rank) { break; } } //Model.Core.UI.WriteLine(" place={0}, rank={1}.", i, neighborRanking.Rank); neighborRankings.Insert(i, neighborRanking); } } }
} // private bool spreadFromStand() { //-------------------------------------------------------------- // For the current stand, enqueue all the eligible sites onto // the harvestableSites queue private bool EnqueueEligibleSites(Stand crntStand) { bool rtrnVal = false; int sitesHarvested = 0, sitesChecked = 0; foreach (ActiveSite crntSite in crntStand) { sitesChecked++; if (SiteVars.TimeSinceLastDamage(crntSite) >= minTimeSinceDamage) { sitesHarvested++; harvestableSites.Enqueue(crntSite); areaSelected += Model.Core.CellArea; rtrnVal = true; } } return(rtrnVal); } // private void EnqueueEligibleSites() {
//--------------------------------------------------------------------- /// <summary> /// Harvests a stand (and possibly its neighbors) according to the /// prescription's site-selection method. /// </summary> /// <returns> /// The area that was harvested (units: hectares). /// </returns> // This is called by AppliedPrescription public virtual void Harvest(Stand stand) { //set prescription name for stand stand.PrescriptionName = this.Name; stand.HarvestedRank = AppliedPrescription.CurrentRank; stand.LastPrescription = this; stand.MinTimeSinceDamage = this.minTimeSinceDamage; //set current stand currentStand = stand; currentStand.ClearDamageTable(); // SelectSites(stand) is where either complete, complete stand spreading, or partial stand // spreading are activated. // tjs - This is what gets the sites that will be harvested foreach (ActiveSite site in siteSelector.SelectSites(stand)) { currentSite = site; SiteVars.Cohorts[site].RemoveMarkedCohorts(this); if (SiteVars.CohortsDamaged[site] > 0) { stand.LastAreaHarvested += Model.Core.CellArea; SiteVars.Prescription[site] = this; } if (speciesToPlant != null) { Reproduction.ScheduleForPlanting(speciesToPlant, site); } } return; }
//--------------------------------------------------------------------- /// <summary> /// Harvests a stand (and possibly its neighbors) according to the /// repeat-harvest's site-selection method. /// </summary> /// <returns> /// The area that was harvested (units: hectares). /// </returns> public override void Harvest(Stand stand) { if (stand.IsSetAside) { SiteSelector = additionalSiteSelector; } base.Harvest(stand); harvestedStands.Clear(); // Add stand to list only if actually harvested if (stand.LastAreaHarvested > 0) { harvestedStands.Add(stand); } if (spreadingSiteSelector != null) { harvestedStands.AddRange(spreadingSiteSelector.HarvestedNeighbors); } return; // areaHarvested; }
//--------------------------------------------------------------------- /// <summary> /// use combination of all rules in rule_list to determine if this stand meets this inclusion requirement /// </summary> bool IRequirement.MetBy(Stand stand) { int optionalStatements = 0; int optionalStatementsMet = 0; //loop through each rule checking it against this stand foreach (InclusionRule rule in rule_list) { //boolean for condition checking bool meets = false; //assign a bool for the generic condition: there are enough of this rule's species in the stand. //meets = check_rule(stand, stand_cohorts, rule, get_key(key_start, rule.RuleAgeRange), stand.SiteCount, rule.PercentOfCells); meets = CheckRule(stand, rule); //forbidden if (rule.InclusionType == "Forbidden") { if (meets) { //this stand meets a 'forbidden' rule so it is disqualified (can return false right away) // Model.Core.UI.WriteLine("returning false1"); return(false); } } //required else if (rule.InclusionType == "Required") { if (!meets) { //this stand violates a 'required' rule so it is disqualified (can return false right away) //Model.Core.UI.WriteLine("returning false2"); return(false); } else { //this stand does not violate this 'required' rule. in case of no optionals, //it must know that it has fulfilled a required rule to return true. // Model.Core.UI.WriteLine("returning true1"); //required_flag = true; } } //optional else if (rule.InclusionType == "Optional") { //mark that there has been an optional rule even included in the requirement optionalStatements++; if (meets) { //this stand met an 'optional' rule so it is still qualified (but can't return anything because it //may not be done checking all rules against this stand) //however, mark that at least 1 optional rule is fulfilled optionalStatementsMet++; } } //} //do nothing if key is not found. //catch (KeyNotFoundException) { // Model.Core.UI.WriteLine("Key Not Found Exception"); //} } if (optionalStatements > 1 && optionalStatementsMet < 1) { return(false); } // Model.Core.UI.WriteLine("returning default truth!!"); return(true); }
//--------------------------------------------------------------------- // 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); }
//--------------------------------------------------------------------- /// <summary> /// Computes the rank for a stand. /// </summary> protected abstract double ComputeRank(Stand stand, int i);
//--------------------------------------------------------------------- IEnumerable <ActiveSite> ISiteSelector.SelectSites(Stand stand) { initialStand = stand; return(this); }
} // IEnumerator<ActiveSite> IEnumerable<ActiveSite>.GetEnumerator() private static ActiveSite GetNeighboringSite(List <Stand> harvestedNeighbors, Stand neighborStand) { // get a shared-edge site from any one of the previously harvested neighboring stands // tjs - changed to allow a null return. Sometimes there are not adjacent sites ActiveSite returnSite; foreach (Site current_site in neighborStand) { //check if one of its neighbors is on the edge of the initialStand foreach (RelativeLocation relloc in all_neighbor_locations) { //if it's a valid site and is on the edge if (current_site.GetNeighbor(relloc) != null && current_site.GetNeighbor(relloc).IsActive) { foreach (Stand stand in harvestedNeighbors) { if (SiteVars.Stand[current_site.GetNeighbor(relloc)] == stand) { returnSite = (ActiveSite)current_site; return(returnSite); } } } } } return(new ActiveSite()); }
//--------------------------------------------------------------------- /// <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) bool applyPrescription = false; if (prescription.BeginTime <= Model.Core.CurrentTime && prescription.EndTime >= Model.Core.CurrentTime) { if (!(prescription is AppliedRepeatHarvest)) { applyPrescription = true; } else if (prescription is AppliedRepeatHarvest && Model.Core.CurrentTime > 0 && !((AppliedRepeatHarvest)prescription).HasBeenHarvested) { applyPrescription = true; ((AppliedRepeatHarvest)prescription).HasBeenHarvested = true; } } // if(prescription.BeginTime <= Model.Core.CurrentTime... if (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).HarvestReservedStands(); } } // 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 += prescription.AreaRemainingRatio; } 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] = prescription.AreaRemainingRatio / 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 = prescription.AreaRemainingRatio / 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 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 }
} // IEnumerator<ActiveSite> IEnumerable<ActiveSite>.GetEnumerator() //--------------------------------------------------------------------- // For the starting stand do partial stand spreading until either // we run out of stands or we have our target area private bool SpreadFromStand(Stand startingStand) { List <Stand> standsConsidered = new List <Stand>(); // a list of every stand we have thought about considering // used to prevent considering a stand more than once List <Stand> standsToConsiderAll = new List <Stand>(); List <StandRanking> standsToConsiderRankings = new List <StandRanking>(); bool rtrnVal = false; Stand crntStand; double crntRank; // If we have a valid starting stand, put it on the list to // consider if (startingStand != null && !startingStand.IsSetAside) { standsToConsiderRankings.Insert(0, GetRanking(startingStand)); standsToConsiderAll.Add(startingStand); } // Miranda and Scheller testing methods to make repeat harvest work with stand spreading. //if (startingStand != null && startingStand.IsSetAside) // if( startingStand.LastPrescription. // //if (startingStand.LastPrescription.SiteSelectionMethod.ToString() == "Landis.Harvest.CompleteStandSpreading") // { // standsToConsiderRankings.Insert(0, GetRanking(startingStand)); // standsToConsiderAll.Add(startingStand); // return true; // } while (standsToConsiderRankings.Count > 0 && standsToConsiderRankings[0].Rank > 0 && areaSelected < maxTargetSize) { // Get the stand to work with for this loop iteration crntStand = standsToConsiderRankings[0].Stand; crntRank = standsToConsiderRankings[0].Rank; standsToConsiderRankings.RemoveAt(0); // If the stand is set aside, it doesn't get processed if (crntStand.IsSetAside) { continue; } // Enqueue the eligible sites and put the stand // on the appropriate queue(s) if (EnqueueEligibleSites(crntStand)) { standsToHarvest.Enqueue(crntStand); standsToHarvestRankings.Enqueue(crntRank); } else { standsToReject.Add(crntStand); } standsConsidered.Add(crntStand); if (areaSelected < maxTargetSize) { // Get the neighbors and put them on the // standsToConsider queue foreach (Stand neighbor in crntStand.Neighbors) { if (!standsConsidered.Contains(neighbor) && !standsToConsiderAll.Contains(neighbor) && !neighbor.Harvested) { StandRanking neighborRanking = GetRanking(neighbor); standsToConsiderAll.Add(neighbor); if (neighborRanking.Rank <= 0) { continue; } int i; for (i = 0; i < standsToConsiderRankings.Count; i++) { if (standsToConsiderRankings[i].Rank < neighborRanking.Rank) { break; } } standsToConsiderRankings.Insert(i, neighborRanking); } // if(!standsConsidered.Contains(neighbor) } // foreach (Stand neighbor in crntStand.Neighbors) } // if(areaSelected >= maxTargetSize) } // while (standsToConsider.Count > 0 && .. // If we found enough to meet our goal, return true, // otherwise return the default of false. if (areaSelected >= minTargetSize) { rtrnVal = true; } return(rtrnVal); } // private bool spreadFromStand() {
//-------------------------------------------------------------- // For the starting stand do partial stand spreading until either // we run out of stands or we have our target area private bool SpreadFromStand(Stand startingStand) { List <Stand> standsConsidered = new List <Stand>(); // a list of every stand we have thought about considering // used to prevent considering a stand more than once List <Stand> standsToConsiderAll = new List <Stand>(); List <StandRanking> standsToConsiderRankings = new List <StandRanking>(); bool rtrnVal = false; Stand crntStand; double crntRank; ActiveSite startingSite;// = null; // If we have a valid starting stand, put it on the list to // consider if (startingStand != null && !startingStand.IsSetAside) { standsToConsiderRankings.Insert(0, GetRanking(startingStand)); standsToConsiderAll.Add(startingStand); } while (standsToConsiderRankings.Count > 0 && standsToConsiderRankings[0].Rank > 0 && areaSelected < maxTargetSize) { // Get the stand to work with for this loop iteration crntStand = standsToConsiderRankings[0].Stand; crntRank = standsToConsiderRankings[0].Rank; standsToConsiderRankings.RemoveAt(0); // If the stand is not set aside, Get the starting site if (!crntStand.IsSetAside) { // first stand starts at a random site, subsequent // stands start at an adjoining site if (standsConsidered.Count == 0) { startingSite = crntStand.GetRandomActiveSite; } else { startingSite = GetNeighboringSite(standsConsidered, crntStand); if (startingSite == false) { standsToReject.Add(crntStand); continue; } } } else { // if the stand is set aside, it doesn't get processed // and its neighbors don't go on the stand list standsToReject.Add(crntStand); continue; } // Enqueue the eligible sites and put the stand // on the appropriate queue(s) if (EnqueueEligibleSites(startingSite, crntStand)) { standsToHarvest.Enqueue(crntStand); standsToHarvestRankings.Enqueue(crntRank); } else { standsToReject.Add(crntStand); } standsConsidered.Add(crntStand); if (areaSelected < maxTargetSize) { // Get the neighbors and put them on the // standsToConsider queue foreach (Stand neighbor in crntStand.Neighbors) { if (!standsConsidered.Contains(neighbor) && !standsToConsiderAll.Contains(neighbor) && !neighbor.Harvested) { StandRanking neighborRanking = GetRanking(neighbor); standsToConsiderAll.Add(neighbor); if (neighborRanking.Rank <= 0) { continue; } int i; for (i = 0; i < standsToConsiderRankings.Count; i++) { if (standsToConsiderRankings[i].Rank < neighborRanking.Rank) { break; } } standsToConsiderRankings.Insert(i, neighborRanking); } } } } // If we found enough to meet our goal, return true, // otherwise return the default of false. if (areaSelected >= minTargetSize) { rtrnVal = true; } return(rtrnVal); }
//-------------------------------------------------------------- // 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); }
//--------------------------------------------------------------------- /// <summary> /// Sets a stand aside for multiple additional harvests. /// </summary> public void SetAsideForMultipleHarvests(Stand stand) { stand.SetAsideUntil(EndTime); }
//--------------------------------------------------------------------- /// <summary> /// Computes the rank for a stand. /// </summary> /// <remarks> /// The stand's rank is a random number. /// </remarks> protected override double ComputeRank(Stand stand, int i) { //just return current rank from the list return(rank_array[i]); }