Even distributon of edges in bipartite graph - algorithm

I am given a bipartite and directed graph, initially without edges. One set of nodes is called subjects, the other set is called objects. Edges can only be constructed from a subject to an object.
The number of subjects (numSubj) and objects (numObj) are given, respectively.
Moreover the number of available edges (numEdges) is given.
The goal is to distribute edges from subjects to objects evenly. This means all subjects should have a similar number of outgoing edges, analogously all objects should have a similar number of ingoing edges. Each subject and object has to have at least one connected edge.
Please suggest a solution (e.g. in pseudo code)

First of all let's index all the items in each set of nodes form 1 to numSubj and from 1 to numObj. Let's also assume that numSubj < numObj (if this is not true than simply flip the sets, solve and flip them again).
Now calculate the total number of edges which is the lcm of these numbers, after than you can conclude the number of outgoing edges by dividing the result by numObj (A) and find ingoing by dividing by numSubj (B).
After this calculation for each subject create an edge to the calculated number of subject where the number of ingoing edges, A, is less then the second number calculated - B.
This process can be done like this:
i is connected to [i * B, i * B + 1, ... , i * (B + 1) - 1 ] mod numObj
With 2 and 5:
LCM = 10
Ingoing = 10 / 5 = 2
Outgoing = 10 / 2 = 5
1 -> 1, 2, 3, 4, 5
2 -> 1, 2, 3, 4, 5
With 4 and 8:
LCM = 8
Ingoing = 8 / 8 = 1
Outgoing = 8 / 4 = 2
1 -> 1, 2
2 -> 3, 4
3 -> 5, 6
4 -> 7, 8
With 4 and 6:
LCM = 12
Ingoing = 12 / 6 = 2
Outgoing = 12 / 4 = 3
1 -> 1, 2, 3
2 -> 4, 5, 6
3 -> 1, 2, 3
4 -> 4, 5, 6

Related

Dijkstra's Algorithm with Negative Weights Query

In this scenario, the aim is to find a path with the smallest total weight. There are 5 sections with each section having different nodes. The nodes are only connected to nodes in adjacent sections and a path must consist of only a single node from each section.
For example, let:
section 1 has nodes [1, 2, 3].
section 2 has nodes [4, 5].
section 3 has nodes [6].
section 4 has nodes [7, 8, 9, 10, 11].
section 5 has nodes [12, 13, 14].
A valid path through the sections is [1, 4, 6, 7 , 12] and also [1, 5, 6, 11, 14] etc...
All nodes have negative weights but negative cycles are impossible (due to the one node per section policy). Therefore, does the process of adding a constant to each node resolve the issue of negative weights? If it can fix the issue, are there any papers which show this? I know there are other algorithms to resolve negative weights but I'm interestted in Dijkstra's algorithm. Thanks.
No, you can't do this. Let's have a look at the counter example. Suppose we have a graph with A, B, C nodes and egdes:
A - B -2 (negative)
A - C 6
B - C 7
we are looking for the shortest path from A to C. In the original graph we have
A - B - C => -2 + 7 = 5 (the shortest path, 5 < 6)
A - C => 6
The best choice is A - B - C. Now, let's get rid of negative edges by adding 2. We'll have now
A - B 0
A - C 8
B - C 9
A - B - C => 0 + 9 = 9
A - C => 8 (the shortest path, 8 < 9)
Please note, that now the shortest path is A - C. Alas! While adding constant value to each edge we ruin the problem itself; and it doesn't matter now which algorithm we use.
Edit: Counter example with all edges (arc to prevent negative loops) being negative:
A -> B -6
B -> C -1
A -> C -5
Before adding 6 we have
A -> B -> C = -6 - 1 = -7 (the shortest path)
A -> C = -5
After adding 6 we get
A -> B 0
B -> C 5
A -> C 1
A -> B -> C = 0 + 5 = 5
A -> C = 1 (the shortest path)

Neighbors in the matrix - algorithm

