Hey there i’m pretty sure this is a bug. I’ve been working with probability recently and I noticed that some smaller values never seemed to be chosen. I triple check everything and I think I’ve managed to catch the problem but from my end I don;t understand what is going wrong.
I distilled it down to this. If I tap the button it spawns 100,000 random numbers and if any meet the requirements it prints hello.
The one that is plugged in works fine every time I press the button i get a couple hello’s
But if I narrow the gap to less than 8 like in the example branches below no matter how much I press I never see a hello. It should be fairly easy to replicate just copy what is in the image. The number I used was the upper bounds on my loot drop probability stuff but I also tried it with slightly higher and slightly lower numbers and the same happened. I don’t know where the cut off point is for it to begin working as intended.
The more I test the more it feels like the random int or the “greater than” check lose accuracy at higher numbers and start skipping up and down by larger amounts. I’m using a typical loot drop system where all the rarity’s are added together and then a for loop takes them away from a random number between 0 and the max rarity. Numbers towards to end of the array below say 6 never get chosen but if i move them to the start of the array they seem to get chosen as expected
[EDIT] They don’t get chosen if they are at the start of the array I was mistaken
I just tried setting the number manually instead of letting random int pick a number and I was able to get the loot generator to drop all the items that wouldn’t drop before so I have to assume there is a problem with random int/float
I tried having it randomly jump between the upper amount for each item to drop and again with the lowest amount for each item drop to make sure my loot generator wasn’t interfering at some point. You can see in the picture below the upper amounts plugged in. Using this all 22 items spawn roughly the exact same amount. The way it should work is a random number between 1 and 100000 should spawn option 0, between 100000 and 170000 should spawn option 1 and so on down that list.
if i plug in the random int in range you can see in the picture the smallest brackets do not ever spawn (I’ve made sure to spawn more than enough to rule out probability) specifically it never spawns options 15,16,19,20 and 21 which have brackets of 5,2,5,2 and 1 in size.
below you can see how many of each item spawned after I repeatedly spawned items for a while using the random int in range. You can see that relative to the other amounts you would expect no options to have not spawned.
I triple checked the system that reports these numbers as well to make sure those options weren’t just failing to report. If i set their brackets to be above 8 then every options spawns as expected with the probability I predict in a separate excel sheet
Something to think about:
When creating random numbers they are often created within a relatively large range. And always within the same range. (This has to do with the algorithms used).
Then a modulo operator is used to get the rest when dividing by the max you want.
This means that if your range is very large, then the modulo operation won’t give well distributed values, as the upper values have little to no chance of spawning.
In your case if you truly need to randomize within such a massive range, then you would need to generate a much larger number, and make sure to store it in a type of integer that can handle it ! Then do the modulo operation to get it back into your range. That might not be so easy in blueprint, but shouldn’t be to hard in c++.
As for why a random float in range with an FCeil would SEEM to work for you. Well, you would actually be unable to get a lot of numbers! Because the float is even worse at describing them unless their hiding doubles (64 bit) behind the scenes. The reason you wouldn’t notice that is because your only looking at ranges, and pretty large ones at that, a float is unable to express small differences in numbers once it becomes large enough. Then again, it might be enough for you anyways.
(I think that floats are always randomized 0-1, and then multiplied up to the range you want).
But interesting bug report, and possibly something that epic should look into. (Using a larger data type for randoms)
This would become appar
Thanks I wasn’t aware that was how random numbers were generated. I think part of the issue may be that within blueprint there was no easy way for me to see “inside” the node to get a better idea of how it works.
I don’t know if I have to generate numbers that large, I can’t think of a way to do the loot drop probability that doesn’t involve it where one item needs to be say a 1 in 300,000 chance to drop. I’ve thought about staggering checks so it will roll multiple times but I also can;t think of a way to do that which allows me to effectively affect the chance for rare items to drop in smaller increments because I end up needing those large random numbers again.
I’m not sure what steps you could boil it down to. My main point is that at large enough ranges the random int in range never spawns some numbers but since those numbers have to be large and like you say its one chance in 300,000 I can only think to have it try 100,000’s of time’s to see if it ever does hit the number
Unfortunately that is going to be extremely difficult to test. The random int in range chooses a different variable each time and is independent of the numbers chosen per loop. The likelihood that you get 299991 or 300,000 is 1:300,000 for each loop iteration. Do you have any steps that definitely reproduce the error each time that aren’t reliant on exact numbers within large ranges?
To clarify in-case I misunderstood you. The set up above shows you the difference instantly if you just use the two numbers I said. Because some numbers do not spawn I believe the chance for the numbers that do is spawn is wrong as well. In the example above when I hit T if it is set to 299991 I get multiple prints per button push when you would expect an average of one print every 3 button presses
I think i’ve come up with a way that might help you pin point the issue some more.
I instead changed it so that I created an array with 300,000 instances for each number and then I had the random int remove that number from the array if it came up so after letting it loop a few times I have a list of numbers that the random int never called. this was really memory intensive so I tired lowering the value till it started to remove every index.
With 600,000 attempts at rolling 1 in 50,000 chance you wouldn’t expect any to be left but a full 3rd of the numbers remain and you can see they increase in steps of 3.
I have attempted to reproduce this on my end, however everything is acting exactly as I would expect. The test I ran was to get the random int in range and check against 299991 on tick (see image). in this test, I incremented an integer each time the tick was run. I also attempted this with a while loop and a modified while loop. In each instance the results were similar if extremely varied:
The value came up after 552, 4076, 12187, 17470, 76771, and 19503 iterations. It did not matter what number I selected. I fully expected this behavior, though admittedly I expected it to take many more iterations before it would actually select the value randomly, given that each time the value had a 1:300000 chance of selecting 299991. However this actually will not definitively prove that a value is not being selected. This is because, while a value may be selected once in 100000 attempts, one must then consider that that means that 299999 values were not chosen each time a value has been selected, in that, how many were not selected at all or potentially significantly more than other values, which is dependent entirely upon a random selection. It is never guaranteed that a value will be selected, as all random selections must be taken as separate instances that have no bearing on each other, with the exception of instances where a value is removed once selected, which, while improving the odds that another value will be selected, still does not guarantee a value to be selected as long as there are multiple values within a random selector. The only way to 100% guarantee that a value will be selected would be to remove all other values that can be randomly selected, which does not sound like what you are attempting to accomplish.
I still feel like we are getting our wires crossed. I understand it does’t have any bearing on the probability what has come before. you can see in my above message that I an running 600,000 iterations and still being left with a 3rd of the numbers. If I lower the amount eventually I start to get all numbers. Do you not get the same result as me trying what I posted in the first image?
[EDIT] Possibly the confusion comes from the 100,000 iterations in my first images? to be clear i was pushing T multiple times and running as much as 5,000,000 iterations. I wasn’t expecting it to select every number over the 100,000 iterations when there are 300,000 numbers
Using your method in the picture you posted in an entirely fresh project with no content I was able to get 299991 to spawn I then tried 300000 and It does not seem to spawn. I have left it running now for a good 15 minutes at 1400fps which has a very high chance of having spawned it should the system be working. On the other hand 299991 seems to occur quite frequently. much more frequently that you would expect which reflects what you posted too. I got it 5 times before even passing 300,000 iterations
here is a screen shot of 299991 having been only running for 5 minutes to illustrate the significant difference in chance for it to spawn compared to 300000. This is a fresh project with no content at all. I have also tested this on 4.9 and 4.11 update that I believe just rolled out/
No, I never saw the same results as the above images illustrate. I tried with forloops, while loops, and tick and received a high variance but never saw an instance where a number was simply not present within a random int in range. In all scenarios the value eventually appeared, even if it took a significant amount of time to do so.
I’m not sure why this would need to be moved out of bug reports when by your very own finding you saw that 299991 came up an abnormally frequent amount of times.