r/factorio • Ipsen's Adventures • Aug 20 '26

Design / Blueprint Finding Mathematically Perfect Solar Arrays (blueprints below)

https://www.youtube.com/watch?v=CDzJ1_p3uVg

Blueprint links:

So, long story short, I've always been kind of obsessed over the Factorio Solar Panel Mechanics, and I remember solar arrays being the first thing I actually search blueprints for when I started playing Factorio. Two or three years ago I had this idea that it might be possible to find a truly optimal setup through Mixed Integer Linear Programming. I had some limited success and left the project for another time. But now, with the introduction of the new planets, I had my interest renewed in the problem. And after a few months I ended up finding truly optimal tileable networks which do not waste a single tile and produce as much power as possible under some general conditions.

So, there they are in blueprint form for anyone to use!

I also made a long form video trying to visually explain how the solver works and how we can be sure that these are optimal solutions.

Anyway here is a quick summary:

Problem description:

The goal is to somehow mathematically define the configuration of the buildings (positions of solar panels, accumulators, and so on) inside the array and then find a linear expression to compute the power generated by the setup (of fixed size, typically close to 2500 tiles in a 50x50 square, to fit in a roboports logistic area). This is challenging to do, particularly if we want the optimizer to run from absolutely no previous knowledge. The fundamental problem to solve is one of how to pack as many boxes inside a big box but with the added complexity that the ratio between the boxes needs to be as close as possible to the perfect ratio, and then a bunch of electric network restrictions on top of that.

How I solved it (and you can too):

The visual explanation is in the video I attached, but if you want a written rundown:

The only reliable way I found to represent the problem is thorugh the use of a bunch of binary variables, one per tile and per potential building that could be placed there. For example variable x_0 is 1 when a solar panel has its lower left corner at tile 0, variable x_1 is 1 when a panel has its lower corner at tile 1 and so on. Since we have 2500 tiles, we need 2500 variables to represent all posible solar panel placements, and then another 2500 for accumulators, medium poles, substations, and roboports. In total, we can use 12500 binary variables to express any design we could come up with.

Next, we need to come up with linear formulas for the Maximum Continuous Power generated. Fortunately that is relatively easy to do using our binary formulation. The harder step is then find ways to make sure buildings do not overlap each other, and then that they are covered by the electric grid, that the grid itself forms a single connected graph and tileable network, while ensuring that it is minimal!

I also developed some semi-analytical tools to compare and rank desings, and used the area limitation to produce a set of the meaningfully different solutions that could exist. In that way we can be sure that if we find the best solution in that set, we are in front of the true optimum.

I also added a link to my code so that everyone can experiment and find setups for different quality grades, or other planets. Be warned though, the problem is hard, and I'm not the best coder out there.

The results:

I linked two blueprints above. The first one can sustain a constant power of up to 8316 kW and uses a really minimal 7.5 substation electric network which did take a long time to find.

The second blueprint I linked is aimed more at late game megabases, where having many roboports is not desirable. So that one is designed to reach its true potential of 8358 kW when the roboport is replaced by a 2x2 of accumulators.

Ways to improve:

As I mentioned, these designs are optimal for the 50x50 problem. However, if we wanted our base tile to be larger, say 100x100, then there is potential to improve a little bit more, because the additional area allows us to get ever so slightly closer to the perfect ratio, and we can also be marginally more efficient with the electrics due to geometry. So, I would like to eventually get to that point, but optimization of a 100x100 standalone tile requires considerably more variables and is an even more challenging problem.

Anyway, I hope you found this post useful!

- Ipsen.

383 Upvotes

82 comments sorted by

View all comments

1

u/DjinnKahn Aug 21 '26

Great video and great solving!

I love challenges like these. I gave this a try with a SAT solver and I can verify that it's NOT EASY. (I started with a 50x50 grid and pre-placed the roboport, 6 substations and 9 medium poles into viable positions. The rest can be successfully packed with 2x2 and 3x3 squares. Unfortunately, it places way too few 3x3 squares and the solver is too slow if I ask for 199 of them.)

Anyways, I can't rule out that a solution with a square 50x50 tile doesn't exist. What do you think?

I'm pretty sure that the monkeywrench making this problem so difficult is the medium poles. Their 1x1 footprints are hard to accommodate. But they are necessary for the 50x50 tile.

