# How to calculate all possible resistances made from 5 distinct resistors in series and/or parallel? [closed]

Five distinct resistors resistors={1,2,3,4,5} are given. The objective is to find a list of all possible resistances obtained by configuring all these resistors in any series and/or parallel forms.

How can I do with Mathematica?

## closed as unclear what you're asking by Daniel Lichtblau, m_goldberg, José Antonio Díaz Navas, M.R., rhermansAug 31 '18 at 8:21

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

• What version of Mathematica do you use? – Alex Trounev Aug 24 '18 at 11:34
• Of your question, the title asks for the configurations (i.e. circuits) and the body asks just for their resistances. Which do you want? – Michael E2 Aug 24 '18 at 13:10
• Series and parallel are not the only way resistors can be connected. You can also do this: i.stack.imgur.com/3Hhe4.png Once you have all graphs generated, computing the resistance is easy. You'll need to use IncidenceMatrix and write equations for: currents summing to 0 in all nodes; current-voltage relationship; use the potential at each node to compute potential differences for each edge. Thus the difficult part is generating all valid graphs. – Szabolcs Aug 24 '18 at 13:12
• @MichaelE2: The resistance is the most required. – Friendly Ghost Aug 24 '18 at 13:23
• You have not actually clarified if you only want series/parallel arrangement or all possible connectivity patterns. Please make this explicit in the question. – Szabolcs Aug 30 '18 at 13:54

Any connection of resistors in series and/or parallel can be seen as a tree in which branch nodes are connection types and leaves are resistors.

Series connection of a resistor with series connection of two other resistors is just a series connection of all three resistors, in other words series connection is described by an associative (or Flat) branch node. Same is true for parallel connection.

Series or parallel connection of one resistor with second one is the same thing as connection of second one with first one, so connections are described by commutative (or Orderless) branch nodes.

# Groupings

To generate all necessary trees we can use Groupings function.

Since series and parallel connections are Flat, we can limit ourselves to generating binary trees, so we'll use 2 as branch arity.

Groupings function groups subsequences of given list and we need not only subsequence groupings but all subset groupings, so as first argument we'll use Permutations of set of resistors.

With Permutations of resistors, as first argument, we don't need more than one representative for each collection of expressions whose tree structure is equivalent up to permutation of the branches, so we can use {2, Orderless} as arity specification.

Putting it together we get 472 combinations:

