Generate multiple sequences of numbers with unique values at each index - algorithm

I have a row with numbers 1:n. I'm looking to add a second row also with the numbers 1:n but these should be in a random order while satisfying the following:
No positions have the same number in both rows
No combination of numbers occurs twice
For example, in the following
Row 1: 1 2 3 4 5 6 7 ...
Row 2: 3 6 15 8 13 12 7 ...
the number 7 occurs at the same position in both rows 1 and 2 (namely position 7; thereby not satisfying rule 1)
while in the following
Row 1: 1 2 3 4 5 6 7 ...
Row 2: 3 7 15 8 13 12 2 ...
the combination of 2+7 appears twice (in positions 2 and 7; thereby not satisfying rule 2).
It would perhaps be possible – but unnecessarily time-consuming – to do this by hand (at least up until a reasonable number), but there must be quite an elegant solution for this in MATLAB.

This problem is called a derangment of a permutation.
Use the function randperm, in order to find a random permutation of your data.
x = [1 2 3 4 5 6 7];
y = randperm(x);
Then, you can check that the sequence is legal. If not, do it again and again..
You have a probability of about 0.3 each time to succeed, which means that you need roughly 10/3 times to try until you find it.
Therefore you will find the answer really quickly.
Alternatively, you can use this algorithm to create a random derangment.
Edit
If you want to have only cycles of size > 2, this is a generalization of the problem.
In it is written that the probability
in that case is smaller, but big enough to find it in a fixed amount of steps. So the same approach is still valid.

This is fairly straightforward. Create a random permutation of the nodes, but interpret the list as follows: Interpret it as a random walk around the nodes, and if node 'b' appears after node 'a', it means that node 'b' appears below node 'a' in the lists:
So if your initial random permutation is
3 2 5 1 4
Then the walk in this case is 3 -> 2 -> 5 -> 1 -> 4 and you creates the rows as follows:
Row 1: 1 2 3 4 5
Row 2: 4 5 2 3 1
This random walk will satisfy both conditions.
But do you wish to allow more than one cycle in your network? I know you don't want two people to have each other's hat. But what about 7 people, where 3 of them have each other's hats and the other 4 have each other's hats? Is this acceptable and/or desirable?

Andrey has already pointed you to randperm and the rejection-sampling-like approach. After generating a permutation p, an easy way to check whether it has fixed point is any(p==1:n). An easy way to check whether it contains cycles of length 2 is any(p(p)==1:n).
So this gets permutations p of 1:n fulfilling your requirements:
p=[];
while (isempty(p))
p=randperm(n);
if any(p==1:n), p=[];
elseif any(p(p)==1:n), p=[];
end
end
Surrounding this with a for loop and for each counting the iterations of the while loop, it seems that one needs to generate on average 4.5 permutations for every "valid" one (and 6.2 if cycles of length three are not allowed, either). Very interesting.

Related

How can I identify what class of graph algorithm to apply to this problem and possibly how to solve it?

I have this graph problem I would like to solve. I am not sure what algorithm to apply to it.
Maybe depth first search, topological sort or something else. Even if I know which one was
necessary I am not sure I would be able to apply it. Maybe someone can point me in the right
direction. If you want to completely solve it, you are also welcome, but you should also explain
it, because that's also important and not just get the code. Thank you in advance.
Problem statement:
In the city of N, under unclear circumstances, the territory of one of the factories turned into
an anomalous zone. All entrances to the territory were blocked, and it was named an industrial zone.
There are N buildings in the industrial zone, some of them connected by roads. On any road, you
can move in both directions.
A novice stalker was given the task to get to the warehouse in the industrial zone. He found
several maps of the industrial zone's territory in the electronic archive.
Since the maps were created by different people, each of them contains information
only about certain roads in the industrial zone. The same road can appear on several maps.
On the way, the stalker can upload one map from the archive to the mobile phone.
When loading a new map, the previous one is not saved in the phone's memory.
The stalker can only move along roads marked on the currently loaded map.
Each card download costs 1 dollar. To
minimize costs, the stalker needs to choose a route that allows them to load maps as few times as possible.
A stalker can download the same map several times, and you will have to pay
for each download. Initially, there is no map in the mobile phone's memory.
You need to write a program that calculates the minimum amount of expenses required
for a stalker to get from the entrance to the industrial zone to the warehouse.
Input data format:
The first line of the input file contains two natural numbers N and K (2 ≤ N ≤ 2000; 1 ≤ K ≤
2000) — the number of buildings in the industrial zone and the number of maps, respectively.
The entrance to the industrial zone is located in
building number 1, and the warehouse is located in building number N.
The following lines contain information about available maps.
First line of the I-th description maps contains the number ri— the number of roads marked on the i-th map.
Then come ri-strings containing two natural numbers a and b each (1 ≤ a, b ≤ N; a ≠ b)
indicating that there is a road connecting buildings a and b on the i-th map.
The total number of roads marked on all maps does not
exceed 300,000 (r1+ r2+ … + rK ≤ 300 000).
Output data format:
In the output file, you need to output one number — the minimum amount of expenses of the stalker.
If you can't get to the warehouse, print the number -1.
Examples or test cases:
Example 1:
Input:
5 3
1
3 4
3
1 2
1 3
2 4
1
4 5
output:
2
Example 2:
Input:
5 3
2
3 2
4 5
1
2 1
2
1 3
5 4
output:
-1
Example 3:
input:
12 4
4
1 6
2 4
7 9
10 12
3
1 4
7 11
3 6
3
2 5
4 11
8 9
5
3 10
10 7
7 2
12 3
5 12
output:
3

