-1

We have an undirected acyclic graph where there is only a single path between two connected nodes that may look something like this.

Enter image description here

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • @ravenspoint They're just the node id. – John Smith Nov 13 '22 at 16:15
  • @ravenspoint I've updated the post so that it hopefully portrays the task better. – John Smith Nov 13 '22 at 16:21
  • My bad, I've misused the term 'node' here, the nodes are the black numbers - just an average graph node. The red points are the resource deposits (I used nodes incorrectly here) - you can pretty much ignore their position on the edge since we just need to know how many of them are on the specific edge. – John Smith Nov 13 '22 at 16:29
  • See my answer to https://stackoverflow.com/a/74436277/16582 – ravenspoint Nov 15 '22 at 16:16

2 Answers2

0

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

enter image description here

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.

ravenspoint
  • 19,093
  • 6
  • 57
  • 103
  • I've rewritten the question, just like you asked. Hopefully it clarifies things a bit. – John Smith Nov 13 '22 at 17:00
  • Sure. I have posted my answer. – ravenspoint Nov 13 '22 at 17:01
  • Thanks, but I'm not sure I explained it correctly, we do not know the radius of the extractors before hand - we only know the graph structure and how many deposits each edge contains. – John Smith Nov 14 '22 at 11:12
  • Also note that we have to collect all deposits – John Smith Nov 14 '22 at 11:13
  • You want to minimize fuel consumption. Fuel consumption depends on the radii. You do not know the the radii. It is thus impossible to minimize fuel consumption - insufficient data. – ravenspoint Nov 14 '22 at 15:12
  • No, we're supposed to figure out the radii and from that we can get the total fuel consumption. – John Smith Nov 14 '22 at 15:16
  • So, "figure out" the radii and apply the greedy algorithm for the allocation problem. – ravenspoint Nov 14 '22 at 15:18
  • Figuring out the radii **is the problem** , I've managed to implement a greedy algo that counts the deposits around every node, picks the node with with the most deposits, increases its range by 1 and 'lowers' the deposit count on the neighboring edges, then I repeat this until all edges contain no deposits. This obviously doesn't work for all cases. I've tried looking up allocation problems, but I find it quite difficult, since most of the results are memory related. A link would be very helpful – John Smith Nov 14 '22 at 15:28
  • "Figuring out the radii is the problem ," So you asked the wrong question.!!! Please edit your question. – ravenspoint Nov 14 '22 at 15:30
  • I have edited my answer to apply to the new question you have asked. – ravenspoint Nov 14 '22 at 15:34
  • Thanks for updating the answer, I think I know where you're going with this, but I think I might be missing something - you mention the first deposit on the edge from 0 to 3 (031) - is this correct? The individual collectors cannot go through other collectors- that is, collector on node 0 should only be able to access the following deposits: 011, 012, 013. – John Smith Nov 14 '22 at 16:10
  • The "cost" of assigning an unreachable deposit is infinite. You can model that by just omitting the pair from the input data. Look at the table in my answer. It only incudes pairs where the deposit is reachable from the collector. – ravenspoint Nov 14 '22 at 16:15
  • You renumbered the nodes!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! – ravenspoint Nov 14 '22 at 16:37
  • excuse me? I didn't even touch the image since I uploaded it (yesterday, when you asked me to change the graph image, and even then, the values were the same). – John Smith Nov 14 '22 at 16:41
  • Your original diagram had nodes numbered 0 3 5 6 7 8 – ravenspoint Nov 14 '22 at 16:43
  • I just checked, and, you're correct - I apologize for that, however, the image was updated yesterday. – John Smith Nov 14 '22 at 16:46
  • You are very difficult to work with! – ravenspoint Nov 14 '22 at 16:48
  • My friend, you yourself told me to refactor my question and rework the diagram, so I did. I don't know why you'd still be using the original image as a reference when you asked me to rework it. – John Smith Nov 14 '22 at 16:50
  • I did not tell you to renumber the nodes. I am working with an offline copy of your question. Not everyone lives in the cloud. – ravenspoint Nov 14 '22 at 16:54
  • I do understand that, however, you've asked me to rephrase my question - this implies that you've re-read the question after I updated it - this means that there is no way that you could've missed the image that covers 1/3 of the question area. I do realize that the way I've asked the question wasn't the best, and that I've made several errors along the way, but this is not one of them. – John Smith Nov 14 '22 at 16:58
0

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.
MarkB
  • 672
  • 2
  • 9
  • Is the weight equivalent to the collector radius? What happens with the OP's example, where the radius of node 1 is 2 for the optimal solution? – ravenspoint Nov 15 '22 at 16:22
  • Yes, weight is collector radius. In OP's example, the optimal solution has total radius = 5. There happens to be a optimal solution s.t. the radius of node 1 is 2. However, there is also an optimal solution s.t. the radius of node 1 is 3. I guarantee that the algorithm I described will produce 5 regardless of the ordering of the nodes selected in step 3. – MarkB Nov 15 '22 at 17:25
  • "4. weight(V) + weight(W) >= # of resource collectors on the edge(V,W)" I do not understand this line. What does it do? Won't the weights of V and W be zero since V has just been selected? So the >= will always be false? – ravenspoint Nov 15 '22 at 19:01
  • "Set weight(W) = max(weight(W), R(V,W) - weight(V))." Not sure, but I think this line could be simply replaced by "Set weight(W) = R(V,W)" for the same effect. Again, I am not sure, but it looks like your algorithm is a complicated way of describing PASS1 in the algorithm I presented at stackoverflow.com/a/74436277/16582 – ravenspoint Nov 15 '22 at 19:13
  • @ravenspoint, I added an example on the other question that demonstrates your algorithm producing a suboptimal result. Line 4 does nothing...it is simply a statement that must be true in order to solve the problem. – MarkB Nov 15 '22 at 19:37
  • I have run your example in my code. It produces the optimal result. – ravenspoint Nov 15 '22 at 20:21