/// <summary> /// Worker has finished a task, he push it to done in the TaskManager /// </summary> /// <param name="task"></param> public void SetDone(SymuTask task) { if (task is null) { throw new ArgumentNullException(nameof(task)); } if (!task.IsAssigned) { // Task has been cancelled return; } task.UnAssign(); var todo = ToDo.Contains(task); var inProgress = InProgress.Contains(task); if (todo) { ToDo.Remove(task); } else if (inProgress) { InProgress.Remove(task); } else { return; } task.SetDone(); if (_debug) { Done.Add(task); } // We don't want to track message as Task if (task.Parent is Message) { return; } if (todo) { TaskResult.ToDo--; } else { TaskResult.InProgress--; } TaskResult.Done++; TaskResult.WeightDone += task.Weight; TaskResult.Incorrectness += (int)task.Incorrectness; }
public override void GetNewTasks() { var task = new SymuTask(Schedule.Step) { Weight = 1 }; task.SetKnowledgesBits(Environment.MainOrganization.Murphies.IncompleteBelief, Environment.MainOrganization.ArtifactNetwork.Knowledge.GetEntities <IKnowledge>(), 1); Post(task); }
public void Initialize() { _task = new SymuTask(0); for (var i = 0; i < 2; i++) { // knowledge length of 10 is arbitrary in this example var knowledge = new Knowledge(Network, MainOrganization.Models, i.ToString(), 10); _knowledges.Add(knowledge); } }
/// <summary> /// Ask Help to teammates about it belief /// when task is blocked because of a lack of belief /// </summary> /// <param name="task"></param> /// <param name="blocker"></param> public virtual void TryRecoverBlockerIncompleteBelief(SymuTask task, Blocker blocker) { if (task is null) { throw new ArgumentNullException(nameof(task)); } if (blocker is null) { throw new ArgumentNullException(nameof(blocker)); } // Check if he has the right to receive knowledge from others agents if (!Cognitive.MessageContent.CanReceiveBeliefs) { // If agent has no other strategy // Blocker must be unblocked in a way or another RecoverBlockerIncompleteBeliefByGuessing(task, blocker); return; } var murphy = Environment.MainOrganization.Murphies.IncompleteBelief; var knowledgeId = (IAgentId)blocker.Parameter; var knowledgeBit = (byte)blocker.Parameter2; var teammates = GetAgentIdsForInteractions(InteractionStrategy.Beliefs).ToList(); var askInternally = murphy.AskInternally(Schedule.Step, blocker.InitialStep); if (teammates.Any() && askInternally) { var attachments = new MessageAttachments(); attachments.Add(blocker); attachments.Add(task); attachments.KnowledgeId = knowledgeId; attachments.KnowledgeBit = knowledgeBit; var messageType = murphy.AskOnWhichChannel(Cognitive.InteractionCharacteristics.PreferredCommunicationMediums); ImpactOfTheCommunicationMediumOnTimeSpent(messageType, true, task.KeyActivity); SendToMany(teammates, MessageAction.Ask, SymuYellowPages.Help, attachments, messageType); } else { if (murphy.ShouldGuess(blocker.NumberOfTries)) { // Blocker must be unblocked in a way or another RecoverBlockerIncompleteBeliefByGuessing(task, blocker); } else { TryRecoverBlockerIncompleteBeliefExternally(task, blocker); } } }
/// <summary> /// Common method to reply help for Murphy type MurphyIncomplete (Knowledge, Information, Beliefs) /// </summary> /// <param name="task"></param> /// <param name="blocker"></param> /// <param name="medium"></param> /// <param name="internalHelp"></param> public void ReplyHelpIncomplete(SymuTask task, Blocker blocker, CommunicationMediums medium, bool internalHelp) { if (task == null) { throw new ArgumentNullException(nameof(task)); } // Take some time to learn, allocate this time on KeyActivity ImpactOfTheCommunicationMediumOnTimeSpent(medium, false, task.KeyActivity); task.Recover(blocker, internalHelp ? BlockerResolution.Internal : BlockerResolution.External); }
public void SelectNextTaskTest4() { _tasksLimit.LimitSimultaneousTasks = false; _tasksManager = new TasksManager(_tasksLimit, true); var task = new SymuTask(0) { Type = "todo" }; _tasksManager.AddToDo(task); Assert.IsNotNull(_tasksManager.SelectNextTask(0)); Assert.AreEqual(1, _tasksManager.InProgress.Count); }
public override void GetNewTasks() { var task = new SymuTask(Schedule.Step) { Weight = 1, // Creator is randomly a person of the group - for the incomplete information murphy Creator = (AgentId)Environment.AgentNetwork.FilteredAgentIdsByClassId(ClassId).Shuffle().First() }; task.SetKnowledgesBits(Model, Environment.MainOrganization.ArtifactNetwork.Knowledge.GetEntities <IKnowledge>(), 1); Post(task); }
/// <summary> /// CancelBlocker a task : /// remove a task from either To do or in progress /// </summary> /// <param name="task"></param> public void Cancel(SymuTask task) { if (task == null) { throw new ArgumentNullException(nameof(task)); } if (!task.IsAssigned) { return; } var todo = ToDo.Contains(task); var inProgress = InProgress.Contains(task); if (todo) { ToDo.Remove(task); } else if (inProgress) { InProgress.Remove(task); } else { return; } task.Cancel(); if (_debug) { Cancelled.Add(task); } // We don't want to track message as Task if (task.Parent is Message) { return; } if (todo) { TaskResult.ToDo--; } else { TaskResult.InProgress--; } TaskResult.Cancelled++; }
public void SelectNextTaskTest1() { var task = new SymuTask(0) { Type = CommunicationMediums.FaceToFace.ToString() }; _tasksManager.AddToDo(task); task = new SymuTask(0); _tasksManager.AddInProgress(task); var selectedTask = _tasksManager.SelectNextTask(0); Assert.AreEqual(selectedTask.Type, CommunicationMediums.FaceToFace.ToString()); }
public static void ReplyHelpIncompleteKnowledge(SymuTask task, Blocker blocker) { if (task is null) { throw new ArgumentNullException(nameof(task)); } if (blocker is null) { throw new ArgumentNullException(nameof(blocker)); } task.KnowledgesBits.RemoveFirstMandatory((IAgentId)blocker.Parameter); }
public override void GetNewTasks() { var task = new SymuTask(Schedule.Step) { // Weight is randomly distributed around 1, but has a minimum of 0 Weight = Math.Max(0, Normal.Sample(1, 0.1F * Environment.RandomLevelValue)), // Creator is randomly a person of the group - for the incomplete information murphy Creator = (AgentId)Environment.AgentNetwork.FilteredAgentIdsByClassId(ClassId).Shuffle().First() }; task.SetKnowledgesBits(Model, Environment.MainOrganization.ArtifactNetwork.Knowledge.GetEntities <IKnowledge>(), 1); Post(task); }
/// <summary> /// Check if there are blockers today on the task /// </summary> /// <param name="task"></param> private void CheckBlockers(SymuTask task) { if (task is null) { throw new ArgumentNullException(nameof(task)); } if (!Environment.MainOrganization.Murphies.MultipleBlockers && task.IsBlocked) // One blocker at a time { return; } CheckNewBlockers(task); }
private bool SelectNextMessage(CommunicationMediums medium, out SymuTask symuTask) { if (ToDo.Exists(t => t.Type == medium.ToString())) { var task = ToDo.Find(t => t.Type == medium.ToString()); SetInProgress(task); { symuTask = task; return(true); } } symuTask = null; return(false); }
/// <summary> /// Check if there are new blockers for the task /// </summary> /// <param name="task"></param> public virtual void CheckNewBlockers(SymuTask task) { if (task == null) { throw new ArgumentNullException(nameof(task)); } if (task.Parent is Message) { return; } CheckBlockerIncompleteKnowledge(task); CheckBlockerIncompleteBeliefs(task); CheckBlockerIncompleteInformation(task); }
public void SelectNextTaskTest2() { var task = new SymuTask(0) { Type = "todo" }; _tasksManager.AddToDo(task); task = new SymuTask(0) { Type = "ip" }; _tasksManager.AddInProgress(task); var selectedTask = _tasksManager.SelectNextTask(0); Assert.AreEqual(selectedTask.Type, "ip"); }
/// <summary> /// Add a task directly in AverageInProgress /// </summary> /// <param name="task"></param> public void AddInProgress(SymuTask task) { if (task is null) { throw new ArgumentNullException(nameof(task)); } InProgress.Add(task); // We don't want to track message as Task if (task.Parent is Message) { return; } TaskResult.TotalTasksNumber++; TaskResult.InProgress++; task.SetTasksManager(this); }
public override void TryRecoverBlockerIncompleteKnowledgeExternally(SymuTask task, Blocker blocker, IAgentId knowledgeId, byte knowledgeBit) { if (blocker == null) { throw new ArgumentNullException(nameof(blocker)); } var attachments = new MessageAttachments(); attachments.Add(blocker); attachments.Add(task); attachments.KnowledgeId = knowledgeId; attachments.KnowledgeBit = knowledgeBit; Send(Internet.AgentId, MessageAction.Ask, SymuYellowPages.Help, attachments, CommunicationMediums.ViaAPlatform); }
/// <summary> /// Check Task.KnowledgesBits against WorkerAgent.expertise /// If Has expertise Task will be complete /// If has expertise for mandatoryKnowledgesBits but not for requiredKnowledgesBits, he will guess, and possibly /// complete the task incorrectly /// If hasn't expertise for mandatoryKnowledgesBits && for requiredKnowledgesBits, he will ask for help (co workers, /// internet forum, ...) && learn /// </summary> /// <param name="task"></param> public void CheckBlockerIncompleteKnowledge(SymuTask task) { if (!Environment.MainOrganization.Murphies.IncompleteKnowledge.On || !Environment.MainOrganization.Models.Knowledge.On) { return; } if (task is null) { throw new ArgumentNullException(nameof(task)); } foreach (var knowledgeId in task.KnowledgesBits.KnowledgeIds) { CheckBlockerIncompleteKnowledge(task, knowledgeId); } }
/// <summary> /// Post a task in the TasksProcessor /// </summary> /// <param name="task"></param> /// <remarks>Don't use TaskProcessor.Post directly to handle the OnBeforeTaskPost event</remarks> public void Post(SymuTask task) { if (task == null) { throw new ArgumentNullException(nameof(task)); } // if filtering tasks here, we must unassigned the task otherwise the task would not be taken by anyone // for the moment it is not filtered if (!Cognitive.TasksAndPerformance.CanPerformTask) // || task.IsCancelledBy(Id)) //|| task.IsBlocked) { return; } OnBeforePostTask(task); TaskProcessor.Post(task); OnAfterPostTask(task); }
/// <summary> /// Convert message into a task to be perform in the task manager /// MessageResult.ReceivedMessagesCost is also updated /// </summary> /// <param name="message"></param> /// <returns></returns> private SymuTask ConvertMessageIntoTask(Message message) { var communication = Environment.MainOrganization.Communication.TemplateFromChannel(message.Medium); var task = new SymuTask(Schedule.Step) { Type = message.Medium.ToString(), TimeToLive = communication.TimeToLive, Parent = message, Weight = Environment.MainOrganization.Communication.TimeSpent(message.Medium, false, Environment.RandomLevelValue), Assigned = message.Receiver //todo maybe define a specific KeyActivity to follow the time spent on messaging? }; Environment.Messages.Result.ReceivedMessagesCost += task.Weight; return(task); }
public void Initialize() { _task = new SymuTask(0) { Assigned = _agentId }; _message = new SymuTask(0) { Parent = new Message(), Assigned = _agentId }; var tasksLimit = new TasksLimit(); _tasksManager = new TasksManager(tasksLimit, true); _tasks = new List <SymuTask> { _task }; }
/// <summary> /// Agent has checked its beliefs against the task. /// Now the agent must define its answer given the mandatory and required scores /// By default, mandatoryScore is checked against MurphyIncompleteBeliefs.ThresholdForReacting /// The task is blocked if necessary. /// Override this method to implement your own answer /// </summary> /// <param name="task"></param> /// <param name="knowledgeId"></param> /// <param name="mandatoryScore"></param> /// <param name="requiredScore"></param> /// <param name="mandatoryIndex"></param> /// <param name="requiredIndex"></param> /// <exception cref="ArgumentNullException"></exception> protected virtual void CheckBlockerIncompleteBelief(SymuTask task, IAgentId knowledgeId, float mandatoryScore, float requiredScore, byte mandatoryIndex, byte requiredIndex) { if (task == null) { throw new ArgumentNullException(nameof(task)); } // Cognitive.InternalCharacteristics.RiskAversionThreshold should be > Environment.Organization.Murphies.IncompleteBelief.ThresholdForReacting if (mandatoryScore > -Environment.MainOrganization.Murphies.IncompleteBelief.ThresholdForReacting) { return; } // mandatoryScore is not enough => agent don't want to do the task, the task is blocked var blocker = task.Add(Murphy.IncompleteBelief, Schedule.Step, knowledgeId, mandatoryIndex); TryRecoverBlockerIncompleteBelief(task, blocker); }
/// <summary> /// Push the task in progress /// </summary> /// <param name="task"></param> public void SetInProgress(SymuTask task) { if (task is null) { throw new ArgumentNullException(nameof(task)); } ToDo.Remove(task); InProgress.Add(task); OnAfterSetTaskInProgress?.Invoke(this, new TaskEventArgs(task)); // We don't want to track message as Task if (task.Parent is Message) { return; } TaskResult.ToDo--; TaskResult.InProgress++; }
/// <summary> /// Post the task into the todoColumn /// </summary> /// <param name="task"></param> public void Post(SymuTask task) { lock (ToDo) { AddToDo(task); // This is called when we enqueue a message, within a lock // We cooperatively unblock any waiting reader. If there is no waiting // reader we just leave the message in the incoming queue if (_savedCont == null) { return; } var sc = _savedCont; _savedCont = null; sc.SetResult(true); } }
/// <summary> /// Check a particular beliefId from Task.BeliefBits against Agent.Beliefs /// Prevent the agent from acting on a particular belief /// Task may be blocked if it is the case /// </summary> public void CheckRiskAversion(SymuTask task, IAgentId knowledgeId) { if (task is null) { throw new ArgumentNullException(nameof(task)); } if (!BeliefsModel.On) { return; } var taskBits = task.KnowledgesBits.GetBits(knowledgeId); float mandatoryScore = 0; byte mandatoryIndex = 0; var belief = BeliefsModel.GetBeliefFromKnowledgeId(knowledgeId); var actorBelief = BeliefsModel.GetActorBelief(knowledgeId); MurphyIncompleteBelief.CheckRiskAversion(belief, taskBits, actorBelief, ref mandatoryScore, ref mandatoryIndex, -Cognitive.InternalCharacteristics.RiskAversionValue()); if (!(mandatoryScore <= -Cognitive.InternalCharacteristics.RiskAversionValue())) { return; } var murphy = Environment.MainOrganization.Murphies.IncompleteBelief; // Prevent the agent from acting on a particular belief if (murphy.ShouldGuess((byte)task.HasBeenCancelledBy.Count)) { // to avoid complete blocking, we allow the agent, depending on the Murphies.IncompleteBelief parameters // to unblock the task var blocker = task.Add(Murphy.IncompleteBelief, Schedule.Step, knowledgeId, mandatoryIndex); RecoverBlockerIncompleteBeliefByGuessing(task, blocker); } else { // Agent can cancel the task a certain number of times TaskProcessor.Cancel(task); } }
/// <summary> /// Try recover blocker for an incompleteInformation blocker /// Missing information come from creator => ask PO, Users, .... /// </summary> /// <param name="task"></param> /// <param name="blocker"></param> public void TryRecoverBlockerIncompleteInformation(SymuTask task, Blocker blocker) { if (task is null) { throw new ArgumentNullException(nameof(task)); } if (blocker is null) { throw new ArgumentNullException(nameof(blocker)); } var murphy = Environment.MainOrganization.Murphies.IncompleteInformation; var askInternally = Environment.MainOrganization.Murphies.IncompleteKnowledge.AskInternally(Schedule.Step, blocker.InitialStep); //TODO send to creator only if he has the right to communicate to cf. Network if (askInternally && task.HasCreator) { var messageType = murphy.AskOnWhichChannel(Cognitive.InteractionCharacteristics .PreferredCommunicationMediums); var parameter = new MessageAttachments(); parameter.Add(blocker); parameter.Add(task); Send(task.Creator, MessageAction.Ask, SymuYellowPages.Help, parameter, messageType); } else { if (murphy.ShouldGuess(blocker.NumberOfTries)) { // Blocker must be unblocked in a way or another RecoverBlockerIncompleteByGuessing(task, blocker, Environment.MainOrganization.Murphies.IncompleteInformation, BlockerResolution.Guessing); } else { TryRecoverBlockerIncompleteInformationExternally(task, blocker); } } }
/// <summary> /// Simulate the work on a specific task /// </summary> /// <param name="task"></param> public virtual float WorkOnTask(SymuTask task) { if (task is null) { throw new ArgumentNullException(nameof(task)); } float timeSpent; if (Schedule.Type == TimeStepType.Intraday) { timeSpent = Math.Min(Environment.MainOrganization.Models.Intraday, Capacity.Actual); } else { timeSpent = Cognitive.TasksAndPerformance.TasksLimit.LimitSimultaneousTasks // Mono tasking ? Math.Min(task.Weight, Capacity.Actual) // Multi tasking : Math.Min(task.Weight / 2, Capacity.Actual); } timeSpent = Math.Min(task.WorkToDo, timeSpent); task.WorkToDo -= timeSpent; if (task.WorkToDo < Tolerance) { SetTaskDone(task); } else { UpdateTask(task); } // As the agent work on task that requires knowledge, the agent can't forget the associate knowledge today ForgettingModel.UpdateForgettingProcess(task.KnowledgesBits); Capacity.Decrement(timeSpent); return(timeSpent); }
/// <summary> /// </summary> /// <param name="task"></param> /// <param name="blocker"></param> /// <returns></returns> public override void TryRecoverBlockerIncompleteBelief(SymuTask task, Blocker blocker) { if (task is null) { throw new ArgumentNullException(nameof(task)); } if (blocker is null) { throw new ArgumentNullException(nameof(blocker)); } // RiskAversionThreshold has been exceeded => // Worker don't want to do the task, the task is blocked in base method // Ask advice from influencers var attachments = new MessageAttachments { KnowledgeId = (IAgentId)blocker.Parameter, KnowledgeBit = (byte)blocker.Parameter2 }; SendToMany(Influencers, MessageAction.Ask, SymuYellowPages.Belief, attachments, CommunicationMediums.Email); }
/// <summary> /// Check Task.KnowledgesBits for a specific KnowledgeBit against WorkerAgent.expertise /// If Has expertise Task will be complete /// If has expertise for mandatoryKnowledgesBits but not for requiredKnowledgesBits, he will guess, and possibly /// complete the task incorrectly /// If hasn't expertise for mandatoryKnowledgesBits && for requiredKnowledgesBits, he will ask for help (co workers, /// internet forum, ...) && learn /// </summary> /// <param name="task"></param> /// <param name="knowledgeId"></param> protected virtual void CheckBlockerIncompleteKnowledge(SymuTask task, IAgentId knowledgeId) { if (task == null) { throw new ArgumentNullException(nameof(task)); } if (!Environment.MainOrganization.Murphies.IncompleteKnowledge.On || Math.Abs(task.WorkToDo) < Tolerance || // Task is done !task.IsAssigned) { return; } var taskBits = task.KnowledgesBits.GetBits(knowledgeId); // If taskBits.Mandatory.Any => mandatoryCheck is false unless workerKnowledge has the good knowledge or there is no mandatory knowledge var mandatoryOk = taskBits.GetMandatory().Length == 0; // If taskBits.Required.Any => RequiredCheck is false unless workerKnowledge has the good knowledge or there is no required knowledge var requiredOk = taskBits.GetRequired().Length == 0; byte mandatoryIndex = 0; byte requiredIndex = 0; Environment.MainOrganization.Murphies.IncompleteKnowledge.CheckKnowledge(knowledgeId, taskBits, KnowledgeModel, ref mandatoryOk, ref requiredOk, ref mandatoryIndex, ref requiredIndex, Schedule.Step); if (!mandatoryOk) { // mandatoryCheck is false => Task is blocked var blocker = task.Add(Murphy.IncompleteKnowledge, Schedule.Step, knowledgeId, mandatoryIndex); TryRecoverBlockerIncompleteKnowledge(task, blocker); } else if (!requiredOk) { RecoverBlockerIncompleteKnowledgeByGuessing(task, null, knowledgeId, requiredIndex, BlockerResolution.Guessing); } }
/// <summary> /// Check Task.BeliefBits against Agent.Beliefs /// Prevent the agent from acting on a particular belief /// Task may be blocked if it is the case /// </summary> public void CheckBlockerIncompleteBeliefs(SymuTask task) { if (task is null) { throw new ArgumentNullException(nameof(task)); } if (task.Parent is Message) { return; } if (task.WorkToDo < Tolerance || !task.IsAssigned) { // Task is done or cancelled return; } foreach (var knowledgeId in task.KnowledgesBits.KnowledgeIds) { CheckBlockerIncompleteBelief(task, knowledgeId); CheckRiskAversion(task, knowledgeId); } }