-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Algorithmic improvements #14
Comments
Fantastic work. Let me see if I can port your Rust code to Go tonight or whatnot. I was pretty happy when I got to less than a second, but this is amazeballs. |
No idea how you implemented your Rust program but I found a couple of ways to increase the performance of the application which at least worked for the Python program:
I noticed, when I took a quick look over the Rust code, that the calculation for the actual DPS are more efficient because they only multiply 2 numbers. The The funny thing is that the Python program now runs slower when using multiple cores because Python launches processes when dealing with multiple cores. But at least the single core computation runs now as fast as the previous 8 core computation: about 6 seconds for 8 boosters. |
Good point on the booster stats being separable from shield, that cuts out a lot of work. Now down to 140ms for an 8 booster search. The k-d tree is built by generating a list of every pairwise combination of boosters and plotting their combined stats in 4-space into the tree. That's then used to quickly eliminate pairs which are strictly worse than other pairs in all dimensions. It's then a matter of teaching the combinations function to only return those matching the pairs filter - using an array of bitmaps in this case. |
I might also copy that k-d tree algorithm. Haven't decided yet. @vanderaj Remember what I wrote on Youtube about generating the booster variation list? I tried to get it into a non-recursive loop and after I got somewhat stuck, I found out that Python has a way to do it in 1 line of code... booster_combinations = list(itertools.combinations_with_replacement(range(1, len(self._shield_booster_variants) + 1), test_data.number_of_boosters)) |
As I was having incorrect output whilst fixing the DPS issue, I chose not to implement this, but the speed of the Go port is more than satisfactory without it. I might have a go at some other time, but I need to catch up with the Lost Souls expedition in my second account, and re-fit my Chieftain using these results on my main account. i.e. gone fishing |
So, with the help of a friend with experience in this sort of thing, I've made some significant improvements to my Rust version.
In short: I'm now filtering the booster list using a small k-d tree to eliminate pairwise combinations which can always be beaten by other pairs. This cuts the search space by about 90%, and stacks well with simple naive filtering when damage types are 0.
In short, I can now calculate optimal 8-booster configurations in 30-300 milliseconds, on a single, relatively slow CPU core, which makes it great for my web version.
I've thrown over 100,000 random scenarios at it and found no difference with the exhaustive version, so this approach seems quite sound.
The text was updated successfully, but these errors were encountered: