3

Switching Network

Engines numbered 1, 2, ..., n are on the line at the left, and it is desired to rearrange(permute) the engines as they leave on the right-hand track. An engine that is on the spur track can be left there or sent on its way down the right track, but it can never be sent back to the incoming track. For example if n = 3, and we ha the engines numbered 1,2,3 on the left track, then 3 first goes to the spur track. We could then send 2 to the spur, then on the way to its right,then send 3 on the way, then 1, obtaining the new order 1,3,2. We have to find all the possible permutations for specific n.

For n=1, answer = 1;

For n=2 answer = 2;

For n=3 answer = 5;

Didn't find any generality. Using Stack Implementation would be very helpful.

But any solution is welcomed.

p.s. This is not a homework question, as I am a self taught person.

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
  • 1
    At the very least, disallowed permutations include any with at least two displaced sequential numbers (for example, `3` and `4` displaced but still sequential - `[1,3,4,2]`, `[3,1,4,2]`) or any with the first number at the end and not completely reversed (like `[4,2,3,1]`). I wonder if there are other generalized rules. – גלעד ברקן May 09 '15 at 17:34
  • i hope you find more generalisation –  May 09 '15 at 17:38
  • There is something wrong with your problem description. If the number of permutations for n=3 is 5, not 6, that must mean that only one engine can fit on the spur. But in your description you can say that 3 then 2 can go onto the spur. – Edward Doolittle May 10 '15 at 04:20
  • @EdwardDoolittle all the combinations except 231 is possible. So only 5 combinations is possible –  May 10 '15 at 04:23
  • OK I see, your problem description is correct then for n=3. But the question remains, how many engines can fit on the spur? – Edward Doolittle May 10 '15 at 04:26
  • you can fit upto n engines on the spur. See for the combination 3,2,1 we fit all the 3 engines in the spur then make them leave the spur –  May 10 '15 at 04:28

3 Answers3

3

Here's my attempt at a recursive solution (see comments in Java code):

private static int result = 0;
private static int n = 3;

public static void g(int right,int spur){
  if (right == n) // all trains are on the right track
    result++;
  else if (right + spur < n) // some trains are still on the left track
    g(right,spur + 1); // a train moved from the left track to the spur
  if (spur > 0) // at least one train is on the spur
    g(right + 1,spur - 1); // a train moved from the spur to the right track 
               // (also counts trains moving directly from the left to right track)
}

public static void main (String[] args){ 
  g(0,0);
  System.out.println(result); // 5
}

The recursive solution above actually counts each possibility. For a combinatorial solution we consider all combinations of n movements on and out of the spur, where adjacent such movements are equivalent to movements directly from the left to right track. There are 2n choose n such combinations. Now let's count the invalid ones:

Consider all combinations of (n - 1) ins and (n + 1) outs of the spur. All these include a point, p, where a train is counted as leaving the spur when no trains are on it. Let's say that p has k ins and (k + 1) outs preceding it - then the number of remaining ins is (n - 1 - k); and remaining outs, (n + 1) - (k + 1) = (n - k).

Now reverse the ins and outs for each one of these combinations starting after p so that in becomes out and out in. Each one of the reversed sections has necessarily (n - k) ins and (n - 1 - k) outs. But now if we total the number of ins and outs before and after p we get k + (n - k) = n ins, and (k + 1) + (n - 1 - k) = n outs. We have just counted the number of combinations of n ins and n outs that are invalid. If we assume that one such combination may not have been counted, theoretically reverse that combination after its p and you will find a combination of (n - 1) ins and (n + 1) outs that was not counted. But by definition we counted them all already so our assumed extra combination could not exist.

Total valid combinations then are 2n choose n - 2n choose (n + 1), the Catalan numbers.

(Adapted from an explanation by Tom Davis here: http://mathcircle.berkeley.edu/BMC6/pdf0607/catalan.pdf)

גלעד ברקן
  • 23,602
  • 3
  • 25
  • 61
  • Sorry, i don't know anything about js. But it will be helpful if you provide me an algorithm like @FabioTurati –  May 10 '15 at 03:40
  • @KishanKumar I did my best to convert the code from JavaScript to Java (at which I am not adept). As for the algorithm - all I did was code the conditions you stated in the question (see the comments in the code). – גלעד ברקן May 10 '15 at 05:33
1

First, note that you may ignore the possibility of moving the train from incoming directly to outgoing: such a move can be done by moving a train to the spur and then out again.

Denote a train move from incoming to spur as ( and a train move from spur to outgoing as ), and you get a bijection between permutations of the trains and strings of n pairs of correctly balanced parenthesis. That statement needs proving, but the only hard part of the proof is proving that no two strings of balanced parentheses correspond to the same permutation. The number of such strings is the n'th Catalan number, or choose(2n, n)/(n+1), where choose(n, k) is the number of ways of choosing k items from n.

Here's code to compute the solution:

def perms(n):
    r = 1
    for i in xrange(1, n+1):
        r *= (n + i)
        r //= i
    return r // (n + 1)

You can generate all the permutations with this code, which also exposes the Catalan nature of the solution.

def perms(n, i=0):
    if n == 0:
        yield []
    for k in xrange(n):
        for s in perms(k, i+1):
            for t in perms(n-k-1, i+k+1):
                yield s + [i] + t

print list(perms(4))

Output:

[[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], [0, 2, 3, 1],
 [0, 3, 2, 1], [1, 0, 2, 3], [1, 0, 3, 2], [1, 2, 0, 3],
 [2, 1, 0, 3], [1, 2, 3, 0], [1, 3, 2, 0], [2, 1, 3, 0],
 [2, 3, 1, 0], [3, 2, 1, 0]]
Paul Hankin
  • 54,811
  • 11
  • 92
  • 118
0

The status of the system can be described by giving the 3 (ordered!) lists of engines, in the left, spur and right tracks. Given the status, it is possible to calculate all the possible moves. This creates a tree of possibilities: the root of the tree is the initial status, and every move corresponds to a branch which leads to a new status. The final status at the end of a branch (a leaf) is your final position in the right track.

So, you have to build and explore all the tree, and at the end you have to count all the leaves. And the tree is a common data structure.

Just to clarify, the tree in this case wouldn't replace the stacks. The stacks are used to store your data (the position of the engines); the tree is used to track the progress of the algorithm. Every time you have a status (a node of the tree) you have to analyse your data (=the content of the stacks) and find the possible moves. Every move is a branch in the tree of the algorithm, and it leads to a new status of the stacks (because the engine has moved). So basically you will have one "configuration" of the 3 stacks for each node of the tree.

  • I have just started learning DSA. So sorry to say. I have no idea about trees. I got this question in the 2nd chapter itself. So its possible to be solved by using stack. Nw going to study trees. After i finish stack –  May 09 '15 at 15:45
  • @KishanKumar: I have expanded my answer to make it clearer that the tree wouldn't replace the stacks. On the contrary, it would keep track of all the moves that you can make (or have already made). But the position of each engine would still be stored by the stacks. – Fabio says Reinstate Monica May 10 '15 at 02:17
  • can you give me a program written in C,C++ or java. –  May 10 '15 at 03:41