图中最短路径,边缘增加

时间:2017-12-10 17:32:06

标签: java graph graph-theory shortest-path dijkstra

我有定向图,我必须找到Q对节点(A,B)之间的最短路径。但路径必须超过最大值。 N边缘和这些边缘的长度必须增加(从A到B(1,3,5,9))。 输出是此路径的长度。 (如果它不存在,则输出-1)。

我试图将图形表示为3D arraylist,然后递归找到填充条件的最短路径,但我不知道出了什么问题。
这段代码不起作用,它是无限递归:

public static int path(int v, int c, int mv, int dc, int pv) {
    if (pv==mv) {
        if (Gi.get(v).contains(c)) {
            return G.get(v).get(c).get(0);
        }
        return -1;
    }
    bol[v]=true;
    for (int i=0; i<G.get(v).size(); i++) {
        for (int j=0; j<G.get(v).get(i).size(); j++) {
            if (!bol[Gi.get(v).get(i)]) {
                if (G.get(v).get(i).get(j)>dc) {
                    int ce=path(Gi.get(v).get(j),c,G.get(v).get(i).get(j),dc,pv+1);
                    if (ce!=-1) return ce;
                }
            }
            else {
                return -1;
            }
        }   
    }
    return vz;
}

有人可以帮助我吗?

谢谢,Ferko

1 个答案:

答案 0 :(得分:0)

您可以使用最小优先级队列和表示路径的单链表数据结构来执行此操作:

import java.util.LinkedList;
import java.util.PriorityQueue;

public class DijkstraTest
{
  public static PathSegment Dijkstra(
      final Vertex from,
      final Vertex to,
      final int maxSize
  )
  {
    if ( from == null )
      throw new IllegalArgumentException( "From vertex cannot be null" );
    if ( to == null )
      throw new IllegalArgumentException( "To vertex cannot be null" );
    if ( maxSize <= 0 )
      throw new IllegalArgumentException( "Maximum size must be at least 1" );
    final PriorityQueue<PathSegment> queue = new PriorityQueue<>();

    for ( final Edge e : from.outEdges )
      queue.add( new PathSegment( e, null ) );

    while ( !queue.isEmpty() )
    {
      final PathSegment p = queue.poll();
      final Edge e   = p.edge;
      final Vertex v = e.to;
      if ( v == to )
      {
        // Found a path to destination
        return p;
      }
      if ( p.size == maxSize )
      {
        // Not reached the destination but at max length so discard this path
        continue;
      }
      for ( final Edge o : v.outEdges )
      {
        if ( o.length > e.length ) // Increasing edges
        {
          queue.add( new PathSegment( o, p ) );
        }
      }
    }

    return null;
  }

  public static class Vertex{
    public final int index;
    public final LinkedList<Edge> outEdges = new LinkedList<>();
    public Vertex( final int i )
    {
      index = i;
    }
  }

  public static class Edge{
    public final Vertex from;
    public final Vertex to;
    public final int length;
    public Edge( final Vertex f, final Vertex t, final int l )
    {
      from = f;
      to = t;
      length = l;
      from.outEdges.add( this );
    }
  }

  public static class PathSegment implements Comparable<PathSegment>{
    public final Edge edge;
    public final PathSegment prev;
    public final int length;
    public final int size;
    public PathSegment( final Edge e, final PathSegment p )
    {
      edge = e;
      prev = p;
      size   = ( prev == null ? 0 : prev.size ) + 1;
      length = ( prev == null ? 0 : prev.length ) + edge.length;
    }

    @Override
    public int compareTo( final PathSegment p )
    {
      return Integer.compare( length, p.length );
    }

    @Override
    public String toString(){
      return ( prev == null ? Integer.toString( edge.from.index ) : prev.toString() )
             + ','
             + Integer.toString( edge.to.index );
    }
  }

  public static void main( final String[] args )
  {
    final Vertex[] vertices = {
      new Vertex(1), new Vertex(2), new Vertex(3), new Vertex(4), new Vertex(5), new Vertex(6)
    };

    final Edge[] edges = {
      new Edge(vertices[0],vertices[1],2),
      new Edge(vertices[0],vertices[2],7),
      new Edge(vertices[0],vertices[5],5),
      new Edge(vertices[1],vertices[0],11),
      new Edge(vertices[1],vertices[2],3),
      new Edge(vertices[2],vertices[3],8),
      new Edge(vertices[2],vertices[4],1),
      new Edge(vertices[3],vertices[1],10),
      new Edge(vertices[3],vertices[4],6),
      new Edge(vertices[5],vertices[3],4),
      new Edge(vertices[5],vertices[3],7)
    };

    PathSegment p;

    p = Dijkstra( vertices[0], vertices[3], 2 );
    System.out.println( p + " - length: " + (p==null?"null":p.length) );

    p = Dijkstra( vertices[2], vertices[0], 2 );
    System.out.println( p + " - length: " + (p==null?"null":p.length) );

    p = Dijkstra( vertices[2], vertices[0], 3 );
    System.out.println( p + " - length: " + (p==null?"null":p.length) );
  }
}

输出:

1,6,4 - length: 12
null - length: null
3,4,2,1 - length: 29