DeleteDuplicates@Groupings[
Permutations@{r1, r2, r3, r4, r5},
{Plus, 1/Total[1/{##}] &} -> {{2, Orderless}}
] // Short
(* {r1+r2+r3+r4+r5, 1/(1/r1+1/r2)+r3+r4+r5, r2+1/(1/r1+1/r3)+r4+r5,
r2+r3+1/(1/r1+1/r4)+r5, <<465>>, 1/(1/r1+1/r2+1/r4+1/(r3+r5)),
1/(1/r1+1/r2+1/r3+1/(r4+r5)), 1/(1/r1+1/r2+1/r3+1/r4+1/r5)} *)
% // Length
(* 472 *)


After flattening many binary groupings can give same grouping with higher arity. Also we start with all permutations of resistors, so we'll end up with many groupings that differ only by permutations of resistors within node, so for orderless connection they describe same system. That's why initially we get a lot of duplicates in our list:

Groupings[
Permutations@{r1, r2, r3, r4, r5},
{Plus, 1/Total[1/{##}] &} -> {{2, Orderless}}
] // Length
(* 5760 *)


That's why this approach won't scale well to larger numbers of resistors.

# orderlessTrees

To remedy problems mentioned above we can directly generate all relevant "orderless trees".

ClearAll[orderlessTrees, hold, extendOrderlessTreeBranchAt, extendOrderlessTrees]
SetAttributes[{hold, extendOrderlessTreeBranchAt, extendOrderlessTrees}, HoldAllComplete]

extendOrderlessTreeBranchAt[tree_, leaf_] := Function[Null,
ReplaceList[
First@Extract[tree, {#}],
{
hold[pre___, x_, post___] :> ReplacePart[tree, {#} -> hold[pre, hold[x, leaf], post]],
l_hold :>  ReplacePart[tree, {#} -> Append[l, Unevaluated@leaf]]
}
],
HoldAllComplete
]

extendOrderlessTrees[trees_, leaf_] := Flatten[
Function[Null,
{
{{hold[#, leaf]}},
extendOrderlessTreeBranchAt[#, leaf] /@ Position[#, _hold, Heads -> False]
},
HoldAllComplete
] /@ trees,
3
]

orderlessTreesInternal = Function[Null,
Fold[extendOrderlessTrees, {hold[#1, #2]}, Unevaluated@{##3}],
HoldAllComplete
];

orderlessTrees@_[] = {};
orderlessTrees[l : _@_] := {l}
orderlessTrees[h_@x__] := Identity[With][{hold = h}, Evaluate@orderlessTreesInternal@x]


Now we can directly generate all relevant for us groupings:

orderlessTrees@Range@3
(* {{{1, 2}, 3}, {{1, 3}, 2}, {1, {2, 3}}, {1, 2, 3}} *)


not only ordered subsequence groupings:

Groupings[Range@3, {2, 3}]
(* {{1, 2, 3}, {{1, 2}, 3}, {1, {2, 3}}} *)


nor groupings with duplicates coming from all permutations:

Groupings[Permutations@Range@3, {{2, Orderless}, {3, Orderless}}]
(* {{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1},
{{1, 2}, 3}, {{1, 3}, 2}, {{2, 1}, 3}, {{2, 3}, 1}, {{3, 1}, 2}, {{3, 2}, 1}} *)


Since nodes representing our connections are Flat, directly inside series node there can be only parallel nodes (or "bare" resistors) and vice versa. So single "orderless tree" can be transformed into two connections. One with nodes on odd levels representing series connections and nodes on even levels - parallel connections, and one with series connections on even levels and parallel on odd levels.

We can perform above transformation by Folding Apply function.

seriesParallelResistances // ClearAll
seriesParallelResistances[l : {_}] := l
seriesParallelResistances[l : {rs__}] := Module[
{testQ, levels = Range[Length@l - 1, 1, -1], trees = orderlessTreesInternal@rs},
Table[
Sequence @@ Fold[Apply[If[testQ@#2, Plus, 1/Total[1/{##}]&], #1, {#2}] &, trees, levels],
{testQ, {OddQ, EvenQ}}
]
]


Using seriesParallelResistances we get the same resistances as with Groupings:

seriesParallelResistances@{r1, r2, r3}
(* {1/(1/r1 + 1/r2) + r3, r2 + 1/(1/r1 + 1/r3), r1 + 1/(1/r2 + 1/r3),
r1 + r2 + r3, 1/(1/(r1 + r2) + 1/r3), 1/(1/r2 + 1/(r1 + r3)),
1/(1/r1 + 1/(r2 + r3)), 1/(1/r1 + 1/r2 + 1/r3)} *)
Sort@% === Sort@DeleteDuplicates@Groupings[Permutations@{r1, r2, r3}, {Plus, 1/Total[1/{##}] &} -> {{2, Orderless}}]
(* True *)


but faster and using less memory:

tmp = {r1, r2, r3, r4, r5};
res1 = seriesParallelResistances@tmp; // MaxMemoryUsed // RepeatedTiming
res2 = DeleteDuplicates@Groupings[Permutations@tmp, {Plus, 1/Total[1/{##}] &} -> {{2, Orderless}}]; // MaxMemoryUsed // RepeatedTiming
Sort@res1 === Sort@res2
(* {0.0060, 328800} *)
(* {0.174, 5055352} *)
(* True *)

tmp = {r1, r2, r3, r4, r5, r6};
res1 = seriesParallelResistances@tmp; // MaxMemoryUsed // RepeatedTiming
res2 = DeleteDuplicates@Groupings[Permutations@tmp, {Plus, 1/Total[1/{##}] &} -> {{2, Orderless}}]; // MaxMemoryUsed // RepeatedTiming
Sort@res1 === Sort@res2
(* {0.0871, 4611032} *)
(* {5.25, 147111488} *)
(* True *)