Example #1
0
 public ConditionalRSL(String attribute, Criterias criteria)
 {
     BinValues      = new Dictionary <int, double>();
     _values        = null;
     this.Attribute = attribute;
     _criteria      = criteria;
     _isAscending   = SimulationMessaging.GetAttributeAscending(attribute);
 }
Example #2
0
        /// <summary>
        /// True if this target is met.
        /// </summary>
        /// <returns></returns>
        public bool IsTargetMet(int nYear)
        {
            double dTargetArea = 0;

            if (m_hashYearTargetArea.Contains(nYear))
            {
                dTargetArea = (double)this.m_hashYearTargetArea[nYear];
            }


            double dSumArea = 0;

            if (this.m_hashYearSumArea.Contains(nYear))
            {
                dSumArea = (double)this.m_hashYearSumArea[nYear];
            }
            if (dSumArea == 0)
            {
                return(true);
            }

            double dTarget = dTargetArea / dSumArea;
            double dGoal   = this.Target;

            if (SimulationMessaging.GetAttributeAscending(this.Attribute))
            {
                if (dGoal < dTarget)
                {
                    return(true);
                }
            }
            else
            {
                if (dGoal > dTarget)
                {
                    return(true);
                }
            }
            return(false);
        }
Example #3
0
        /// <summary>
        ///
        /// Calculates the next years values AND files in the Answer array for base RemainingLife and Benefit cost.
        /// </summary>
        /// <param name="hashAttributeValues">Values for other attributes</param>
        /// <returns>Value for next year</returns>
        public double IterateOneYearEquation(Hashtable hashAttributeValues, int apparentAgeHint, out double apparentAge, out bool bOutOfRange)
        {
            double increment;
            double delta;
            double ratio;
            double dAnswer;
            double dAge = 0;

            apparentAge = 0;
            if (Shift)
            {
                dAge = double.Parse(hashAttributeValues["AGE"].ToString());
            }

            bOutOfRange = true;
            double dValue = double.Parse(hashAttributeValues[this.Attribute].ToString());

            //TODO: Does this need to be solved everytime on
            if (!_isAgeOnly)
            {
                Solve(hashAttributeValues);
            }

            //Check if 99 year value is input
            if (dValue > _answer[98] && !SimulationMessaging.GetAttributeAscending(Attribute))
            {
                bOutOfRange = false;
                return(dValue);
            }
            else if (dValue < _answer[98] && SimulationMessaging.GetAttributeAscending(Attribute))
            {
                bOutOfRange = false;
                return(dValue);
            }
            double dMinimum;
            double dMaximum;

            for (int i = 0; i < 98; i++)
            {
                //This eliminates ascending / descending problem.  Just looking for a number in between.
                if ((_answer[i] >= dValue && dValue > _answer[i + 1]) || (_answer[i] <= dValue && dValue < _answer[i + 1]))
                {
                    if (!Shift || i == 0 || dAge == 0)
                    {
                        delta     = dValue - _answer[i + 1];
                        increment = _answer[i] - _answer[i + 1];
                        if (increment == 0)
                        {
                            return(_answer[i + 1]);
                        }
                        ratio     = 1 - (delta / increment);
                        increment = _answer[i + 1] - _answer[i + 2];
                        delta     = ratio * increment;
                        dAnswer   = _answer[i + 1] - delta;
                    }
                    else // Must be SHIFT and i not 0
                    {
                        delta     = dValue - _answer[i + 1];
                        increment = _answer[i] - _answer[i + 1];
                        double dApparentAge   = (double)i + (1 - (delta / increment)); // Determine apparent age
                        double dApparentRatio = dApparentAge / dAge;                   // Determine rate that age is changing.
                        double dNextAge       = dApparentRatio + dApparentAge;
                        int    iNextAge       = (int)Math.Floor(dNextAge);
                        double dNextRatio     = dNextAge - Math.Floor(dNextAge);
                        if (iNextAge < 99)
                        {
                            increment = _answer[iNextAge] - _answer[iNextAge + 1];
                            delta     = dNextRatio * increment;
                            dAnswer   = _answer[iNextAge] - delta;
                        }
                        else
                        {
                            dAnswer = _answer[99];
                        }
                    }
                    if (SimulationMessaging.GetAttributeMinimum(this.Attribute, out dMinimum))
                    {
                        if (dMinimum > dAnswer)
                        {
                            return(dMinimum);
                        }
                    }
                    if (SimulationMessaging.GetAttributeMaximum(this.Attribute, out dMaximum))
                    {
                        if (dMaximum < dAnswer)
                        {
                            return(dMaximum);
                        }
                    }
                    bOutOfRange = false;
                    return(dAnswer);
                }
            }

            dValue = _answer[0];
            if (SimulationMessaging.GetAttributeMinimum(this.Attribute, out dMinimum))
            {
                if (dMinimum > dValue)
                {
                    return(dMinimum);
                }
            }

            if (SimulationMessaging.GetAttributeMaximum(this.Attribute, out dMaximum))
            {
                if (dMaximum < dValue)
                {
                    return(dMaximum);
                }
            }
            return(dValue);
        }
