简体   繁体   中英

Traversing an undirected, unweighted graph with a twist: minimum visits to each node

I'm trying to write code that will traverse an undirected, unweighted graph. Essentially, the method will be passed a node (which knows all its neighbors). The method then has to build a model of the graph as efficiently* by going from node to node and collecting information which nodes link to each other. At the end, the method will have a complete list of all the nodes and all the vertices that connect them.

*The crux of the problem lies in the word efficiently and what I mean by it. Let me direct your attention to this small graph:

图形

Let's say I start at node G. I can either visit C, B, F, D, H, J or E. I want to minimize the amount of times I visit a node and in order to visit a node, I must pass through all nodes on the way to that node.

Example: let's say I decide to visit node C. The next node to visit could be either A, B, F, D, H, J or E. However, to visit any node except for A, I would have to pass through G again which is considered inefficient. And in order to visit A, I would have to visit G and C again and then pass through C and then G to get back to the rest of the graph. So I decide to visit A. This means I have to pass through C again to reach G. Thus, from a logical point of view, it makes sense to visit the C branch last.

However, the program, when it starts at Node G, is unaware that branch C leads to a dead-end. As I write this, I think it might be impossible, but I ask it anyways: is there anyway to traverse this graph as efficiently as possible (as I have previously defined it) using only the information given (ie that the program only knows about the nodes its visited and the edges emanating from those nodes? Or should I just go with a variation Dijkstra's algorithm in order to insure I visit every node?

This will all be written in Java if that matters.

Do you want simply to traverse the whole graph (regardless of the path taken), and do some operation on each node, or do you want to compute the shortest path from one node to any other node? (I might not understand your goal.)

In the first case, stick to a traversal algorithm such as Breadth First Search . For the other, you may want to consider Dijkstra by using same-weighted edges (ie = 1).

You can see the BFS as a special case of Dijkstra when you are interested only in one starting node and all edges have the same weight. With different costs you could use Uniform Cost Search.

Wouldn't just a simple recursion with a collect-argument do?

public void traverse(Node n, Set<Node> visisted) {

  visited.add(n);

  for (Node neighbour : n.getNeighbours()) {

    if (!visited.contains(neighbour)) {
      traverse(neighbour, visited);
    }

  }

}

An interesting problem... but still not clear what the original problem/goal is from the responses to-date.

Is this a valid re-statement of the problem?:

  • The start node is specified
  • The cost to visit each node is "1"
  • Objective: visit each node
  • Objective: plan a route that minimizes cost
  • Constraint: the final node is not specified (it may be any node)
  • The algorithm has full knowledge of the graph before any costs are incurred (searching every possible path does not -- itself -- incur any cost)

If that is a correct "read" of your problem, then consider these observations:

  • If the cost to "visit a node" is "1", that is the same as "the cost to traverse any edge" is "1"... since the there is a one-to-one correspondence between "visiting a node" and "traversing an edge". (You can't enter a node except by traversing its in-edge.)
  • If two nodes are not directly connected, they are still "transitively connected", as you can simply traverse the intervening nodes. (Alternately: you appear to NOT have the constraint "you may not re-visit a node".)

Thus: all nodes are "connected" via some "distance", and you want to visit all nodes, while minimizing the "distance" traveled.

Is that correct?

If so, I submit that your problem is almost exactly the classical "Traveling Salesman Problem". The only difference I see is that sometimes the statement of the TSP requires "start-node and end-node to be the same". But -- I think -- you allow the start-node and end-node to be different.

If that sounds right -- and you are really just trying to "solve" the TSP in an efficient manner -- then join the multitudes ahead of you who have tried to do the same thing! There might not be a better solution than simply "try all combinations, score each, and take the minimum".

this is to traverse all nodes of graph and calculates the minimum cost of traversing hope it will help U

package capgemni;
/**
*
* @author amit
*/
public class Graphtraversing {
public static void main(String[] args) {
    int res = 0;
    String[] input1= {"A", "B", "C", "D"};
    int[] input2 = {4, 8, 6, 3, 3, 5};

    res = minimum_cost(input1, input2);
    System.out.println(res);

}
static int minimum_cost(String[] input1,int[] input2)
{
    int d = input1.length;
    int costmatrix[][]=new int[input1.length][input1.length];
    int i=0,j=0,k=0;


    for(i=0;i<input1.length;i++){
    for(j=i;j<input1.length;j++){
        costmatrix[i][j]=0;
    }
    }

    for(i=0;i<input1.length;i++){
    for(j=i;j<input1.length;j++){
        if(i==j){
        costmatrix[i][j] = 0;
        }
else{
        costmatrix[i][j] = input2[k];
        k++;
}

    }
    }

for(i=0;i<input1.length;i++){
for(j=0;j<input1.length;j++){
    costmatrix[j][i] = costmatrix[i][j];
}
}

int cost = 0;
int mcost = 0;
int first = 1;
for(i=0; i<input1.length; i++){

for(j=0; j<input1.length; j++){

    cost = cost + costmatrix[i][j];

}
if(first == 1 ){
mcost = cost;
first = 0;
}
else if(cost < mcost){
mcost = cost;
}
cost = 0;
}


    return mcost;
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM