public override int HandleChoice(int valueCount) { ++_choiceIndex; // If we have a preselected value that we should choose for the current path, return it var chosenValuesMaxIndex = _chosenValues.Count - 1; if (_choiceIndex <= chosenValuesMaxIndex) { return(_chosenValues[_choiceIndex].OptionIndex); } // We haven't encountered this choice before; store the value count and return the first value _valueCount.Push(valueCount); var newChosenValue = new LtmcChosenValue { OptionIndex = 0, Probability = GetProbabilityOfPreviousPath() / valueCount //placeholder value (for non deterministic choice) }; _chosenValues.Push(newChosenValue); return(0); }
public void Push(LtmcChosenValue value) { if (_memoryBuffer.SizeInBytes <= Count * sizeof(LtmcChosenValue)) { _memoryBuffer.Resize(_memoryBuffer.SizeInBytes * 2, zeroMemory: true); _buffer = (LtmcChosenValue *)_memoryBuffer.Pointer; } _buffer[Count++] = value; }
/// <summary> /// Sets the choices that should be made during the next step. /// </summary> /// <param name="choices">The choices that should be made.</param> internal override void SetChoices(int[] choices) { Requires.NotNull(choices, nameof(choices)); foreach (var choice in choices) { var newChosenValue = new LtmcChosenValue { Probability = Probability.One, OptionIndex = choice }; _chosenValues.Push(newChosenValue); _valueCount.Push(0); } }
public override bool PrepareNextPath() { if (_choiceIndex != _valueCount.Count - 1) { throw new NondeterminismException(); } // Reset the choice counter as each path starts from the beginning _choiceIndex = -1; // If this is the first path of the state, we definitely have to enumerate it if (_firstPath) { _firstPath = false; return(true); } // Let's go through the entire stack to determine what we have to do next while (_chosenValues.Count > 0) { // Remove the value we've chosen last -- we've already chosen it, so we're done with it var chosenValue = _chosenValues.Remove(); // If we have at least one other value to choose, let's do that next if (_valueCount.Peek() > chosenValue.OptionIndex + 1) { var previousProbability = GetProbabilityUntilIndex(_valueCount.Count - 2); var valueCount = _valueCount.Peek(); var newChosenValue = new LtmcChosenValue { OptionIndex = chosenValue.OptionIndex + 1, Probability = previousProbability / valueCount //placeholder value (for non deterministic choice) }; _chosenValues.Push(newChosenValue); return(true); } // Otherwise, we've chosen all values of the last choice, so we're done with it _valueCount.Remove(); } // If we reach this point, we know that we've chosen all values of all choices, so there are no further paths return(false); }
public override void SetProbabilityOfLastChoice(Probability probability) { var probabilitiesOfChosenValuesMaxIndex = _chosenValues.Count - 1; // If this part of the path has previously been visited we do not change the value // because this value has already been set by a previous call of SetProbabilityOfLastChoice. // Only if we explore a new part of the path the probability needs to be written. // A new part of the path is explored, iff the previous HandleChoice pushed a new placeholder // value onto the three stacks). if (_choiceIndex == probabilitiesOfChosenValuesMaxIndex) { _chosenValues[_choiceIndex] = new LtmcChosenValue { OptionIndex = _chosenValues[_choiceIndex].OptionIndex, Probability = GetProbabilityOfPreviousPath() * probability }; } }
internal override void ForwardUntakenChoicesAtIndex(int choiceIndexToForward) { // This method is called when it is assumed, that choosing anything different at choiceIndex // leads to the same state as the path until the last choice. // Thus, we can simply revert this unnecessary choice and add the probability of the unmade alternatives // of the reverted choice to the last choice. // Note, very small numbers get multiplied and summarized. Maybe type double is too imprecise. if (_valueCount[choiceIndexToForward] == 0) { return; //Nothing to do } Assert.That(_chosenValues[choiceIndexToForward].OptionIndex == 0, "Only first choice can be made deterministic."); // We disable a choice by setting the number of values that we have yet to choose to 0, effectively // turning the choice into a deterministic selection of the value at index 0 var oldProbabilityUntilDeterministicChoice = GetProbabilityUntilIndex(choiceIndexToForward - 1).Value; var oldProbabilityOfDeterministicChoice = GetProbabilityUntilIndex(choiceIndexToForward).Value; var differenceProbabilityToAdd = oldProbabilityUntilDeterministicChoice - oldProbabilityOfDeterministicChoice; var probabilityOfLastChoicePath = GetProbabilityUntilIndex(LastChoiceIndex).Value; var newValueOfLastChoice = (probabilityOfLastChoicePath + differenceProbabilityToAdd); // set the calculated value _chosenValues[LastChoiceIndex] = new LtmcChosenValue { OptionIndex = _chosenValues[LastChoiceIndex].OptionIndex, Probability = new Probability(newValueOfLastChoice) }; // Set the alternatives to zero. _valueCount[choiceIndexToForward] = 0; }