Example #4
0
        public CalculateBenefit(int year,
                                Treatments treatmentToEvaluate,
                                List <Deteriorate> deteriorates,
                                List <CalculatedAttribute> calculatedAttributes,
                                List <Consequences> noTreatmentConsequences,
                                List <Committed> committedProjects,
                                Dictionary <string, List <AttributeChange> > committedConsequences,
                                Dictionary <string, CommittedEquation> committedEquation,
                                List <Treatments> simulationTreatments)
        {
            Year                        = year;
            Treatment                   = treatmentToEvaluate;
            Deteriorates                = deteriorates;
            CalculatedAttributes        = calculatedAttributes;
            NoTreatmentConsequences     = noTreatmentConsequences;
            CommittedProjects           = committedProjects;
            CommittedConsequences       = committedConsequences;
            CommittedEquations          = committedEquation;
            IsBenefitAttributeAscending = SimulationMessaging.GetAttributeAscending(SimulationMessaging.Method.BenefitAttribute);
            IsBenefitCalculated         = calculatedAttributes.Any(a => a.Attribute == SimulationMessaging.Method.BenefitAttribute);
            CurrentDeteriorate          = new List <Deteriorate>();
            SimulationTreatments        = simulationTreatments;

            //Need to input Deficient
            _isNoTreatmentCircular = false;

            //See if any of the no treatment consequences effect the criteria.
            //If they do not there is no need recalculate/resolve
            var attributesConsequence = new List <string>();

            foreach (var consequence in NoTreatmentConsequences)
            {
                foreach (var attribute in consequence.Attributes)
                {
                    if (!attributesConsequence.Contains(attribute))
                    {
                        attributesConsequence.Add(attribute);
                    }
                }
                if (consequence.Criteria?.CriteriaAttributes != null)
                {
                    foreach (var attribute in consequence.Criteria.CriteriaAttributes)
                    {
                        if (_isNoTreatmentCircular)
                        {
                            break;
                        }

                        foreach (var calculated in CalculatedAttributes)
                        {
                            if (calculated.Attribute != attribute)
                            {
                                continue;
                            }
                            //If a attribute is calculated it could result in a circular condition (maybe)
                            _isNoTreatmentCircular = true;
                            break;
                        }
                        //If the criteria is modified by a consequence it can change (even with no treatment)
                        if (!attributesConsequence.Contains(attribute))
                        {
                            continue;
                        }
                        _isNoTreatmentCircular = true;
                    }
                }
            }
        }
