/**
* Dijkstra算法(单起点最短路径) <br/>
* 基于贪婪算法,每次各点到起点的距离中选出最小权重(该值u初始值为点到起点的距离, 如果点没有连接起点的边,则值为正无穷)的点n加入到树中
* ,新加入点应该有一个值记录到起点的距离d,在遍历剩下未加入树的点,如果当前点u值大于新加入点n到当前点的距离d1+d,
* 则当前点将更新为d1+d,如此重复,直至全部点加入树
*
* <br/>
* 每个节点必须有两个标记:(1)起点到顶点的最短路径 (2)顶点父母 <br/>
* <br/>
* 加入树中的节点u*后: <br/>
* (1)把u*从边缘集合中移动到树顶点集合 <br/>
* (2)对余下的每一个边缘节点u,如果通过权重w(u*,u)的边和u*相连,当du* + w(u*,u) < du时,把u的标记分别更新为du* +
* w(u*,u)
*
* @author chenxuegui
*
*/
public class Dijkstra
{
// 存储未加入树的节点同树中点的最小距离
private static Map<String, Distance> map;
// 存储加入的边
private static List<Distance> tree;
private static String origin = null;
public static void main(String[] args)
{
int[][] a = new int[5][5];
tree = new ArrayList<>();
map = new HashMap<>();
String cur = null;
init(args, a, 5);
cur = origin;
int preDis = 0;
map.remove(origin);
while (map.size() != 0)
{
traverse(cur, a, 5, preDis);
Distance minDis = find();
tree.add(minDis);
cur = minDis.getVertex();
preDis = minDis.getWeight();
}
System.out.println(tree);
}
/**
* 初始化
*/
private static void init(String args[], int[][] a, int n)
{
int i = 0;
for (; i < n * n; i++)
{
a[i / n][i % n] = Integer.valueOf(args[i]);
}
origin = args[i++];
n += i;
for (; i < n; i++)
{
map.put(args[i], new Distance(args[i], null, Integer.MAX_VALUE));
System.out.println(args[i]);
}
}
/**
* 从Map<String, Distance>中查找权值最小的关系对应的边 返回边
*
* @return
*/
public static Distance find()
{
String key = null;
int minWeight = Integer.MAX_VALUE;
for (Entry<String, Distance> entry : map.entrySet())
{
if (minWeight > entry.getValue().getWeight())
{
key = entry.getKey();
minWeight = entry.getValue().getWeight();
}
}
// 约束:把map.key(未加入树的点)放在vertex1
Distance d = map.get(key);
map.remove(key);
return d;
}
/**
* 从cur vertex中对各既在map中又在权值比map中小的点跟新到map中
*
* @param vertex
* 上一个加入map的节点
* @param a
* @param n
* @param preDis
* 上一个节点到起点的距离
*/
public static void traverse(String vertex, int[][] a, int n, int preDis)
{
Distance distance;
String s;
int index = vertex.charAt(0) - 97;
for (int i = 0; i < n; i++)
{
s = "" + (char) (i + 97);
if (i != index && map.get(s) != null)
{
distance = map.get(s);
if (distance.getWeight() > a[index][i] + preDis
&& a[index][i] != 0)
{
distance.setWeight(a[index][i] + preDis);
distance.setParentVertex(vertex);
}
}
}
}
}
/**
*
* @author Administrator
*
*/
class Distance
{
/**
* 该节点
*/
private String vertex;
/**
* 该节点的父节点,即与当前节点连着的边的另一个节点
*/
private String parentVertex;
/**
* 两个点所在边的权值
*/
private int weight;
public Distance(String vertex, String parentVertex, int weight)
{
this.vertex = vertex;
this.parentVertex = parentVertex;
this.weight = weight;
}
public String toString()
{
return "(" + this.parentVertex + " : " + this.vertex + "value: "
+ this.getWeight() + ")";
}
public String getVertex()
{
return vertex;
}
public void setVertex(String vertex)
{
this.vertex = vertex;
}
public String getParentVertex()
{
return parentVertex;
}
public void setParentVertex(String parentVertex)
{
this.parentVertex = parentVertex;
}
public int getWeight()
{
return weight;
}
public void setWeight(int weight)
{
this.weight = weight;
}
}
贪婪算法——3 Dijkstra算法
最新推荐文章于 2024-07-24 20:54:00 发布