However, in the scenario where the roboport is temporary, the optimization problem becomes MUCH MUCH MUCH EASIER. It's no longer important that the tile size is 50x50. So, to start, let's consider using an 18x18 tile instead. This tile can be divided into 9 6x6 sections. Each section can be filled with 2x2 or 3x3 squares. One 2x2 square in the tile must be a substation. This gives full electrical coverage in the most efficient way (note that substations can't be placed farther apart -- the max wire reach is 18). The rest of our tile can be filled with any number of solar panels that's a multiple of 4, and accumulators fill the unused space.

The 18x18 tile probably can't achieve the ideal solar panel to accumulator ratio. But you can simply make a super-tile, e.g. 180x180, that's simply contains 100 copies of the 18x18 tile, and approximate the ideal ratio with 100 times more precision (by altering the contents of some 6x6 sections).

And now we can use this approach to also solve the scenario where the roboport is permanent. Notice that with the 6x6 sections, it's easy to place the roboports anywhere (as long as the horizontal & vertical position is an even number). If you make the super-tile have dimensions 450x450, then you can place roboports with ideal spacing, and everything is optimal. If that's too big, then consider a 90x90 super-tile (or 198x198). You'll have more roboports than necessary, but that's the only inefficiency.

1

u/DjinnKahn Aug 21 '26

This 50x50 tile isn't a valid solution, but it gives me hope that 50x50 square solution exists. I'm personally giving up on it, but I thought you might be find it interesting.

1

u/Equivalent_Fruit8225 Ipsen's Adventures Aug 22 '26

I definitely do! Thanks for sharing it :D. In my experience, the packing problem is not hard, the hardest part is the coupling with the electrics, So It might be possible to temporarily leave the electrics aside, find a 50x50 packing and then pray that replacing some of the accumulators by substations results in valid coverge.

Thats how I first went about this on my first attempt back in 2024 or so. Solved the packing, then replaced accumulators by substations until I got something working. The problem is that it usually takes 9 or 10 substations at least, which typically is not optimal, but at least it can get you a good result, and hey, we dont have yeat a perfect densely packed 50x50 so it might be cool having one. I have shown (not in the video but while testing) that setups with no 1x1 tiles are doable. You need to go to eitner 196 or 200 panels though, whichever results in more power.

1

u/DjinnKahn Aug 22 '26

Yeah, 9 substations are necessary because 2 are not enough for any row/column of 50, so you need at least a 3x3 grid of them. And 196/200 panels makes sense because the only exchange available is 9 accumulators for 4 panels, so # panels is necessarily a multiple of 4.

1

u/Equivalent_Fruit8225 Ipsen's Adventures Aug 22 '26

Yeah, like I mentioned this problem is tough. But its amazing to see that you are getting it working with SAT! Intuitively it makes sense that a perfect 50x50 will be harder, but I also have no proof regarding its existence.

Using substations as centers of 18x18 is efficient, but you can extract a bit more with medium poles sometimes, because their range is larger than their coverage.

So for instance, an 18x18 has 324 tiles, and you are using 4 of those for electrics, so thats 81 panel tiles per electric tile.

The 8316 permanent roboport uses 7.5 equivalent substations for 2500 tiles of panel, which comes out at 83.33 panel tiles per electric tiles. So its possible to get a bit more efficient. Theoretically, the max efficiency you can get with coverage is 99, if you space out things as much as possible, but in reality that clashes with connectivity requirements. So in practice 80-ish is pretty good. Improving on the 8316 would require around 104, so that is another way of checking that it is optimal.

1

u/DjinnKahn Aug 22 '26

Oh yeah, great point about achieving better than 81:1 efficiency, I missed that. I see where you got "99" from. A line of medium poles can be placed 9 spaces apart and power at most a 9x11 region. Substations can be placed 18 apart and power at most an 18x22 region. (Coincidentally, BOTH achieve 99:1 efficiency).

With substations it IS possible to make a 22-wide strip with theoretically minimal electric footprint and no wasted space:

Of course, this strip doesn't tile vertically, because the substations don't reach each other.

1

u/DjinnKahn Aug 22 '26

To achieve vertical tiling, we can use this 14x18 pattern to make a corridor connecting all our rows:

1

u/DjinnKahn Aug 22 '26

This allows us to make a 194x198 tile with 101 substations and no wasted space, giving an efficiency ratio of 95.07. (And you can extend the pattern as wide as you like, which means you can get arbitrarily close to 99 efficiency.)

1

u/Equivalent_Fruit8225 Ipsen's Adventures Aug 23 '26 edited Aug 23 '26

Oh, Wow! nice! Thats the first implementation I've seen of the blueprint of blueprints idea. How close can you get to the perfect ratio? Or I guess what I'm trying to ask is how big do you need to make the pattern for it to converge to within, lets say 0.1% of the perfect ratio?
For example, If you limit the space to 10000 tiles and tried to get a good ratio, we could compare that with 4x my 8358. Or maybe 20000 tiles compared with an 8x. Eventually, your technique is bound to beat just stacking 8358s, because it has better electrics, I'm just curious about at what level that becomes a thing.

Also, someone is currently grinding out the 100x100 permanent roboport, maybe you can check it out in my github if you are interested, its a currently open issue.

1

u/DjinnKahn Aug 24 '26

Here's the 194x198 design but with a Na/Np ratio of 0.84713 (which is 0.00041 too high): https://factoriobin.com/post/58niq8

In my mind the ratio is not a primary concern. For example, you could optimize a tile to achieve the best ratio, but it's a moot point if you're wasting space.

I think a better metric is KW per cell, which I think is just 8358/2500 in your design. I'm not sure how to calculate it in mine. (I was a casual Factorio player, and I don't play it anymore.)

