Пример #1
0
        /// <summary>
        /// Calculates normalized value for goal prioritizing.
        /// </summary>
        /// <param name="agent"></param>
        /// <param name="goal"></param>
        /// <param name="goalState"></param>
        /// <returns></returns>
        double CalculateNormalizedValue(IAgent agent, Goal goal, GoalState goalState)
        {
            double maxPossibleDifference = 0;


            RuleLayerConfiguration layerConfiguration = agent.AssignedRules.Where(rule => rule.Consequent.Param == goal.ReferenceVariable && (rule.Layer.LayerConfiguration.ConsequentValueInterval != null && rule.Layer.LayerConfiguration.ConsequentValueInterval.Length == 2))
                                                        .Select(rule => rule.Layer.LayerConfiguration).FirstOrDefault();

            if (layerConfiguration != null)
            {
                maxPossibleDifference = Math.Max(Math.Abs(layerConfiguration.MaxValue(agent) - goalState.Value), Math.Abs(layerConfiguration.MinValue(agent) - goalState.Value));
            }
            else
            {
                if (goal.Tendency == "EqualToOrAboveFocalValue" || goal.Tendency == "Maximize")
                {
                    maxPossibleDifference = (string.IsNullOrEmpty(goal.FocalValueReference) ? goalState.FocalValue : (double)agent[goal.FocalValueReference]);
                }

                if (goal.Tendency == "Minimize")
                {
                    double maxValue = agent.AssignedRules.Where(rule => rule.Consequent.Param == goal.ReferenceVariable)
                                      .Select(rule => string.IsNullOrEmpty(rule.Consequent.VariableValue) ? (double)rule.Consequent.Value : (double)agent[rule.Consequent.VariableValue])
                                      .Max();

                    maxPossibleDifference = maxValue - goalState.PriorValue;
                }

                //if (goal.Tendency == "EqualToOrBelowFocalValue")
                //{
                //    double maxValue = agent.AssignedRules.Where(rule => rule.Consequent.Param == goal.ReferenceVariable)
                //        .Select(rule => string.IsNullOrEmpty(rule.Consequent.VariableValue) ? (double)rule.Consequent.Value : (double)agent[rule.Consequent.VariableValue])
                //        .Max();

                //    maxPossibleDifference = maxValue - goalState.PriorValue;
                //}
            }

            return(Math.Abs(goalState.DiffCurrentAndPrior / maxPossibleDifference));
        }
