Page 1 of 1

almost Math.max using 8 combinators

Posted: Sun Sep 25, 2016 5:09 pm
by Cobaltur
So my Math.max implementation. It is my first complex combinator.

- due to value truncation it does not work well on small numbers e.g. "4 and 5" ; same as "The Largest Item Finder" in viewtopic.php?f=193&t=20732 which makes believe that the job can be done. This is not a problem for "4 and 6"
- I like to have all max signals . so for the example above there is the "wrong" result "4 and 5".

But for my train station setup (e.g. 50k, 0k, 120k, ... ) having multipe unload areas and for blocking rails this it is the first step.
Factorio_math_max.jpg
Factorio_math_max.jpg (35.71 KiB) Viewed 8964 times
blueprint 0.14.9
My main idea is to recursivley increase the average of the exising array. And to reduce the elements in the array by adding their negative opposite and the end of one cylce.

e.g. [20, 50, 80,90,100]
first round : N = 5, S = 360 => A = 72
[-20,-50, 80, 90, 100]
filtered ==> [-20,-50] ==> reinsert/add in first combinator ==> [20 + -20, 50 + -50, 80 + 0, 90 + 0, 100 +0 ]

2nd round : N = 3, S = 270 => A = 90
[-20,-50, -80, 90, 100]

4th N=2, S = 190 => A = 95
[-20,-50, -80, -90, 100] ==> filter only for positive ==> 100
Factorio_math_max_details.jpg
Factorio_math_max_details.jpg (90.08 KiB) Viewed 8964 times
detailed setup

Hm I thought it would be easy to flip some expression to get a Math.min but the setup does not yet stabilze. I have to keep trying...
And I´m suprised that this is still working. I made several tries and had alot of more NOOP combinators to stabilize the setup. Maybe I need them now again...


UPDATE 160916_2046:
setup is instable on certain array e.g. [2,5] because avererage of 2.5 is truncated to 2, and removing it from the array flickers. 2 combinators are doing the jobs - input *=1000 and output /=1000 - but this makes me not happy. Also the math.min is not that easy for. I think I'm still missing some skills and experiences.
Help is welcome.


Update 1.10.
I realized thinking in logic gates is not my nature :) and for smaller things the "best item finder" and its explained details withour recursion will do it for the most scenrios.
Therefore I won't spend any more time in vanilla combinators.

I started implementing the math.min, max and rand as new combinators https://mods.factorio.com/mods/Cobaltur/MathCoProcessor

Re: almost Math.max using 8 combinators

Posted: Tue Sep 27, 2016 5:05 pm
by Megatron
I tried that approach. It might be easier to filter out all that are above the average (EACH > A => EACH), then continue the loop with those remaining signals. It makes it work with negative values as well.
For min() it's the same algorithm. Just use (EACH <= A) instead of (EACH > A) which needs 2 combinators. Or you could invert the input and work with negative values and use (EACH < A) (all results will get truncated towards zero)

There is a problem though if all (remaining) singals have the same value. Subtracting the average will destroy all signals, and filtering it with my proposition doesn't work either because there is no value greater than the average.

To tackle this you could do something crazy, like scale the input, add a unique value to each (like wooden box = 1, iron box = 2, ..) then discard all values smaller than the scale factor, and perform the algorithm on the rest. Add the inverse of the unique signals in the end, discard the negative values and downscale to get to the final result. You might do this in parallel in case the other circuit couldn't come up with a single result.

However, you could always do the ugly approach, and loop through all possible signals, extract them one by one from the input and store their value if it's greater/less than another stored before.

Re: almost Math.max using 8 combinators

Posted: Thu Sep 29, 2016 9:18 pm
by Cobaltur
Oh substracting the average on all is also a nice idea.
In my approch I tried to keep all values and to flip only the sign into negative (besides the *=1000 & /=1000 surrounder for low values)

And for my station scenrio I can just add a checker "if this rail has to be blocked" if it is in the maximum list" (and not all are blocker afterwards).

But I'm new to this topic. I will definitly read more topics here.

Re: almost Math.max using 8 combinators

Posted: Sat Oct 01, 2016 3:26 pm
by Cobaltur
I stopped working on this.
Doing it as a mod seems is easier for me s. above.
I cannt wait for the day this will be in vanilla. Because I love to play vanilla.

Re: almost Math.max using 8 combinators

Posted: Tue Nov 08, 2016 12:06 am
by SeeDee
I had the exact same idea about calculating the maximum for deciding which loading station a train should go to. My reasoning was that I would check for each station if the number of items at that station was less than the maximum and in that case block that station, so that a train would always go to station with the maximum number of items. After reading some threads I realized that calculating the max for an arbitrary number of signals is no trivial task. However I found out that I don't actually need to calculate the max.

All I have to check for each station is whether any signal is higher than the number of items at the current station. This is something the decider can do out of the box. The remaining task was to remove any station that already has a train in it from checking against each other station's number of items.
Balance loading.png
Balance loading.png (1.09 MiB) Viewed 8617 times
Each station uses a separate signal to communicate its number of items to the other stations (I'm using "0", "1" and "2" in the image). This system is easily scalable to use more stations and it can handle identical amounts of items in different stations. The constant combinators in the image simply represent the number of items as read from the chests.

One thing I found confusing, though I think it helped me, is that a rail signal which is block by a circuit condition does NOT output Red, nor any other state, unless there is a train in the following rail segment.

Re: almost Math.max using 8 combinators

Posted: Wed Nov 09, 2016 11:12 pm
by Blurb
This seems a bit too easy, and I'm wondering if I've misunderstood what you want to accomplish.
Three decider combinators should be enough to output the smaller (or larger) of two integers A and B.
math(minmax).jpg
math(minmax).jpg (85.51 KiB) Viewed 8584 times
From left to right, combinators will be denoted 1, 2, 3 and so forth.

1 & 2:
Represent the function's input. They output variables A and B.

3:
A > B (Reversing inequality will change functionality between .min and .max)
C = 1

4:
C = 0
B

5:
C = 1
A

6:
ANY + 0
ANY
Function output. Serves no actual purpose.


The only issue I know of is that in cases where A = B, then output is B.
This is because C will be treated as 0, even if it's more like a NULL value.

Re: almost Math.max using 8 combinators

Posted: Wed Nov 09, 2016 11:22 pm
by DaveMcW
Blurb wrote:This seems a bit too easy, and I'm wondering if I've misunderstood what you want to accomplish.
Three decider combinators should be enough to output the smaller (or larger) of two integers A and B.
The goal is a JavaScript style Math.max, that can take any number of inputs, not just two.

Re: almost Math.max using 8 combinators

Posted: Thu Nov 10, 2016 6:28 pm
by SeeDee
To me calculating the max was just an intermediate step. My overall goal was to choose the train station at a mining outpost that had the maximum number of items stored, so that loading a train would would be as fast as possible. It would have been further complicated by the requirement that if one station already had train in it it should not block the other stations, even if they had fewer items.

As I tried to explain above I didn't actually have to calculate the max in the end. All I did was to check if any other station had more items than the current one. This is done directly by the rail signal. The other combinators are ensuring that the current amount of items is not passed on to the rest of the stations if the current stations is blocked by a train.