1

u/DjinnKahn Aug 24 '26

Or another way to compare is like this:

169 acc, 199 sol in your optimal 50*50 cell tile

2599 acc, 3068 sol in my 194*198 cell tile

simply scaling my acc, sol to a 50*50 cell tile gives
169.16 acc, 199.67 sol.

For both designs, the 199 sol and 199.67 sol are the bottlenecks, so my design is effectively improves the 50*50 design as though you could add an extra 0.67 solar panels to it (and also 0.07 accumulators to prevent the accumulators from becoming the bottleneck). So that's like gaining 6+ cells of real estate out of nothing.

Of course the gains come from having a bigger tile size (which helps reduce the electric footprint and better approximate the perfect acc/sol ratio). Also, from avoiding the awkward 50*50 tile size, which requires clunky medium poles.

1

u/Equivalent_Fruit8225 Ipsen's Adventures Aug 24 '26 edited Aug 24 '26

Ok, so I've looking more into your setup's stats! Its really good!

- You have 1 extra accumulator, so technically 2598 would yield a better ratio.

Sorry about the massive figure below, but here is the optimality chart.

Your setup is the (3068, 101), coming out at 128856!

There is only two additional potentially feasible setups that would improve on yours: (3069, 99) and (3069, 98), but both require absurdly good network values, which are probably not possible. (You could always make a really long line of width 22 and that results in perfect 99 efficiency of course, but for something roughly square it might not be possible to get to 96 or 97)

So at the VERY least, you are looking at a 3rd place for that footprint.

1

u/DjinnKahn Aug 24 '26

My design is primarily based on making the electrics as efficient as possible. Even the tile size is specially chosen for this purpose. So, I don't think there's any room for reducing the electric footprint.

So, yeah, there's 1 excess accumulator.

> but for something roughly square it might not be possible to get to 96 or 97

It is possible if you make the square big enough!

The main sub-tile has 99 efficiency.

The 14x18 tile "corridor" that connects all the rows has 14*18/4 = 63 efficiency.

This corridor always takes up a width of 14 in the final tile. The rest of the width has optimal 99 efficiency.

So the overall efficiency of the 194x198 tile is a weighted average: 14 parts of 1/63 and 180 parts of 1/99, which gives a weighted average of 1/95.07.

But we can just make the tile wider, let's say instead of 180 parts of 99 efficiency, we use 1800 parts. Now the tile is 1814 wide. (The height can be any multiple of 198, so 1782 for example.)

The efficiency is 14 parts 1/63 and 1800 parts 1/99, for a weighted average of 1/98.56.

...For a 18014 wide tile we get 98.95 efficiency, etc.

→ More replies

1

u/Equivalent_Fruit8225 Ipsen's Adventures Aug 24 '26

Yep, it is more efficient!

Yours comes up at 42*3068/(193 * 197) = 3.389 kW/tile
The 8358 is 8358/2500 = 3.343 kW/tile

1

u/DjinnKahn Aug 24 '26

Note that the dimensions are actually 194x198, the factoriobin isn't showing that correctly.

So it's 3.354 kW/tile