最短路径问题-Graph Java实现

本文介绍了一种将Scala的Dijkstra算法翻译为Java的方法,用于解决图的最短路径问题。通过创建JavaSparkContext实例,构建Graph对象,并应用Dijkstra算法,从特定顶点出发找到图中其他顶点的最短路径。代码中包含图的顶点和边的创建,以及使用迭代方式更新最短距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目前只有 scala的Graph实现的dijkstra算法,用java 翻译了一下,可以自己看看

public class GraphShortPathsTest
{
private static final ClassTag<Integer> tagInteger = ClassManifestFactory.classType( Integer.class );
private static final ClassTag<String> tagString = ClassManifestFactory.classType( String.class );
private static final ClassTag<Object> tagObject = ClassManifestFactory.classType( Object.class );
private static final ClassTag<Double> tagDouble = ClassManifestFactory.classType( Double.class );
private static final ClassTag<Tuple2<Object,Double>> tagTuple2 = ClassManifestFactory.classType( Tuple2.class );
private static final ClassTag<Tuple2<Boolean,Double>> tagTuple2Boolean = ClassManifestFactory.classType( Tuple2.class );
public static void main( String[] args )
{
SparkConf conf = new SparkConf().setAppName( "Graph short path" ).setMaster( "local" );
JavaSparkContext ctx = new JavaSparkContext( conf );

JavaRDD<Tuple2<Object, String>> verts = ctx.parallelize( Arrays.asList(  
new Tuple2<Object, String>( 1L, "a" ),
new Tuple2<Object, String>( 2L, "b" ),
new Tuple2<Object, String>( 3L, "c" ),
new Tuple2<Object, String>( 4L, "d" ),
new Tuple2<Object, String>( 5L, "e" )) );

JavaRDD<Edge<Double>> edges = ctx.parallelize( Arrays.asList( 
new Edge<Double>( 1L, 2L, 10.0 ),
new Edge<Double>( 2L, 3L, 20.0 ),
new Edge<Double>( 2L, 4L, 30.0 ),
new Edge<Double>( 4L, 5L, 80.0 ),
new Edge<Double>( 1L, 4L, 30.0 )
) );

Graph<String, Double> g = Graph.apply( verts.rdd( ), edges.rdd( ), "aa",
StorageLevel.MEMORY_ONLY( ), StorageLevel.MEMORY_ONLY( ), tagString, tagDouble );

Graph<Tuple2<String,Double>, Double> g2 = dijkstra( g, 1L );
g2.vertices( ).foreach( new MyFuction1<Tuple2<Object,Tuple2<String,Double>>, BoxedUnit>( )
{


@Override
public BoxedUnit apply(
Tuple2<Object, Tuple2<String, Double>> t )
{
System.out.println( t );
return BoxedUnit.UNIT;
}

});

ctx.stop( );
}

private static <VD> Graph<Tuple2<VD,Double>,  Double> dijkstra(Graph<VD, Double> g, Object oriID)
{
Graph<Tuple2<Boolean,Double>, Double> g2 = g.mapVertices( new MyFuction2<Object, VD, Tuple2<Boolean,Double>>( )
{


@Override
public Tuple2<Boolean, Double> apply( Object id, VD vdValue )
{
double value = oriID.equals( id )?0.0:Double.MAX_VALUE;
return new Tuple2<Boolean, Double>(false, value);
}
}, tagTuple2Boolean, null );

long count = g2.vertices( ).count( );
while(count != 0)
{
count--;
final Object currentID = g2.vertices( ).filter( new MyFuction1<Tuple2<Object,Tuple2<Boolean,Double>>, Object>( )
{


@Override
public Object
apply( Tuple2<Object, Tuple2<Boolean, Double>> t )
{
return !t._2( )._1( );
}
}).fold( new Tuple2<Object,Tuple2<Boolean, Double>>(Double.valueOf( 0.0 ),  new Tuple2<Boolean, Double>(false, Double.MAX_VALUE )),
new MyFuction2<Tuple2<Object,Tuple2<Boolean,Double>>, Tuple2<Object,Tuple2<Boolean,Double>>, Tuple2<Object,Tuple2<Boolean,Double>>>( )
{


@Override
public Tuple2<Object, Tuple2<Boolean, Double>> apply(
Tuple2<Object, Tuple2<Boolean, Double>> t1,
Tuple2<Object, Tuple2<Boolean, Double>> t2 )
{

return t1._2( )._2( ) < t2._2( )._2( )? t1:t2;
}
})._1( );

VertexRDD<Double> newDistances = g2.aggregateMessages( new MyFuction1<EdgeContext<Tuple2<Boolean,Double>,Double,Double>, BoxedUnit>( )
{

@Override
public BoxedUnit apply(
EdgeContext<Tuple2<Boolean, Double>, Double, Double> t )
{
if (currentID.equals(t.srcId( )))
{
t.sendToDst( t.srcAttr( )._2( ) + t.attr( ) );
}
return BoxedUnit.UNIT;
}
}, new MyFuction2<Double, Double, Double>( )
{


@Override
public Double apply( Double a, Double b )
{
return Math.min( a, b );
}
}, TripletFields.All, tagDouble );

g2 = g2.outerJoinVertices(newDistances , new MyFuction3<Object, Tuple2<Boolean, Double>, Option<Double>, Tuple2<Boolean, Double>>( )
{


@Override
public Tuple2<Boolean, Double> apply( Object t1,
Tuple2<Boolean, Double> t2, Option<Double> t3 )
{
return new Tuple2<Boolean, Double>(t2._1( ) || t1.equals( currentID ), Math.min( t2._2( ), t3.getOrElse(  
new MyFuction0<Double, Double>( )
{


@Override
public Double apply( )
{
return Double.MAX_VALUE;
}
}) ));
}
}, tagDouble, tagTuple2Boolean, null );
}

Graph<Tuple2<VD,Double>, Double> retValue = g.outerJoinVertices( g2.vertices( ), new MyFuction3<Object, VD, Option<Tuple2<Boolean, Double>>,Tuple2<VD, Double>>( )
{



@Override
public Tuple2<VD, Double> apply( Object t1, VD t2,
Option<Tuple2<Boolean, Double>> t3 )
{
Tuple2<VD, Double> retValue = new Tuple2<VD, Double>( t2, t3.getOrElse( new MyFuction0<Tuple2<Boolean, Double>, Tuple2<Boolean, Double>>( )
{
@Override
public Tuple2<Boolean, Double> apply( )
{
return new Tuple2<Boolean, Double>(false, Double.MAX_VALUE);
}
} )._2);
return retValue;
}


}, tagTuple2Boolean, ClassManifestFactory.classType( Tuple2.class), null );
return retValue;
}

private static <T> JavaPairRDD<Object, T> toJavaPair( VertexRDD<T> v, ClassTag<T> tagT )
{
return new JavaPairRDD<Object, T>( (RDD<Tuple2<Object, T>>) v, tagObject, tagT );
}

private static  <T> JavaRDD<Tuple2<Object, T>> toJavaPair( VertexRDD<T> v )
{
return new JavaRDD<Tuple2<Object, T>>( (RDD<Tuple2<Object, T>>) v,ClassManifestFactory.classType( Tuple2.class ) );
}


public static abstract class MyFuction2<T1, T2, R> extends AbstractFunction2<T1, T2, R> implements Serializable
{


}

public static abstract class MyFuction3<T1, T2, T3,  R> extends AbstractFunction3<T1, T2, T3, R> implements Serializable
{


}

public static abstract class MyFuction0<T1, R> extends AbstractFunction0< R> implements Serializable
{


}

public static abstract class MyFuction1<T1, R> extends AbstractFunction1<T1, R> implements Serializable
{


}


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值