I have a problem with coming up with an algorithm for the "graph" :(
Maybe one of you would be so kind and direct me somehow <3
The task is as follows:
We have a board of at least 3x3 (it doesn't have to be a square, it can be 4x5 for example). The user specifies a sequence of moves (as in Android lock pattern). The task is to check how many points he has given are adjacent to each other horizontally or vertically.
Here is an example:
Matrix:
1 2 3 4
5 6 7 8
9 10 11 12
The user entered the code: 10,6,7,3
The algorithm should return the number 3 because:
10 is a neighbor of 6
6 is a neighbor of 7
7 is a neighbor of 3
Eventually return 3
Second example:
Matrix:
1 2 3
4 5 6
7 8 9
The user entered the code: 7,8,6,3
The algorithm should return 2 because:
7 is a neighbor of 8
8 is not a neighbor of 6
6 is a neighbor of 3
Eventually return 2
Ofc number of operations equal length of array - 1
Sorry for "ile" and "tutaj", i'm polish
If all the codes are unique, use them as keys to a dictionary (with (row/col) pairs as values). Loop thru the 2nd item in user input to the end, check if math.Abs(cur.row-prev.row)+math.Abs(cur.col-prev.col)==1. This is not space efficient but deal with user input in linear complexity.
The idea is you have 4 conditions, one for each direction. Given any matrix of the shape n,m which is made of a sequence of integers AND given any element:
The element left or right will always be + or - 1 to the given element.
The element up or down will always be + or - m to the given element.
So, if abs(x-y) is 1 or m, then x and y are neighbors.
I demonstrate this in python.
def get_neighbors(seq,matrix):
#Conditions
check = lambda x,y,m: np.abs(x-y)==1 or np.abs(x-y)==m
#Pairs of sequences appended with m
params = zip(seq, seq[1:], [matrix.shape[1]]*(len(seq)-1))
neighbours = [check(*i) for i in params]
count = sum(neighbours)
return neighbours, count
seq = [7,8,6,3]
matrix = np.arange(1,10).reshape((3,3))
neighbours, count = get_neighbors(seq, matrix)
print('Matrix:')
print(matrix)
print('')
print('Sequence:', seq)
print('')
print('Count of neighbors:',count)
Matrix:
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
Sequence: [10, 6, 7, 3]
Count of neighbors: 3
Another example -
seq = [7,8,6,3]
matrix = np.arange(1,10).reshape((3,3))
neighbours, count = get_neighbors(seq, matrix)
Matrix:
[[1 2 3]
[4 5 6]
[7 8 9]]
Sequence: [7, 8, 6, 3]
Count of neighbors: 2
So your input is the width of a table, the height of a table, and a list of numbers.
W = 4, H = 3, list = [10,6,7,3]
There are two steps:
Convert the list of numbers into a list of row/column coordinates (1 to [1,1], 5 to [2,1], 12 to [3,4]).
In the new list of coordinates, find consequent pairs, which have one coordinate identical, and the other one has a difference of 1.
Both steps are quite simple ("for" loops). Do you have problems with 1 or 2?

Minimum Possible Sum of times in the given problem

onsider a graph of five vertices whose vertices are labelled 1 to 5. The only edges present in the graph are one each from 1 to 2, 1 to 3, 1 to 4 and 1 to 5. Let the time taken to travel from 1 to 2, 3, 4 and 5 be 5, 5, 1 and 1 units respectively. Also assume that if it takes time t to travel from vertex a to b, then it takes the same time to travel from b to a.We wish to select a walk from vertex 1 to some other vertex, back to vertex 1 and so on till each vertex (except vertex 1 - the source) is visited exactly once.
Let the initial instant be t = 0. Let the times of visit of vertices 2, 3, 4 and 5 from t = 0 be t2, t3, t4 and t5.We wish to minimise the sum of t2, t3, t4 and t5.
Find out the minimum possible sum of the given times.
i am unable to understand the question itself
This is my understanding of the question:
If you visit nodes 2, 3 ,4, and 5 in that order, the times will be:
t2 = 5 (going from 1 to 2),
t3 = 15 (5 to get to 2, 5 to return from 2 back to 1, and 5 to go from 1 to 3),
t4 = 21 (15 + 5 + 1),
t5 = 23 (21 + 1 + 1).
The sum is 64. You can get a better time with a different order, your task is to find the best (minimum) sum.
To minimise the total time of visiting, we select the path which takes minimum time first because this time piles up on all other vertices. After we come back to 1,we then select the path with second minimum time and we repeat this process each time after we come back to 1.
Let the times in sorted order be a,b,c and d for vertices v1,v2,v3 and v4. Then vertex v1 is visited at time t = a.We come back to 1 at t = 2a.We then reach the second vertex at t = 2a + b and come back to 1 at t = 2a + 2b. Continuing similarly, vertex v3 is visited at t = 2a + 2b + c and v4 is visited at t = 2a + 2b + 2c + d. So, the minimum value of the sum of times would be 7a + 5b + 3c + d.
So, the answer is 32.
so can we start the walk with vertex 5 =1+1=2
vertex 4 = 1+1=2
vertex 3=5+5=10
vertex 2= 5
total=2+2+10+5=19
Note that your total never changes, no matter the order in which you visit the nodes, so you cannot minimize it. You may want to clarify this with the teacher, but the problem definition states "time instance," not duration.
Think of it as starting a timer at time t-1 Then, for your path above (t-1 = 0): t-5(vertex-5) = 1, t-4 = 3, t-2 = 9, t-3 = 19. The sum is 32. Much better than 64, so you are on the right track!
Dijkstra's is used to find the shortest path between nodes, and it doesn't apply here. This problem is much easier.

Generate a Random Flow Network

I am trying to create a flow network for a given graph so that it can be used to test an algorithm. To provide clarity, I want the flow into each vertex to equal the flow out. All flow comes from the source and goes to the sink. Each edge has a maximum capacity and a direction. I would like to generate a flow through this network that equals the maximum flow (found by the min cut) that never exceeds the capacity for each edge.
Below is a graphical example of what I am given and what I am trying to obtain. Of course the "Desired Flow Graph" is not a unique example. I want this generated randomly.
Given Weighted Graph
Desired Flow Graph
I have this graph represented in MatLab with three arrays. The first array s gives the "from" vertex, the second array t gives the "to" vertex, and the third array w1 gives the maximum capacity from s to t. I would like to generate a random array such as w2 that represents the flow. (Note the letters in the pictures are equivalent to their corresponding numbers in the code where "A" = 1.
s = [1 1 1 2 3 3 4 6 5 6];
t = [2 3 4 5 5 6 6 5 7 7];
w1 = [10 15 10 8 5 7 6 5 18 15];
w2 = [8 12 6 8 5 7 6 0 13 13];
Any help with some sort of algorithm that can perform this task would be greatly appreciated. I would love a link to an algorithm, pseudocode, direct code, or even just a description of how such an algorithm may be implemented. Thanks in advance for the help.
Check out the maxflow function in MATLAB:
http://www.mathworks.com/help/matlab/ref/graph.maxflow.html
For the graph you posted, you can construct a directed graph with these commands:
s = [1 1 1 2 3 3 4 6 5 6];
t = [2 3 4 5 5 6 6 5 7 7];
w1 = [10 15 10 8 5 7 6 5 18 15];
g = digraph(s,t,w1);
Then you can use maxflow to calculate the flow values between node 1 and node 7 and return them in a new directed graph gf:
[mf,gf] = maxflow(g,1,7);
The w2 vector you refer to now just includes the edge weights of the gf graph, so you can extract it like this:
w2 = gf.Edges.Weight

Project Euler - 68

I have already read What is an "external node" of a "magic" 3-gon ring? and I have solved problems up until 90 but this n-gon thing totally baffles me as I don't understand the question at all.
So I take this ring and I understand that the external circles are 4, 5, 6 as they are outside the inner circle. Now he says there are eight solutions. And the eight solutions are without much explanation listed below. Let me take
9 4,2,3; 5,3,1; 6,1,2
9 4,3,2; 6,2,1; 5,1,3
So how do we arrive at the 2 solutions? I understand 4, 3, 2, is in straight line and 6,2,1 is in straight line and 5, 1, 3 are in a straight line and they are in clockwise so the second solution makes sense.
Questions
Why does the first solution 4,2,3; 5,3,1; 6,1,2 go anti clock wise? Should it not be 423 612 and then 531?
How do we arrive at 8 solutions. Is it just randomly picking three numbers? What exactly does it mean to solve a "N-gon"?
The first doesn't go anti-clockwise. It's what you get from the configuration
4
\
2
/ \
1---3---5
/
6
when you go clockwise, starting with the smallest number in the outer ring.
How do we arrive at 8 solutions. Is it just randomly picking three numbers? What exactly does it mean to solve a "N-gon"?
For an N-gon, you have an inner N-gon, and for each side of the N-gon one spike, like
X
|
X---X---X
| |
X---X---X
|
X
so that the spike together with the side of the inner N-gon connects a group of three places. A "solution" of the N-gon is a configuration where you placed the numbers from 1 to 2*N so that each of the N groups sums to the same value.
The places at the end of the spikes appear in only one group each, the places on the vertices of the inner N-gon in two. So the sum of the sums of all groups is
N
∑ k + ∑{ numbers on vertices }
k=1
The sum of the numbers on the vertices of the inner N-gon is at least 1 + 2 + ... + N = N*(N+1)/2 and at most (N+1) + (N+2) + ... + 2*N = N² + N*(N+1)/2 = N*(3*N+1)/2.
Hence the sum of the sums of all groups is between
N*(2*N+1) + N*(N+1)/2 = N*(5*N+3)/2
and
N*(2*N+1) + N*(3*N+1)/2 = N*(7*N+3)/2
inclusive, and the sum per group must be between
(5*N+3)/2
and
(7*N+3)/2
again inclusive.
For the triangle - N = 3 - the bounds are (5*3+3)/2 = 9 and (7*3+3)/2 = 12. For a square - N = 4 - the bounds are (5*4+3)/2 = 11.5 and (7*4+3)/2 = 15.5 - since the sum must be an integer, the possible sums are 12, 13, 14, 15.
Going back to the triangle, if the sum of each group is 9, the sum of the sums is 27, and the sum of the numbers on the vertices must be 27 - (1+2+3+4+5+6) = 27 - 21 = 6 = 1+2+3, so the numbers on the vertices are 1, 2 and 3.
For the sum to be 9, the value at the end of the spike for the side connecting 1 and 2 must be 6, for the side connecting 1 and 3, the spike value must be 5, and 4 for the side connecting 2 and 3.
If you start with the smallest value on the spikes - 4 - you know you have to place 2 and 3 on the vertices of the side that spike protrudes from. There are two ways to arrange the two numbers there, leading to the two solutions for sum 9.
If the sum of each group is 10, the sum of the sums is 30, and the sum of the numbers on the vertices must be 9. To represent 9 as the sum of three distinct numbers from 1 to 6, you have the possibilities
1 + 2 + 6
1 + 3 + 5
2 + 3 + 4
For the first group, you have one side connecting 1 and 2, so you'd need a 7 on the end of the spike to make 10 - no solution.
For the third group, the minimal sum of two of the numbers is 5, but 5+6 = 11 > 10, so there's no place for the 6 - no solution.
For the second group, the sums of the sides are
1 + 3 = 4 -- 6 on the spike
1 + 5 = 6 -- 4 on the spike
3 + 5 = 8 -- 2 on the spike
and you have two ways to arrange 3 and 5, so that the group is either 2-3-5 or 2-5-3, the rest follows again.
The solutions for the sums 11 and 12 can be obtained similarly, or by replacing k with 7-k in the solutions for the sums 9 resp. 10.
To solve the problem, you must now find out
what it means to obtain a 16-digit string or a 17-digit string
which sum for the groups gives rise to the largest value when the numbers are concatenated in the prescribed way.
(And use pencil and paper for the fastest solution.)

Resources