Algorithm - Finding the most rewarding path in a given graph - algorithm

Question: You are given the following inputs:
3
0 0 1
3 1 1
6 0 9
The first line is the number of points on the graph.
The rest of the lines contain the points on the graph, and their reward. For example:
0 0 1 would mean at point (0,0) [which is the starting point] you are given a reward of 1.
3 1 1 would mean at point (3,1) you are given a reward of 1.
6 0 9 would mean at point (6, 0) you are given a reward of 9.
Going from point a, to point b costs 1.
Therefore if you go from (0,0) -> (3,1) -> (6,0) your reward is 11-2 (cost of traversing 2 nodes) * sqrt(10).
Goal: Determine the maximum amount of rewards you can make (the total amount of reward you collect - the cost) based on the provided inputs.
How would I go about solving this? It seems like dynamic programming is the way to go, but I am not sure where to start.

Related

Calculate the lowest cost of running several resource collectors on an undirected acyclic graph

We have an undirected acyclic graph where there is only a single path between two connected nodes that may look something like this.
Simple guide to the image:
Black numbers: Node id's (note that each node contains a resource collector)
Resource collectors: Every resource collector collects resources on edges that are right next to it (so a collector on node 0 cannot reach resource deposits past node 1 and so on). A resource collector also requires fuel to operate - the amount of fuel a resource collector needs is directly connected to its range - the range determines the furthest resource node it can reach on the allowed edges (the range of the collectors is the blue circle on some nodes in the image). The fuel consumption of a collector is then calculated like this: fuel = radius of the circle (meaning that in the example case node 0 consumes 1 fuel and node 1 and 3 consume 2 fuel each, and since all the resource deposits have been covered our final fuel requirement is 5 (nodes 2, 5 and 4 do not use any fuel, since their radii are 0)).
Black lines: Graph edges
Red dots: Resource deposits, we only receive the number of deposits on a specific edge and all the deposits are evenly spaced apart on their respective edge.
Our task is to find the best configuration for our resource collectors (that is, find the configuration that consumes the lowest amount of fuel, and reaches all resource nodes) By this is meant: set the collector radius.
Things I've tried to solve this problem:
At first I've tried locating the "central" node of the graph and then traversing it with BFS while checking one node ahead and determining the amount of fuel from there, this did work for some graphs, but it became unstable in more complex ones.
After that I've tried basically the same thing, but I chose the leaf nodes as the starting points, this produced similar, imperfect, results.
This is an allocation problem.
Set "cost" of each pair of collector and deposit it can reach to be the distance from collector to deposit. Other pairs, where the deposit is unreachable, have infinite cost and can be omitted from the input.
Set collector/deposit pair with ( next ) lowest cost. Allocate deposit to collector. Repeat until all deposits allocated.
Set radius of each collector to be the distance from the collector to the furthest deposit assigned to it.
Here is the cost of each pair in your example. 031 means the first deposit on the edge from 0 to 3
Note that you renumbered the nodes in your example!!! The numbers in the table refer to the original diagram which looked like this
collector
deposit
cost
0
031
1
0
032
2
0
033
3
3
031
3
3
032
2
3
033
1
3
351
1
3
361
1
3
362
2
3
371
1
3
372
2
5
351
1
5
581
1
5
582
2
6
361
2
6
362
1
7
371
2
7
372
1
8
581
2
8
582
1
Note that this algorithm will assign deposit 231 to collector 2. This is different from your answer, but has the same total fuel cost. However 142 will go to 4 and 152 will go to 5, which increases the total fuel cost.
To handle this situation, collectors with more than 2 connections to other nodes need to be looked at, to see if the fuel cost can be further reduced by increasing their radius, "robbing" deposits from their neighbors.
This is not an allocation problem. There is a greedy optimal solution in O(n).
Here is the essence of the solution:
Let R(V,W) be the # of resource collectors on an edge between V & W. Note: R(V,W) == R(W,V) given the graph is undirected.
Set weight(V) = 0 for all vertices in the graph
1. A connected undirected acyclic graph is a forest.
2. Either the graph has 1 node (terminal case), or there is at least 1 vertex with degree 1. If the graph has 1 node, the algorithm is finished.
3. Select any vertex with degree 1. Let V be the vertex. Let W represent the other vertex connected to V.
4. weight(V) + weight(W) >= # of resource collectors on the edge(V,W)
5. Since V has degree 1, it is strictly better to use fuel from node W.
6. Set weight(W) = max(weight(W), R(V,W) - weight(V)).
7. Remove V and E(V,W) from the graph. The resulting graph is still a connected undirected acyclic graph. Repeat until the graph is a single vertex.
Test case #1:
A - B - C - D - E. All edges have 1 resource collector
Select A. weight(B) = 1, since R(A,B) - weight(A) = 1.
Select B. weight(C) = 0, since R(B,C) - weight(B) = 0.
Select C. weight(D) = 1, since R(C,D) - weight(C) = 1.
Select D. weight(E) = 0, since R(D,E) - weight(D) = 0.
Test case #2:
A - B - C - D - E. R(A,B) = R(D,E) = 1. R(B,C) = R(C,D) = 2.
Select A. weight(B) = 1, since R(A,B) - weight(A) = 1.
Select E. weight(D) = 1, since R(D,E) - weight(E) = 1.
Select B. weight(C) = 1, since R(B,C) - weight(B) = 1.
Select C. weight(D) = 1, since max(weight(D), R(C,D) - weight(C)) = 1.

