Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Graph travelling algorithm

I've got an interesting graph-theory problem. I am given a tree T with n nodes and a set of edges. T is, of course, undirected. Each edge has weight that indicates how many times (at least) it has to be visited. We are strolling from node to node using edges and the task is to find minimal number of needed steps to satisfy above conditions. I can start from any node.

For example, this tree (edge weight in parentheses):

1 - 2 (1)

2 - 3 (1)

3 - 4 (2)

4 - 5 (1)

4 - 6 (1)

we need 8 steps to walk this tree. That are for example: 1->2->3->4->3->4->5->4->6

I don't know how to approach this algorithm. Is it possible to find this optimal tour or can we find this minimal number not directly?

like image 729
ray Avatar asked Nov 25 '12 17:11

ray


People also ask

What are the methods used for Travelling a graph?

The graph has two types of traversal algorithms. These are called the Breadth First Search and Depth First Search.

What is graph traversing algorithm?

In computer science, graph traversal (also known as graph search) refers to the process of visiting (checking and/or updating) each vertex in a graph. Such traversals are classified by the order in which the vertices are visited. Tree traversal is a special case of graph traversal.

Which algorithm is used in graph?

Floyd Warshall algorithm is a great algorithm for finding shortest distance between all vertices in graph. It has a very concise algorithm and O(V^3) time complexity (where V is number of vertices). It can be used with negative weights, although negative weight cycles must not be present in the graph.

What is the best graph search algorithm?

Dijkstra's algorithm is efficient because it only works with a smaller subset of the possible paths through a graph (i.e., it doesn't have to read through all of your data). After each node is solved, the shortest path from the start node is known and all subsequent paths build upon that knowledge.


1 Answers

Add extra edges to your graph corresponding to the weight of each edge. (i.e. if a->b has weight 3, then your graph should include 3 undirected edges connections between a and b).

Then what you are trying to find is called an Eulerian trail on this graph.

A Eulerian trail can be closed (if start==end) or open (if start!=end).

Closed trails exist if all nodes have even degree.

Open trails exist if all nodes except 2 have even degree.

Paths can be found using Fleury’s Algorithm (faster linear algorithms also exist if this is too slow).

If your graph does not satisfy the requirements for an Eulerian trail, then simply add the smallest number of extra edges until it does.

One way of doing this is to perform a depth first search over the tree and keep track of the minimum number of edges that you can add to each subtree in order that it has 0,1, or 2 vertices of odd degree. This should take time linear in the number of nodes in the tree.

EXAMPLE CODE

This Python code computes the shortest number of steps for a graph. (To construct the graph you should consider it as a rooted graph and add edges for each edge going away from the root)

from collections import defaultdict
D=defaultdict(list)
D[1].append((2,1))
D[2].append((3,1))
D[3].append((4,2))
D[4].append((5,1))
D[4].append((6,1))
BIGNUM=100000

class Memoize:
    def __init__(self, fn):
        self.fn = fn
        self.memo = {}
    def __call__(self, *args):
        if not self.memo.has_key(args):
            self.memo[args] = self.fn(*args)
        return self.memo[args]

@Memoize
def min_odd(node,num_odd,odd,k):
    """Return minimum cost for num_odd (<=2) odd vertices in subtree centred at node, and using only children >=k

    odd is 1 if we have an odd number of edges into this node from already considered edges."""
    edges=D[node]
    if k==len(edges):
        # No more children to consider, and no choices to make
        if odd:
            return 0 if num_odd==1 else BIGNUM
        return 0 if num_odd==0 else BIGNUM

    # We decide whether to add another edge, and how many of the odd vertices to have coming from the subtree
    dest,w0 = edges[k]
    best = BIGNUM
    for extra in [0,1]:
        w = w0+extra
        for sub_odd in range(num_odd+1):
            best = min(best, w + min_odd(dest,sub_odd,w&1,0) + min_odd(node,num_odd-sub_odd,(odd+w)&1,k+1) )

    return best

root = 1
print min( min_odd(root,2,0,0),min_odd(root,0,0,0) )
like image 141
Peter de Rivaz Avatar answered Oct 06 '22 22:10

Peter de Rivaz