Пример #2
0
        /// <summary>
        /// Executes agent innovation process for specific site
        /// </summary>
        /// <param name="agent"></param>
        /// <param name="lastIteration"></param>
        /// <param name="goal"></param>
        /// <param name="layer"></param>
        public void Execute(IAgent agent, LinkedListNode <Dictionary <IAgent, AgentState> > lastIteration, Goal goal,
                            RuleLayer layer, ActiveSite site)
        {
            Dictionary <IAgent, AgentState> currentIteration = lastIteration.Value;
            Dictionary <IAgent, AgentState> priorIteration   = lastIteration.Previous.Value;

            //gets prior period activated rule
            RuleHistory history         = priorIteration[agent].RuleHistories[site];
            Rule        priorPeriodRule = history.Activated.Single(r => r.Layer == layer);

            LinkedListNode <Dictionary <IAgent, AgentState> > tempNode = lastIteration.Previous;

            //if prior period rule is do nothing rule then looking for any do something rule
            while (priorPeriodRule.IsAction == false && tempNode.Previous != null)
            {
                tempNode = tempNode.Previous;

                history = tempNode.Value[agent].RuleHistories[site];

                priorPeriodRule = history.Activated.Single(r => r.Layer == layer);
            }

            //if the layer or prior period rule are modifiable then generate new rule
            if (layer.LayerConfiguration.Modifiable || (!layer.LayerConfiguration.Modifiable && priorPeriodRule.IsModifiable))
            {
                RuleLayerConfiguration parameters = layer.LayerConfiguration;

                Goal selectedGoal = goal;

                GoalState selectedGoalState = lastIteration.Value[agent].GoalsState[selectedGoal];

                #region Generating consequent
                double min = parameters.MinValue(agent);
                double max = parameters.MaxValue(agent);

                double consequentValue = priorPeriodRule.Consequent.Value;

                switch (selectedGoalState.AnticipatedDirection)
                {
                case AnticipatedDirection.Up:
                {
                    if (RuleLayerConfiguration.ConvertSign(parameters.ConsequentRelationshipSign[goal.Name]) == ConsequentRelationship.Positive)
                    {
                        max = Math.Abs(consequentValue - max);

                        consequentValue += (Math.Abs(PowerLawRandom.GetInstance.Next(min, max) - max));
                    }
                    if (RuleLayerConfiguration.ConvertSign(parameters.ConsequentRelationshipSign[goal.Name]) == ConsequentRelationship.Negative)
                    {
                        max = Math.Abs(consequentValue - min);

                        consequentValue -= (Math.Abs(PowerLawRandom.GetInstance.Next(min, max) - max));
                    }

                    break;
                }

                case AnticipatedDirection.Down:
                {
                    if (RuleLayerConfiguration.ConvertSign(parameters.ConsequentRelationshipSign[goal.Name]) == ConsequentRelationship.Positive)
                    {
                        max = Math.Abs(consequentValue - min);

                        consequentValue -= (Math.Abs(PowerLawRandom.GetInstance.Next(min, max) - max));
                    }
                    if (RuleLayerConfiguration.ConvertSign(parameters.ConsequentRelationshipSign[goal.Name]) == ConsequentRelationship.Negative)
                    {
                        max = Math.Abs(consequentValue - max);

                        consequentValue += (Math.Abs(PowerLawRandom.GetInstance.Next(min, max) - max));
                    }

                    break;
                }

                default:
                {
                    throw new Exception("Not implemented for AnticipatedDirection == 'stay'");
                }
                }

                RuleConsequent consequent = RuleConsequent.Renew(priorPeriodRule.Consequent, consequentValue);
                #endregion


                #region Generating antecedent
                List <RuleAntecedentPart> antecedentList = new List <RuleAntecedentPart>(priorPeriodRule.Antecedent.Length);

                foreach (RuleAntecedentPart antecedent in priorPeriodRule.Antecedent)
                {
                    dynamic newConst = agent[antecedent.Param];

                    RuleAntecedentPart newAntecedent = RuleAntecedentPart.Renew(antecedent, newConst);

                    antecedentList.Add(newAntecedent);
                }
                #endregion

                AgentState agentState = currentIteration[agent];

                Rule generatedRule = Rule.Renew(priorPeriodRule, antecedentList.ToArray(), consequent);


                //change base ai values for the new rule
                double consequentChangeProportion = (generatedRule.Consequent.Value - priorPeriodRule.Consequent.Value) / (double)priorPeriodRule.Consequent.Value;


                Dictionary <Goal, double> baseAI = agent.AnticipationInfluence[priorPeriodRule];

                Dictionary <Goal, double> proportionalAI = new Dictionary <Goal, double>();



                agent.AssignedGoals.ForEach(g =>
                {
                    double ai = baseAI[g];

                    ConsequentRelationship relationship = RuleLayerConfiguration.ConvertSign(priorPeriodRule.Layer.LayerConfiguration.ConsequentRelationshipSign[g.Name]);

                    double difference = Math.Abs(ai * consequentChangeProportion);


                    switch (selectedGoalState.AnticipatedDirection)
                    {
                    case AnticipatedDirection.Up:
                        {
                            if (relationship == ConsequentRelationship.Positive)
                            {
                                ai += difference;
                            }
                            else
                            {
                                ai -= difference;
                            }

                            break;
                        }

                    case AnticipatedDirection.Down:
                        {
                            if (relationship == ConsequentRelationship.Positive)
                            {
                                ai -= difference;
                            }
                            else
                            {
                                ai += difference;
                            }

                            break;
                        }
                    }

                    proportionalAI.Add(g, ai);
                });


                //add the generated rule to the prototype's mental model and assign one to the agent's mental model

                if (agent.Prototype.IsSimilarRuleExists(generatedRule) == false)
                {
                    //add to the prototype and assign to current agent
                    agent.AddRule(generatedRule, layer, proportionalAI);
                }
                else if (agent.AssignedRules.Any(rule => rule == generatedRule) == false)
                {
                    //assign to current agent only
                    agent.AssignNewRule(generatedRule, proportionalAI);
                }



                if (layer.Set.Layers.Count > 1)
                {
                    //set consequent to actor's variables for next layers
                    generatedRule.Apply(agent);
                }
            }
        }