Admissible Heuristic Modification

I am currently working on a project involving a puzzle and various pathfinding algorithms. The puzzle is represented using a 2d array, and has a specific form factor. Each cell in the 2d array has a jump value, and that is the number of spaces you can move up, down, left, or right from the cell.
I am currently working on implementing A* search on this puzzle. I was thinking of using manhattan distance as an admissible heuristic for this problem, but I do not think that the conventional manhattan distance will work since movement is limited to a specific number of moves.
For example:
2 2 2 1 1
1 1 1 2 2
3 1 2 1 1
3 1 2 1 1
2 1 1 1 0
Is a possible grid. You start from the 2 in the top left cell and are trying to get to the 0 in the bottom right cell. From the start cell, you can move right two or down 2 to new spaces which have different jump values. This process repeats until the goal is reached if the puzzle is solvable.
How can I modify the manhattan distance abs(x1-x2) + abs(y1-y2) to incorporate moving a specific number of spaces?
As you have observed Manhattan distance isn't an admissible heuristic, e.g. starting from P = (3,2) you have:
Manhattan(P, Target) = abs(3 - 4) + abs(2 - 4) = 1 + 2 = 3
but the real distance is just 2.
An admissible heuristic is:
h(P) = (P_x != Target_x) + (P_y != Target_y)
where
| 1 if x == y
(x != y) = |
| 0 otherwise
This works since for every component of the current-position-vector that doesn't match the corresponding component in target vector you have to take at least 1 move.

Maximum path cost in matrix