Unable to solve a codechef puzzle?

I am trying to solve this apparently beginner level problem. But not even able to come up with a brute force approach.
Here is the problem statement:
Johnny has some difficulty memorizing the small prime numbers. So, his computer science teacher has asked him to play with the following puzzle game frequently.
The puzzle is a 3x3 board consisting of numbers from 1 to 9. The objective of the puzzle is to swap the tiles until the following final state is reached:
1 2 3
4 5 6
7 8 9
At each step, Johnny may swap two adjacent tiles if their sum is a prime number. Two tiles are considered adjacent if they have a common edge.
Help Johnny to find the shortest number of steps needed to reach the goal state.
Input
The first line contains t, the number of test cases (about 50). Then t test cases follow. Each test case consists of a 3x3 table describing a puzzle which Johnny would like to solve.
The input data for successive test cases is separated by a blank line.
Output
For each test case print a single line containing the shortest number of steps needed to solve the corresponding puzzle. If there is no way to reach the final state, print the number -1.
Example
Input:
2
7 3 2
4 1 5
6 8 9
9 8 5
2 4 1
3 7 6
Output:
6
-1
Here is a start on Python for finding the distance to ALL boards that are reachable from the start.
start = '123456789'
needed_moves = {start: 0}
work_queue = [start]
while (len(work_queue)):
board = work_queue.pop(0)
for next_board in next_move(board):
if next_board not in needed_moves:
needed_moves[next_board] = needed_moves[board] + 1
work_queue.append(next_board)
This is a standard pattern for a breadth first search. Just supply a next_move function and some glue for the tests cases and you're good.
For a depth first search, just switch the queue for a stack. Which really means do work_stack.pop() to pop the last element rather than work_queue.pop(0) to get the first one.

Select optimal pairings of elements

I have following problem e.g:
Given a bucket with symbols
1 1 2 3 3 4
And book of recipes to create pairs e.g:
12 13 24
Select from bucket optimal pairing, leaving as little as possible symbols in the bucket. So using the examplary values above the optimal pairing would be:
13 13 24 Which would use all the symbols given.
Naive picking from the bucket could result in something like:
12 13 Leaving the 3 and 4 unmatched. 3 and 4 cannot be matched because the book does not contain a recipe for that particular connection
Notes:
Real problem consits on average of: 500 elements in bucket in about 30 kind of symbols.
We've tried to implement the solution using the bruteforce algorithm, however I am afraid that even our grandchildren will not live long enough to see the result :).
There is no limit to the size of recipe book, it could even have every possible in the bucket. Pair made of the same element twice is not allowed.
The answer is not required to empty the bucket completely. Its just about getting the most pairs out of the bucket. Its okay to leave some in the bucket. It would be best to look for the optimal solution, however close approximation is also good enough.
I will appreciate an answer that proposes/gives hint to an algorithm to solve the problem.
Examples:
Bucket:
1 1 2 2 2 2 3 3 3 4 5 6 7 8 8
Recipe book:
12 34 15 68
Optimal result (one of possible):
{1 2} {1 2} {3 4} {6 8}
Leftover:
2 2 3 3 5 7 8
This problem is essentially the maximum matching problem with the small twist that you're allowed to have duplicate objects. Here's one way to solve this problem assuming you have a solver for maximum matching:
Create a node for each number in the input list.
For each recipe, for each pair of numbers matching that recipe, add an edge between the nodes for those numbers.
Run a maximum matching algorithm and return the pairs reported that way.
There are a good number of off-the-shelf maximum matching algorithms you can use, and if you need to code one up yourself, consider Edmonds' Blossom Algorithm, which is reasonably efficient and less tricky to code up than other approaches.
First generate all possibles pairs of symbols and store them with the indices of each symbol , so if you have n symbols , then n*(n+1)/2 pairs are going to be generated (max case n=500 then 125250 pairs are going to be generated ).
Ex : bucket with symbols 1 1 3
Then pairs are going to be generated are (11,1,2)(13,1,3)(13,2,3).
General format ( a[i]a[j], i, j ).
Now lets loop over generated pairs and delete pairs that doesn't exist in the book of recipes, so now we have at most 30 pairs .
Next lets build a graph such that the nodes are our generated pairs, and each 2 nodes are connected if the indices of the 2 pairs are different (using 2 nested loops over our pairs ) .
Finally we can perform BFS or DFS and find the longest graph between all generated graphs , which has the answer to our problem.
If you want c++/Java implementation ,please don't hesitate to ask.

