Learning Solver Design: Automating Factorio Balancers
gianlucaventurini.com
gianlucaventurini.com
https://youtube.com/watch?v=2NKK_2v4jiE&lc=Ugx5goGzTGz-z1g8t...
Search:
“ @Jodmangel 2 weeks ago I wrote a quick script to find the longest belt weave with an SAT solver. It finds your 32-tile bridge, but also a 34-tile one:
The circles are the "external" belts and the squares the 34 "internal" ones. No longer solutions exist (unless I messed up the script, obviously).”
But I can't help to feel that the following paragraph should be removed, since it really seems to be a bit confused about the concepts of both Np-complete and NP-hard.
> Finding a feasible solution is NP-hard because we can't do any better than start placing the components on a 2D grid and check if the properties are respected. Furthermore, finding the optimal solution (i.e., minimum number of components) is NP-complete because it will require enumerating all the possible solutions in order to find the best one.
That specifically seems to be the bit where the explanation goes wrong. Proving that there's no easier method than brute forcing is a hard problem, not something to wave away as an exercise for the reader.
Something like 'Frobbing the fnutz might be NP-hard. The proof via reduction of SAT is left as an exercise for the reader.'
Not very reader friendly, but at least you haven't said anything wrong.
e.g., "Just set up a belt sequence that would solve a 3-SAT problem" to show that belt sequencing is at least as hard as 3-SAT.
(The reverse, setting up a SAT solver to solve belt sequencing only shows that SAT is at least as hard as belt sequencing, which is true for any problem that's not hard hard).
Yes, basically true for any problem where you can verify a correct answer in polynomial time (especially if someone gives you extra hints to help your verification).
You can also think of these 'hints' as 'extremely lucky guesses'.
Eg you can verify that a number is composite, and not prime, by 'guessing' its prime factors.
Or you can guess the solution to a Sudoku and then just verify it.
The traveling salesman problem is interesting: it's trivial to verify that any given candidate solution has a specific cost (and that cost can be very low), but it's not trivial to verify that the candidate is minimal. (I'm not even sure it's possible in polynomial time.)
I've repeatedly encountered people using crappy solutions to problems because they read some result from complexity theory that made them think they couldn't do better. .. when in reality a slightly smarter algorithm does much better on average.
Consider for example the min cover problem: You have a set of bit vectors and you want to find the minimum collection where at least one vector is true for every bit. (e.g. optimizing a collection of tests). There is a simple greedy algorithm-- include the vector that covers the most yet-uncovered bits. There is a proof that this algorithm achieves the best possible worst case approximation error.
But in practice this is a useless result. Worst case approximation error is driven by pathological inputs. It's easy to come up with modifications of the greedy algorithm that significantly improve the quality of the solutions on average (or at least do in the sorts of real problems I've applied it to).
The author was missing the words "in NP" if they are talking about complexity.
We ended up removing it from the default quickstarts [1], but maybe we should reinstate it in timefold-sandbox?
[1] https://github.com/TimefoldAI/timefold-quickstarts/commit/d9...
The balancer issue is different in particular but in my experience, for this kind of problem, using z3 and cvc5 give much faster result than mnilp solvers or cp-sat. On smaller models they are all quite fast. But as it gets larger it's actually much faster for me to binary search an optimal objective through sat with z3 or cvc5 than it is to ask most nlp solvers to optimize it. I haven't tried gurobi or cplex of course.
But I expect this is because of their ability to do really effective incremental solving so that binary searching the objective is very efficient (z3 has an optimizer and soft constraints but they do not advertise it as supporting non linear logic and I can get it to hang on some models)
Especially for this type of problem, I would consider using an SMT solver and seeing how it does
If you stick with Clos networks, a homegrown solver using bdds is probably quite fast and wildly memory efficient.
Not natively, but the game gives you a lot of tools. You could probably add some of those things with circuits (the "Factorio redstone"), or with a little more effort writing a mod.
The game is hard deterministic (so that multiplayer works) despite having plenty of multithreaded optimizations. You could probably do something with it. Although that may raise some eyebrows.
Personally I find the new DLC with compact design on space platforms to be really fun that way. Back pressure has been a necessary mechanism to create to prevent all sorts of deadlocks for instance.
https://github.com/Card-Forge/forge
You'd need an AI player API, something that lets you hook an AI player into the engine and run it without graphics obviously so you can train fast. Forge has an AI player (or more?) but I don't know if can be used that way.
I guess with a bit of elbow grease you could make a bot to play Arena (and even play against itself), but that may not be acceptable by WotC.
> Example of 4 x 4 naïve Throughput-Limited belt balancer. This is not what we want.
is this because a slowdown on belt #1 doesnt then get filled by belts 3 and 4? so this isn't a properly completely rebalancing system?
> 4 x 4 Throughput-Unlimited belt balancer. This is what we want.
but then this is weird too. the top left tunnel entrance thingy goes down and then immediately up again. why? maybe it tunnels all the way to the top right, in which case it has the same exact flaw as the first throughput limited example that we didnt want - belts 3 and 4 dont get to redistribute their stuff to it if belt 1 dies.
thanks but also i am very intimidated by how much work you put into this game lol
is this why i am a bad engineer
In the naive solution you are effectively allocating a single belt output from each layer-1 mixer, so the system will run at half throughput. But the fan-out to a pair of mixers in layer-3 does mean that your 4 output belts are balanced, which might be good enough in some cases - for example of downstream smelters have lower capacity than the theoretical 4-belt max throughput.
The low level uops (microops) of a CPU seem to be relevant.
Openttd is another example of a game where you can implement train signalling.
You are literally describing balancing. You are using an ad hoc solution as opposed to a blueprint, which can be fine, but I wouldn’t dismiss the convenience of being able to belt off a line of variable consumption from your bus and then guarantee each line down the bus will continue to have a fair flow of components. You clearly appreciate that this is desirable, and are solving for it in your own way.
If you're tapping off the side most lane it doesn't matter what balancer you have at the head of the bus, you have to "balance" it after that point.
Furthermore, if you need real balancers in the middle of your bus to prevent the later stages of the line from being starved, that's a failure to plan for sufficient capacity. Balancers are a convienent way to patch over that mistake, but that's the sort of thing I'm talking about when I say they're cope.
Space Age (the most recent DLC) required me to use several 6:4 and 6:3 balancers.
I usually start by hacking it. Once I place a premade balancer, throughout dramatically improves.
For instance on Gleba, you better have a plan to either use or burn the full belt. It doesn't matter if you're balancing the lanes, you need a plan for the same throughput of spoilage.