Can anyone tell the algorithm for finding the maximum path cost in a NxM matrix starting from top left corner and ending with bottom right corner with left ,right , down movement is allowed in a matrix and contains negative cost. A cell can be visited any number of times and after visiting a cell its cost is replaced with 0
Constraints
1 <= nxm <= 4x10^6
INPUT
4 5
1 2 3 -1 -2
-5 -8 -1 2 -150
1 2 3 -250 100
1 1 1 1 20
OUTPUT
37
Explanation is given in the image
Explanation of Output
Since you have also negative costs then use bellman-ford. What you do is that you change sign of all the costs(convert negative signs to positive and positive to negative) then find the shortest path and this path will be the longest because you have changed the signs.
If the sign is never becoms negative then use dijkstra shrtest-path but before that make all values negative and this will return you the longest path with it's cost.
You matrix is a direct graph. In your image you are trying to find a path(max or min) from index (0,0) to (n-1,n-1).
You need these things to represent it as a graph.
You need a linkedlist and in each node you have a first_Node, second_Node,Cost to move from first node to second.
An array of linkedlist. In each array index you save a linkedlist.If for example there is a path from 0 to 5 and 0 to 1(it's an undirected graph) then your graph will look like this.
If you want a direct-graph then simply add in adj[0] = 5 and do not add in adj[5] = 0 , this means that there is path from 0 to 5 but not from 5 to zero.
Here linkedlist represents only nodes which are connected not there cost. You have to add extra variable there which keep cost for each two nodes and it will look like this.
Now instead of first linkedlist put this linkedlist in your array and you have a graph now to run shortest or longest path algorithm.
If you want an intellgent algorithm then you can use A* with heuristic, i guess manhattan will be best.
If cost of your edges is not negative then use Dijkstra.
If cost is negative then use bellman-ford algorithm.
You can always find the longest path by converting the minus sign to plus and plus to minus and then run shortest path algorithm. Path founded will be longest.
I answered this question and as you said in comments to look at point two. If that's a task then main idea of this assignment is ensure the Monotonocity.
h stands for heuristic cost.
A stands for accumulated cost.
Which says that each node the h(A) =< h(A) + A(A,B). Means if you want to move from A to B then cost should not be decreasing(can you do something with your values such that this property will hold) but increasing and once you satisfy this condition then everyone node which A* chooses , that node will be part of your path from source to Goal because this is the path with shortest/longest value.
pathMax You can enforece monotonicity. If there is path from A to B such that f(S...AB) < f(S ..B) then set cost of the f(S...AB) = Max(f(S...AB) , f(S...A)) where S means source.
Since moving up is not allowed, paths always look like a set of horizontal intervals that share at least 1 position (for the down move). Answers can be characterized as, say
struct Answer {
int layer[N][2]; // layer[i][0] and [i][1] represent interval start&end
// with 0 <= layer[i][0] <= layer[i][1] < M
// layer[0][0] = 0, layer[N][1] = M-1
// and non-empty intersection of layers i and i+1
};
An alternative encoding is to note only layer widths and offsets to each other; but you would still have to make sure that the last layer includes the exit cell.
Assuming that you have a maxLayer routine that finds the highest-scoring interval in each layer (const O(M) per layer), and that all such such layers overlap, this would yield an O(N+M) optimal answer. However, it may be necessary to expand intervals to ensure that overlap occurs; and there may be multiple highest-scoring intervals in a given layer. At this point I would model the problem as a directed graph:
each layer has one node per score-maximizing horizontal continuous interval.
nodes from one layer are connected to nodes in the next layer according to the cost of expanding both intervals to achieve at least 1 overlap. If they already overlap, the cost is 0. Edge costs will always be zero or negative (otherwise, either source or target intervals could have scored higher by growing bigger). Add the (expanded) source-node interval value to the connection cost to get an "edge weight".
You can then run Dijkstra on this graph (negate edge weights so that the "longest path" is returned) to find the optimal path. Even better, since all paths pass once and only once through each layer, you only need to keep track of the best route to each node, and only need to build nodes and edges for the layer you are working on.
Implementation details ahead
to calculate maxLayer in O(M), use Kadane's Algorithm, modified to return all maximal intervals instead of only the first. Where the linked algorithm discards an interval and starts anew, you would instead keep a copy of that contender to use later.
given the sample input, the maximal intervals would look like this:
[0]
1 2 3 -1 -2 [1 2 3]
-5 -8 -1 2 -150 => [2]
1 2 3 -250 100 [1 2 3] [100]
1 1 1 1 20 [1 1 1 1 20]
[0]
given those intervals, they would yield the following graph:
(0)
| =>0
(+6)
\ -1=>5
\
(+2)
=>7/ \ -150=>-143
/ \
(+7) (+100)
=>12 \ / =>-43
\ /
(+24)
| =>37
(0)
when two edges incide on a single node (row 1 1 1 1 20), carry forward only the highest incoming value.
For each element in a row, find the maximum cost that can be obtained if we move horizontally across the row, given that we go through that element.
Eg. For the row
1 2 3 -1 -2
The maximum cost for each element obtained if we move horizontally given that we pass through that element will be
6 6 6 5 3
Explanation:
for element 3: we can move backwards horizontally touching 1 and 2. we will not move horizontally forward as the values -1 and -2, reduces the cost value.
So the maximum cost for 3 = 1 + 2 + 3 = 6
The maximum cost matrix for each of elements in a row if we move horizontally, for the input you have given in the description will be
6 6 6 5 3
-5 -7 1 2 -148
6 6 6 -144 100
24 24 24 24 24
Since we can move vertically from one row to the below row, update the maximum cost for each element as follows:
cost[i][j] = cost[i][j] + cost[i-1][j]
So the final cost matrix will be :
6 6 6 5 3
1 -1 7 7 -145
7 5 13 -137 -45
31 29 37 -113 -21
Maximum value in the last row of the above matrix will be give you the required output i.e 37

Construct a graph from given node degrees

I have to find which of the following values can be the degrees of an undirected graph with 6 vertices:
a) 3 2 2 2 3 3
b) 4 2 2 2 3 2
c) 5 2 2 2 0 3
d) 5 2 2 2 1 2
I only method I found is to try to draw the graph on a sheet of paper and then check if it is possible.
I just need a hint to start this problem, if possible, in other way than drawing each graph.
The following algorithm decides if a simple graph can be constructed with given node degrees:
sort the degrees in descending order
if the first degree is 0 (i.e.all degrees are 0) then obviously such a graph can be formed (no edges) and you are done.
if the first degree has value d (> 0) then the following d degrees must be greater 0. If not you are done: no such graph can be formed.
take away the first degree (value d) and reduce the following d degrees by one (i.e. draw the requested number of edges from the node with highest degree to the nodes with highest degrees among the remaining ones - see proof below for correctness of this assumption), then continue with step 1 (with now one node less)
example a) (can be rejected because of the odd sum of weights, but also the above algorithms works)
3 2 2 2 3 3
3 3 3 2 2 2
2 2 1 2 2
2 2 2 2 1
1 1 2 1
2 1 1 1
0 0 1
1 0 0
-1 not possible
example c)
5 2 2 2 0 3
5 3 2 2 2 0
2 1 1 1 -1 not possible
example d)
5 2 2 2 1 2
5 2 2 2 2 1
1 1 1 1 0
0 1 1 0
1 1 0 0
0 0 0 ok
What is missing is a proof that if a graph can be drawn with given node degrees, then one of the matching graphs has this property of step 4, i.e. that the node with highest degree is connected with the nodes with next highest degrees.
Let us therefore assume that A is the node with highest degree and that it is connected with a node B whose degree is less then the degree of node C not being connected to A. Since degree(C) > degree(B), there is node D connected to C and not connected to B. Thus, there are edges AB and CD, and there are no edges AC nor BD. So we can replace AB and CD by the edges AC and BD without changing the nodes' degrees.
By repeating this procedure enough times we can make all nodes with the next highest degrees being connected to node with the highest degree.
The handshaking lemma or degree sum formula is necessary and sufficient condition in this case, since we only care that it forms an undirected graph (orientation of the edge doesn't matter, but nothing is said about loop or parallel edges). Therefore, option c and option d are valid 6-vertex undirected graph.
If the question asks for simple undirected graph (loop and parallel edges disallowed), then we need to bring in the algorithm by Havel/Hakimi, which is as described by #coproc.

ACM MIPT - Graph existence puzzle - examples unclear

This is with reference to the 'graph existence' problem - http://acm.mipt.ru/judge/problems.pl?problem=110. Can someone explain why there is no tree in example 1 but there is a tree in example 2? In both examples, vertices 0, 1, 2 and 3 are connected to each other. Here is the problem statement and examples for your reference:
You are given a matrix of distances in a graph.
You should check whether this graph could be a tree or set of trees (forest).
Edge length is 0 or positive integer.
Input: The first line contains number of vertices N.
Next N lines contains matrix (only left bottom triangle of matrix).
Distance -1 corresponds to infinite distance.
Output: Output YES or NO. If YES, then next lines should contains list of edges
of the tree (any tree (forest) with given distance matrix).
Each edge is coded by two identifiers of it's ends.
Vertex identifiers are numbers 0, 1, ..., N-1.
Input#1
4
0
1 0
1 1 0
1 1 1 0
Output#1
NO
Input#2
5
0
1 0
2 1 0
3 2 1 0
-1 -1 -1 -1 0
Output#2
YES
0 1
1 2
2 3
The problem is not very well translated from its Russian original.
The given matrix is not the matrix of edges in the graph as one might conclude, but a distance matrix. Each edge probably has weight of 1, but I am not entirely sure has a nonnegative weight. One has to check if the matrix can be realized by a tree or a forest.
That is in the first example all vertices are connected, but the second example can be realized the graph looks like:
Example 2:
(0) - (1) - (2) - (3) (4)
The graph in example 1 is
Example 1:
(0) - (1) - (2) - (3)
|_____|_____| |
| |___________|
|_________________|

Resources