What is a good individual representation for a closed path planning task using genetic algorithm?

There is a n*n grid and in one of the cells of the grid lies an agent A.
A can travel T number of cells.
Each cell in the grid has some weight and the path for A has to maximize that weight.
A also has to return to its starting position within its traveling range T.
What can be a good individual representation to represent the paths?
Methods I have tried:
Chromosome is a list of coordinates.
Chromosome is a list of directions. Each gene is a direction like up, down, up-right, etc. Path never breaks in the middle.
Problems with both methods is that crossing-over almost always generates invalid paths. Paths become broken in the middle. They don't form a closed path. I can't seem to figure out a good way to represent the individual solution and an appropriate crossing-over method. Please help.
First of all, I would say that this problem is a better fit for other approaches, such as maybe ant colony optimization, greedy approaches that give good enough solutions etc. GAs might not work so well for the exact reason you describe.
However, if you must use GAs, here are two possible models that might be worth investigating:
Severely punish invalid paths by giving invalid moves a cost of -infinity. For example, if your chromosome says go from a cell x to an unreachable cell y, consider the cost of y -infinity. This might be worth combining with a low probability of crossover happening, something like 5% maybe.
Don't do crossover, just do some form of more involved mutation of the offspring.
If you want to get even fancier, this is somewhat similar to the travelling salesman problem, which has a lot of research in relation to genetic algorithms:
http://www.lalena.com/AI/Tsp/
http://www.math.hmc.edu/seniorthesis/archives/2001/kbryant/kbryant-2001-thesis.pdf
You could encode the path as a reference list:
Assume these are your locations (1 2 3 4 5 6 7 8 9)
A subset route of (1 2 3 4 8) could be encoded (1 1 2 1 4).
Now take two parents
p1 = (1 1 2 1 | 4 1 3 1 1)
p2 = (5 1 5 5 | 5 3 3 2 1)
which will produce
o1 = (1 1 2 1 5 3 3 2 1)
o2 = (5 1 5 5 4 1 3 1 1)
which will be decoded into these location routes
o1 = 1 – 2 – 4 – 3 – 9 – 7 – 8 – 6 – 5
o2 = 5 – 1 – 7 – 8 – 6 – 2 – 9 – 3 – 4
This way, a crossover will always yield valid results (whether this representation will help you solving your problem better is a different question).
Some additional information can be found here.

Finding the maximum sum from a matrix

There is a matrix with m rows and n columns. The task is to find the maximum sum choosing a single element from each row and column. I came up with a solution, which finds the maximum from the whole matrix and then sets that row and column as zero adds it to the sum and proceeds with finding the next max. This repeats m times.
But the problem with this approach was if there is repetitive elements. I'll try to explain it with an example. Here is the matrix..
3 6 5 3
9 4 9 2
8 1 4 3
4 7 2 5
Now, if I follow the above method.. sum will be 9 + 7 + 5 + 3 whereas it should be 9 + 8 + 7 + 3. How to solve this problem.. I'm stuck
Update: The columns are cost of seats which can be assigned to a person and the rows are number of persons. We want to assign them in such a way, so that we get the max cost.
Isn't this just http://en.wikipedia.org/wiki/Assignment_problem, typically solved by http://en.wikipedia.org/wiki/Hungarian_algorithm? Obviously, you want a maximum rather than a minimum, but surely you can achieve that by maximising for costs that are -(the real cost) or, if you are worried about -ve costs, (Max cost in matrix) - (real cost).
Your algorithm is wrong - consider a slight change in the matrix, where the second 9 is 8:
3 6 5 3
9 4 8 2
8 1 4 3
4 7 2 5
Then your algorithm has no problem in finding 9, 7, 5, 3 (no duplicates), but the correct answer is still 8, 8, 7, 3.
You can brute force it, by trying all combinations. One good way to put that into code is to use a recursive function, that solves the problem for any matrix:
In it you would iterate through say the first row and call the function for the submatrix obtained by deleting the correspondent row and column. Then you would pick the highest sum.
That, of course, will be too slow for large matrixes. The complexity is O(N!).

Resources