private void Step <TOutcome>(RunContext runContext, IOutcomeReporter <TOutcome> outcomeReporter, IStepContext <TOutcome> step)
        {
            string eventId = step.EventId;

            if (!liveModel.TryChooseRank(eventId, step.DecisionContext, runContext.ResponseContainer, runContext.ApiStatusContainer))
            {
                this.SafeRaiseError(runContext.ApiStatusContainer);
            }

            long actionIndex = -1;

            if (!runContext.ResponseContainer.TryGetChosenAction(out actionIndex, runContext.ApiStatusContainer))
            {
                this.SafeRaiseError(runContext.ApiStatusContainer);
            }

            TOutcome outcome = step.GetOutcome(actionIndex, runContext.ResponseContainer.AsEnumerable());

            if (outcome == null)
            {
                return;
            }

            if (!outcomeReporter.TryQueueOutcomeEvent(runContext, eventId, outcome))
            {
                this.SafeRaiseError(runContext.ApiStatusContainer);
            }
        }
Beispiel #2
0
        private void Step <TOutcome>(RunContext runContext, IOutcomeReporter <TOutcome> outcomeReporter, IStepContext <TOutcome> step)
        {
            string   eventId = step.EventId;
            TOutcome outcome = default(TOutcome);

            if (loopKind == LoopKind.Slates)
            {
                if (!liveModel.TryRequestMultiSlotDecision(eventId, step.SlatesContext, runContext.SlatesContainer, runContext.ApiStatusContainer))
                {
                    this.SafeRaiseError(runContext.ApiStatusContainer);
                }

                int[]   actions = runContext.SlatesContainer.Select(slot => slot.ActionId).ToArray();
                float[] probs   = runContext.SlatesContainer.Select(slot => slot.Probability).ToArray();
                outcome = step.GetSlatesOutcome(actions, probs);
                if (outcome == null)
                {
                    return;
                }
            }
            else if (loopKind == LoopKind.CA)
            {
                if (!liveModel.TryRequestContinuousAction(eventId, step.ContinuousActionContext, runContext.ContinuousActionContainer, runContext.ApiStatusContainer))
                {
                    this.SafeRaiseError(runContext.ApiStatusContainer);
                }
                float action   = runContext.ContinuousActionContainer.ChosenAction;
                float pdfValue = runContext.ContinuousActionContainer.ChosenActionPdfValue;
                outcome = step.GetContinuousActionOutcome(action, pdfValue);
                if (outcome == null)
                {
                    return;
                }
            }
            else
            {
                if (!liveModel.TryChooseRank(eventId, step.DecisionContext, runContext.ResponseContainer, runContext.ApiStatusContainer))
                {
                    this.SafeRaiseError(runContext.ApiStatusContainer);
                }

                long actionIndex = -1;
                if (!runContext.ResponseContainer.TryGetChosenAction(out actionIndex, runContext.ApiStatusContainer))
                {
                    this.SafeRaiseError(runContext.ApiStatusContainer);
                }

                outcome = step.GetOutcome(actionIndex, runContext.ResponseContainer.AsEnumerable());
                if (outcome == null)
                {
                    return;
                }
            }

            if (!outcomeReporter.TryQueueOutcomeEvent(runContext, eventId, outcome))
            {
                this.SafeRaiseError(runContext.ApiStatusContainer);
            }
        }
        public void Test_DeserializeReplayStep_WithoutObservation()
        {
            // Arrange
            string expectedEventId     = "my_experiment-t1-n10-f2-a4-0-0";
            string expectedContext     = PrepareJson("{ \"GUser\":{\"f_int\":0,\"f_float\":0.5,\"f_str_0\":\"value_0\",\"f_str_1\":\"value_1\"}, \"_multi\": [ { \"TAction\":{\"a_f_0\":\"value_0\",\"a_f_1\":\"value_1\"}},{ \"TAction\":{\"a_f_0\":\"value_1\",\"a_f_1\":\"value_2\"}},{ \"TAction\":{\"a_f_0\":\"value_2\",\"a_f_1\":\"value_3\"}},{ \"TAction\":{\"a_f_0\":\"value_3\",\"a_f_1\":\"value_4\"}}] }");
            string expectedObservation = null;

            const string dsJsonWithObservation = "{\"_label_cost\":-0,\"_label_probability\":0.25,\"_label_Action\":1,\"_labelIndex\":0,\"Version\":\"1\",\"EventId\":\"my_experiment-t1-n10-f2-a4-0-0\",\"a\":[1,2,3,4],\"c\":{ \"GUser\":{\"f_int\":0,\"f_float\":0.5,\"f_str_0\":\"value_0\",\"f_str_1\":\"value_1\"}, \"_multi\": [ { \"TAction\":{\"a_f_0\":\"value_0\",\"a_f_1\":\"value_1\"}},{ \"TAction\":{\"a_f_0\":\"value_1\",\"a_f_1\":\"value_2\"}},{ \"TAction\":{\"a_f_0\":\"value_2\",\"a_f_1\":\"value_3\"}},{ \"TAction\":{\"a_f_0\":\"value_3\",\"a_f_1\":\"value_4\"}}] },\"p\":[0.250000,0.250000,0.250000,0.250000],\"VWState\":{\"m\":\"N/A\"}}";

            // Act
            IStepContext <string> stepContext = ReplayStepProvider.DeserializeReplayStep(dsJsonWithObservation);
            string actualObservation          = stepContext.GetOutcome(0, new ActionProbability[0]);

            Assert.AreEqual(expectedEventId, stepContext.EventId, $"{nameof(stepContext.EventId)} is not properly deserialized.");
            Assert.AreEqual(expectedContext, stepContext.DecisionContext, $"{nameof(stepContext.DecisionContext)} is not properly deserialized.");
            Assert.AreEqual(expectedObservation, actualObservation, $"Observation is not properly deserialized.");
        }
        private void Step <TOutcome>(RunContext runContext, IOutcomeReporter <TOutcome> outcomeReporter, IStepContext <TOutcome> step)
        {
            string   eventId = step.EventId;
            TOutcome outcome = default(TOutcome);

            if (loopKind == LoopKind.Slates)
            {
                if (!liveModel.TryRequestMultiSlotDecision(eventId, step.SlatesContext, runContext.MultiSlotResponseContainer, runContext.ApiStatusContainer))
                {
                    this.SafeRaiseError(runContext.ApiStatusContainer);
                }

                int[]   actions = runContext.MultiSlotResponseContainer.Select(slot => slot.ActionId).ToArray();
                float[] probs   = runContext.MultiSlotResponseContainer.Select(slot => slot.Probability).ToArray();
                outcome = step.GetSlatesOutcome(actions, probs);
                if (outcome == null)
                {
                    return;
                }
            }
            else if (loopKind == LoopKind.CA)
            {
                if (!liveModel.TryRequestContinuousAction(eventId, step.ContinuousActionContext, runContext.ContinuousActionContainer, runContext.ApiStatusContainer))
                {
                    this.SafeRaiseError(runContext.ApiStatusContainer);
                }
                float action   = runContext.ContinuousActionContainer.ChosenAction;
                float pdfValue = runContext.ContinuousActionContainer.ChosenActionPdfValue;
                outcome = step.GetContinuousActionOutcome(action, pdfValue);
                if (outcome == null)
                {
                    return;
                }
            }
            else if (loopKind == LoopKind.CCB)
            {
                if (!liveModel.TryRequestDecision(step.DecisionContext, runContext.DecisionResponseContainer, runContext.ApiStatusContainer))
                {
                    this.SafeRaiseError(runContext.ApiStatusContainer);
                }
                // TODO: Populate actionProbs. Currently GetOutcome() just returns a fixed outcome value, so the values of actionProbs don't matter.
                ActionProbability[] actionProbs = new ActionProbability[runContext.DecisionResponseContainer.Count];
                foreach (var slot in runContext.DecisionResponseContainer)
                {
                    outcome = step.GetOutcome(slot.ActionId, actionProbs);
                    if (!outcomeReporter.TryQueueOutcomeEvent(runContext, slot.SlotId, outcome))
                    {
                        this.SafeRaiseError(runContext.ApiStatusContainer);
                    }
                }
                return;
            }
            else if (loopKind == LoopKind.CCBv2)
            {
                if (!liveModel.TryRequestMultiSlotDecisionDetailed(eventId, step.DecisionContext, runContext.MultiSlotResponseDetailedContainer, runContext.ApiStatusContainer))
                {
                    this.SafeRaiseError(runContext.ApiStatusContainer);
                }
                foreach (var slot in runContext.MultiSlotResponseDetailedContainer)
                {
                    outcome = step.GetOutcome(slot.ChosenAction, slot);
                    if (!outcomeReporter.TryQueueOutcomeEvent(runContext, eventId, slot.SlotId, outcome))
                    {
                        this.SafeRaiseError(runContext.ApiStatusContainer);
                    }
                }
                return;
            }
            else
            {
                if (!liveModel.TryChooseRank(eventId, step.DecisionContext, runContext.ResponseContainer, runContext.ApiStatusContainer))
                {
                    this.SafeRaiseError(runContext.ApiStatusContainer);
                }

                long actionIndex = -1;
                if (!runContext.ResponseContainer.TryGetChosenAction(out actionIndex, runContext.ApiStatusContainer))
                {
                    this.SafeRaiseError(runContext.ApiStatusContainer);
                }

                outcome = step.GetOutcome(actionIndex, runContext.ResponseContainer.AsEnumerable());
                if (outcome == null)
                {
                    return;
                }
            }

            if (!outcomeReporter.TryQueueOutcomeEvent(runContext, eventId, outcome))
            {
                this.SafeRaiseError(runContext.ApiStatusContainer);
            }
        }