So lately after farming for some warframes, I started wondering about the likelihood to obtain all blueprints after doing couple runs. So to quench my curiosity, I wrote a small program that simulates boss runs and the corresponding blueprint drops.
Of the data I found across three warframe posts (see below for the reference to the original posts), the likelihood to obtain all blueprints for the following warframes are:
Rhino Warframe Drop Chance
If attempting 9 runs, you have a ~90% chance of obtaining all parts of Rhino.
Excalibur Warframe Drop Chance
90% of the time after doing 29 runs, you will obtain
If attempting 11 runs, you have a ~90% chance of obtaining all parts of Excalibur.
Nyx Warframe Drop Chance
If attempting 13 runs, then you have a ~90% chance of obtaining all parts of Nyx.
Some Unfortunate Warframe Drop Chance
If attempting 29 runs, then you have a ~90% chance of obtaining this all parts of this unfortunate Warframe.
The real point of interest is the cumulative probability (green line) as opposed to the probability (red line). The cumulative probability (green line) gives the probability of obtaining all Warframe parts during any of the consecutive runs. On the other hand, the probability (red line) gives the probability of obtaining all Warframe parts in exactly some specified runs. So for instance looking at Nyx's graph, we have a ~0.05 chance of all Nyx parts dropping after exactly 10 runs but we have a ~0.80 chance of getting all Nyx parts in any of the runs leading up to the 10th run.
A Bit About The Graphs:
The graphs are obtained through numerical means so there is some small error between them and reality but nothing significant. Crudely speaking, each graph simulates 50 consecutive boss runs and repeats this process 100,000 times to arrive at a better average of the probabilities (so a total of 5,000,000 runs).
As for the correctness of the model, I calculated the theoretical values of some data points which fit in well with the graphs. Also, the calculated drop chances of each item after running the consecutive runs simulation only differs by a fraction from the theoretical values (which are the ones displayed in the legend of the graphs). So it seems to be fine.
If anyone wants some more graphs posted, then I can gladly do so but I will require the drop chance of each individual item.
Misconceptions:
Question: Does that mean after I do 11 runs of Excalibur, that my chances of getting the last piece (say item 'c') is roughly above 90% on the 12th and subsequent runs?
Answer: No, that isn't true, that is known as the Gambler's Fallacy. For the 12th run, your probability of obtaining the last item (item 'c') will still 40% as always.
If you have completed 11 runs and not all your Warframe parts have dropped, then the next subsequent run will not have an above 90% drop chance. But, if you start a new second series of 11 runs from this point, then over the span of those runs, you have a chance at least greater than ~90% of obtaining all parts (it's actually ~99.7%). The second series of 11 runs have a higher probability than the first series of 11 runs because they assume you already have 2/3 pieces within possession. And now suppose after completing the second series of runs (so a total of 22 runs so far), the last piece didn't drop unfortunately. Then, if you complete a third series of 11 runs, you would still have a ~99.7% chance of getting the last piece (with a total of 33 runs).
This probability differs from if you initially attempted to complete a series of 33 runs without 'stopping' (which is ~99.9%). Why? Because in the case of where we 'stopped', the probability of obtaining all the parts didn't proc in the first nor second series of 11 runs. So we only had 11 more tries as oppose to 33 hence the probability being less (even though we had 2/3 items already which increased it).
On a side note, the probability mentioned in the question is cumulative so that implies when looking at the corresponding runs, they essentially mean from any number of runs less than or equal to the run.
Code:
As for those interested in the code, it's done in Python using numpy and matplotlib:
# Calculates the cumulative probability of obtaining all n items from a# a boss after some k runs. We assume that each item has an equal chance# of dropping. We resort to numerical estimations in doing so. import matplotlib.pyplot as pltimport numpy as npimport string as string class Item(): """ Representation of an in-game item that can be dropped. """ itemsGenerated = 0 def __init__(self, probability=0.0, isWanted=True): """ Assigns an alphabet ID to the item generated and initializes. """ self.id = string.ascii_lowercase[Item.itemsGenerated] Item.itemsGenerated += 1 self.probability = probability self.isWanted = isWanted self.hasDroppedRecently = False # Flag used to simplify code self.totalDrops = 0 self.totalAttempts = 0 class Instance(): """ Representation of an in-game instance which drops items. """ def __init__(self, itemsList): """ Constructs the instance. Extracts the total amount of wanted items to be dropped. Also, extracts the probabilities for each item to be dropped. """ self.runNum = 1 self.totalAttempts = 0 self.totalWantedItems = 0 self.droppedWantedItems = 0 self.itemsList = itemsList self.itemsProbabilityList = [] for item in itemsList: self.itemsProbabilityList.append(item.probability) if(item.isWanted): self.totalWantedItems += 1 def plotSimulationProbabilities(self, maxRuns, iterations=10000): """ maxRuns - maximum number of boss runs Plots the probability and cumulative probability of successfully getting all items from the boss against the number of runs on a 2D graph using matplotlib. """ title = "Items Dropped By Boss: {} ({})"\ .format(len(self.itemsList), iterations) fileName = "Items {} Iterations {}"\ .format(len(self.itemsList), iterations) # Initializing the y-axis tick marks yticksList = [] for i in range(11): yticksList.append(i/10) # Generating the data runList, runsProbabilityList, runsCumulativeProbabilityList = \ self.generateData(maxRuns, iterations) # Plotting the data fig = plt.figure() fig.canvas.set_window_title(fileName) subplot = fig.add_subplot(111) plt.plot(runList, runsProbabilityList, color="r", label="Probability") plt.plot(runList, runsCumulativeProbabilityList, color="g", label="Cumulative Probability") # Shrinking graph to allow extra information to be placed on the it's # right (items and their drop chances) box = subplot.get_position() subplot.set_position([box.x0, box.y0, 0.8*box.width, box.height]) for i, item in enumerate(self.itemsList): plt.figtext(0.78, 0.7 - i/20, "Item {}: {:<3.0f}%" .format(item.id, 100*item.probability), bbox=dict(facecolor="white", alpha=0.5, width=130), fontweight='bold', fontsize=12) # Adjusting graph settings plt.title(title, fontweight="bold") plt.legend(loc='upper right', fontsize=12) plt.ylabel('Probability') plt.yticks(yticksList) plt.ylim(plt.ylim()[0], 1.2) plt.xlabel('Runs') plt.show() def generateData(self, maxRuns, iterations=10000): """ Executes the consecutive runs simulation, obtains data, calculates probabilities for each set of successful consecutive runs, then returns the processed data ready to be plotted. """ runsDroppedDict = self.simulateConsecutiveRuns(maxRuns, iterations) return self.calculateSimulationProbabilities(runsDroppedDict) def simulateConsecutiveRuns(self, maxRuns, iterations=10000): """ maxRuns - maximum number of tries iterations - number of times to repeat the consecutive runs Per iteration, generates a consecutive sequence of runs until the upper limit is reached or until all the items have dropped in the sequence. Returns a dictionary that contains items of form (runNumber : Number of times successfully obtained all wanted items) """ runsDroppedDict = {i:0 for i in range(1, maxRuns+1)} # Generating Data: # The inner while-loop represents items dropping in consecutive runs up # to a maximum of maxRuns runs. The outer-loop is solely to repeat this # process multiple times for a better numerical solution. for _ in range(iterations): # Initialization per new series of runs self.reset() while(self.runNum <= maxRuns): self.dropItem() # Checks if all items have dropped yet if(self.haveAllItemsDropped()): runsDroppedDict[self.runNum] += 1 break self.runNum += 1 return runsDroppedDict def calculateSimulationProbabilities(self, runsDroppedDict): """ Calculates the probabilities from the data generated by the simulation function. The runs, probabilities and cumulative probabilities are calculated. """ dimension = len(runsDroppedDict) runsList = dimension*[0] runsProbabilityList = dimension*[0] runsCumulativeProbabilityList = dimension*[0] # Calculating Data: # The probabilities of successful runs print("\nProbabilities:") for i, (run, drops) in enumerate(runsDroppedDict.items()): runsList[i] = run runsProbabilityList[i] = drops / self.totalAttempts print("Runs: {:<3} {:<3} Probability: {:<3.4f}" .format(run, "||", runsProbabilityList[i])) # The cumulative probabilities of successful runs runsCumulativeProbabilityList =\ self.calculateCumulativeProbabilities(runsProbabilityList) print("\nCumulative Probabilities:") for i, _ in enumerate(runsCumulativeProbabilityList): print("Runs: {:<3} {:<3} Cumulative Probability: {:<3.4f}" .format(runsList[i], "||", runsCumulativeProbabilityList[i])) # The estimated drop chance of each item print("\nItem Drop Chances From Simulation Data:") for item in self.itemsList: print("Item '{}' drop chance in sample: {:.4f}" .format(item.id, item.totalDrops/item.totalAttempts)) return runsList, runsProbabilityList, runsCumulativeProbabilityList def dropItem(self): """ Selects an item to drop based on weighted probabilities and updates the instance correspondingly. """ itemChosen = np.random.choice(self.itemsList, p=self.itemsProbabilityList) # Updates by checking if the item is wanted and has dropped before if(itemChosen.hasDroppedRecently is False): itemChosen.hasDroppedRecently = True if(itemChosen.isWanted): self.droppedWantedItems += 1 # Updates by incrementing the drop variables of the item objects itemChosen.totalDrops += 1 for item in self.itemsList: item.totalAttempts += 1 def haveAllItemsDropped(self): """ Checks whether all wanted items have dropped from the instance. """ if(self.droppedWantedItems == self.totalWantedItems): return True else: return False def reset(self): """ Resets the instance to allow a new set of consecutive runs. """ self.totalAttempts += 1 self.runNum = 1 self.droppedWantedItems = 0 for item in self.itemsList: item.hasDroppedRecently = False def calculateCumulativeProbabilities(self, probabilityList): """ Calculates and returns the cumulative probabilities list when given a probability list. """ cumulativeProbability = 0 cumulativeProbabilityList = [] for probability in probabilityList: cumulativeProbability += probability cumulativeProbabilityList.append(cumulativeProbability) return cumulativeProbabilityList def main(): """ Creates items, then runs the simulation with the specified items and subsequently plots. """ iterations = 100000 runs = 50 item1 = Item(8/10) item2 = Item(1/10) item3 = Item(1/10) itemsList = [item1, item2, item3] instance = Instance(itemsList) instance.plotSimulationProbabilities(runs, iterations) if __name__ == "__main__": main()
Question
Ozlol
Greetings,
So lately after farming for some warframes, I started wondering about the likelihood to obtain all blueprints after doing couple runs. So to quench my curiosity, I wrote a small program that simulates boss runs and the corresponding blueprint drops.
Of the data I found across three warframe posts (see below for the reference to the original posts), the likelihood to obtain all blueprints for the following warframes are:
Rhino Warframe Drop Chance
If attempting 9 runs, you have a ~90% chance of obtaining all parts of Rhino.
Excalibur Warframe Drop Chance
If attempting 11 runs, you have a ~90% chance of obtaining all parts of Excalibur.
Nyx Warframe Drop Chance
If attempting 13 runs, then you have a ~90% chance of obtaining all parts of Nyx.
Some Unfortunate Warframe Drop Chance
If attempting 29 runs, then you have a ~90% chance of obtaining this all parts of this unfortunate Warframe.
Misconceptions:
Question: Does that mean after I do 11 runs of Excalibur, that my chances of getting the last piece (say item 'c') is roughly above 90% on the 12th and subsequent runs?
Answer: No, that isn't true, that is known as the Gambler's Fallacy. For the 12th run, your probability of obtaining the last item (item 'c') will still 40% as always.
If you have completed 11 runs and not all your Warframe parts have dropped, then the next subsequent run will not have an above 90% drop chance. But, if you start a new second series of 11 runs from this point, then over the span of those runs, you have a chance at least greater than ~90% of obtaining all parts (it's actually ~99.7%). The second series of 11 runs have a higher probability than the first series of 11 runs because they assume you already have 2/3 pieces within possession. And now suppose after completing the second series of runs (so a total of 22 runs so far), the last piece didn't drop unfortunately. Then, if you complete a third series of 11 runs, you would still have a ~99.7% chance of getting the last piece (with a total of 33 runs).
This probability differs from if you initially attempted to complete a series of 33 runs without 'stopping' (which is ~99.9%). Why? Because in the case of where we 'stopped', the probability of obtaining all the parts didn't proc in the first nor second series of 11 runs. So we only had 11 more tries as oppose to 33 hence the probability being less (even though we had 2/3 items already which increased it).
On a side note, the probability mentioned in the question is cumulative so that implies when looking at the corresponding runs, they essentially mean from any number of runs less than or equal to the run.
Code:
As for those interested in the code, it's done in Python using numpy and matplotlib:
References and many hats off to fellow Tennos:
Nyx: https://forums.warframe.com/index.php?/topic/195825-thank-you-phorid/#entry2276005
Rhino: https://forums.warframe.com/index.php?/topic/206582-warframe-part-drop-rates-experiments/
Excalibur: https://forums.warframe.com/index.php?/topic/119448-drop-proportions-of-warfarme-blueprints/
Edited by OzlolLink to comment
Share on other sites
0 answers to this question
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now