Example #5
0
        private double SolveBenefitCost(Hashtable attributeValue, out Hashtable nextAttributeValue, out string rlHash)
        {
            rlHash = "";
            //Set remaining life to 99 years in the case no attribute has a valid remaining life.
            var hashRemainingLife      = new Dictionary <RemainingLife, double>();
            var previousAttributeValue = new Dictionary <RemainingLife, double>();
            var ascendingAttribute     = new Dictionary <string, bool>();

            foreach (var remainingLife in SimulationMessaging.RemainingLifes)
            {
                if (!hashRemainingLife.ContainsKey(remainingLife))
                {
                    hashRemainingLife.Add(remainingLife, 99);
                }
                if (!ascendingAttribute.ContainsKey(remainingLife.Attribute))
                {
                    ascendingAttribute.Add(remainingLife.Attribute, SimulationMessaging.GetAttributeAscending(remainingLife.Attribute));
                }
            }

            //Apply consequence of treatment
            nextAttributeValue = ApplyConsequences(Treatment.ConsequenceList, attributeValue);
            nextAttributeValue = SolveCalculatedFields(nextAttributeValue);
            var currentAttributeValue = new Hashtable();

            foreach (var key in attributeValue.Keys)
            {
                currentAttributeValue.Add(key, nextAttributeValue[key]);
            }



            double sumBenefit = 0;

            UpdateCurrentDeteriorate(currentAttributeValue);

            var apparentAgeHints = new Dictionary <string, int>();

            foreach (var deteriorate in CurrentDeteriorate)
            {
                apparentAgeHints.Add(deteriorate.Attribute, 0);
            }


            var noTreatmentConsequences = GetReducedSetConsequences(nextAttributeValue);

            //Calculate the 100 year benefit
            //Change to 50 year benefit
            for (var i = 0; i < 100; i++)
            {
                //Make sure the current deterioration equations are current (meet all criteria).
                UpdateCurrentDeteriorate(attributeValue);

                //// Deteriorate current deterioration model.
                foreach (var deteriorate in CurrentDeteriorate)
                {
                    if (!apparentAgeHints.ContainsKey(deteriorate.Attribute))
                    {
                        apparentAgeHints.Add(deteriorate.Attribute, 0);
                    }
                    currentAttributeValue[deteriorate.Attribute] =
                        deteriorate.IterateOneYear(currentAttributeValue, apparentAgeHints[deteriorate.Attribute], out double apparentAge);

                    apparentAgeHints[deteriorate.Attribute] = (int)apparentAge;
                }


                // Apply No Treatment or Committed Consequences (or Scheduled)
                var committed = CommittedProjects.Find(c => c.Year == Year);
                var scheduled = Treatment.Scheduleds.Find(s => s.ScheduledYear == i);

                //If both a committed and scheduled.  No benefit.  Can't do both!
                if (scheduled != null && committed != null)
                {
                    return(0);
                }

                //Only get here if scheduled and committed do notcollide.
                if (committed != null)
                {
                    if (!string.IsNullOrWhiteSpace(committed.ScheduledTreatmentId))
                    {
                        var scheduledTreatment =
                            SimulationTreatments.Find(f => f.TreatmentID == committed.ScheduledTreatmentId);
                        currentAttributeValue   = ApplyConsequences(scheduledTreatment.ConsequenceList, currentAttributeValue);
                        noTreatmentConsequences = GetReducedSetConsequences(currentAttributeValue);
                    }
                    else
                    {
                        currentAttributeValue   = ApplyCommittedConsequences(currentAttributeValue, committed);
                        noTreatmentConsequences = GetReducedSetConsequences(currentAttributeValue);
                    }
                }
                else if (scheduled != null)
                {
                    currentAttributeValue   = ApplyConsequences(scheduled.Treatment.ConsequenceList, currentAttributeValue);
                    noTreatmentConsequences = GetReducedSetConsequences(currentAttributeValue);
                }
                else
                {
                    currentAttributeValue = ApplyConsequences(noTreatmentConsequences, currentAttributeValue);
                }


                //// Solve calculated fields
                currentAttributeValue = SolveCalculatedFields(currentAttributeValue);
                //Look up Method.Benefit variable
                if (IsBenefitAttributeAscending)
                {
                    //For attributes that get smaller with deterioration.
                    if ((double)currentAttributeValue[SimulationMessaging.Method.BenefitAttribute] >
                        SimulationMessaging.Method.BenefitLimit)
                    {
                        sumBenefit += (double)currentAttributeValue[SimulationMessaging.Method.BenefitAttribute] -
                                      SimulationMessaging.Method.BenefitLimit;
                    }
                }
                else
                {
                    //For attributes that get larger with deterioration.
                    if ((double)currentAttributeValue[SimulationMessaging.Method.BenefitAttribute] <
                        SimulationMessaging.Method.BenefitLimit)
                    {
                        sumBenefit += SimulationMessaging.Method.BenefitLimit -
                                      (double)currentAttributeValue[SimulationMessaging.Method.BenefitAttribute.ToUpper()];
                    }
                }


                //Calculate remaining life if criteria matches.
                foreach (var remainingLife in SimulationMessaging.RemainingLifes)
                {
                    var storePrevious = false;
                    if (remainingLife.Criteria.IsCriteriaMet(currentAttributeValue))
                    {
                        if (ascendingAttribute[remainingLife.Attribute] && Convert.ToDouble(currentAttributeValue[remainingLife.Attribute]) > remainingLife.RemainingLifeLimit)
                        {
                            hashRemainingLife[remainingLife] = i;
                            //Need to store value of current so that when threshold is crossed can calculate partial.
                            storePrevious = true;
                        }

                        if (!ascendingAttribute[remainingLife.Attribute] && Convert.ToDouble(currentAttributeValue[remainingLife.Attribute]) < remainingLife.RemainingLifeLimit)
                        {
                            hashRemainingLife[remainingLife] = i;
                            storePrevious = true;
                        }

                        if (storePrevious)//The previous value was updated this loop.
                        {
                            if (!previousAttributeValue.ContainsKey(remainingLife))
                            {
                                previousAttributeValue.Add(remainingLife, Convert.ToDouble(currentAttributeValue[remainingLife.Attribute]));
                            }
                            else
                            {
                                previousAttributeValue[remainingLife] = Convert.ToDouble(currentAttributeValue[remainingLife.Attribute]);
                            }
                        }
                        else //Previous value was not updated.  If the previous value exists, calculate the exact remaining life now.
                        {
                            if (previousAttributeValue.ContainsKey(remainingLife))
                            {
                                var delta = (previousAttributeValue[remainingLife] - remainingLife.RemainingLifeLimit) / (previousAttributeValue[remainingLife] - Convert.ToDouble(currentAttributeValue[remainingLife.Attribute]));

                                hashRemainingLife[remainingLife] = hashRemainingLife[remainingLife] + delta;

                                previousAttributeValue.Remove(remainingLife); //So it does not recalculate remaining life.
                            }
                        }
                    }
                }
            }


            var minimumAttributeRemainingLife = new Dictionary <string, double>();

            foreach (var key in hashRemainingLife.Keys)
            {
                if (!minimumAttributeRemainingLife.ContainsKey(key.Attribute))
                {
                    minimumAttributeRemainingLife.Add(key.Attribute, hashRemainingLife[key]);
                }
                else
                {
                    if (minimumAttributeRemainingLife[key.Attribute] > hashRemainingLife[key])
                    {
                        minimumAttributeRemainingLife[key.Attribute] = hashRemainingLife[key];
                    }
                }
            }

            double minimumRemainingLife = 99;

            foreach (var key in minimumAttributeRemainingLife.Keys)
            {
                if (minimumAttributeRemainingLife[key] < minimumRemainingLife)
                {
                    minimumRemainingLife = minimumAttributeRemainingLife[key];
                }
                rlHash += key + "\t" + minimumAttributeRemainingLife[key].ToString("0.0") + "\n";
            }

            if (SimulationMessaging.Method.IsRemainingLife)
            {
                return(minimumRemainingLife);
            }
            else
            {
                return(sumBenefit);
            }
        }