1.数据库表的设计:
dijsname1和dijsname2是有向图中的两个点。
qinmid是这两个点之间的亲密度,将亲密度的值作为边的权值大小。
2.对数据库中数据进行增删改查操作:
//这里主要实现了insert(插入)操作和查找操作(通过两个点查找亲密度)
package com.graduat.dao.impl;
public class DijstraImpl implements DijstTestDao {
private static final String INSERT = "insert into dijsttest(dijsname1,dijsname2,qinmid) values(?,?,?)";
private static final String FINDBYDN = "select qinmid from dijsttest where dijsname1=? and dijsname2=? ";
@Override
public void insert(DijstTest dijstTest) throws Exception {
PreparedStatement prep = null;
Connection conn = null;
try {
conn = DBConnection.getConnection();
prep = conn.prepareStatement(INSERT, Statement.RETURN_GENERATED_KEYS);
prep.setString(1, dijstTest.getDijsname1());
prep.setString(2, dijstTest.getDijsname2());
prep.setInt(3, dijstTest.getQinmid());
prep.executeUpdate();
ResultSet rst = prep.getGeneratedKeys();
rst.next();
int id = rst.getInt(1);
dijstTest.setId(id);
} finally {
DBConnection.close(prep, conn);
}
}
@Override
public DijstTest findByDn(String Dname1, String Dname2) throws Exception {
// TODO Auto-generated method stub
PreparedStatement prep = null;
Connection conn = null;
DijstTest dijstTest = null;
ResultSet rst = null;
try {
conn = DBConnection.getConnection();
prep = conn.prepareStatement(FINDBYDN);
prep.setString(1, Dname1);
prep.setString(2,Dname2);
rst = prep.executeQuery();
if(rst.next()) {
dijstTest = new DijstTest();
dijstTest.setQinmid(rst.getInt("qinmid"));
}
} finally {
DBConnection.close(prep, conn);
}
return dijstTest;
}
}
3.定义节点信息:
public class Node {
//定义节点的name属性和child孩子属性,并且实现其get和set方法。
private String name;
private Map<Node,Integer> child = new HashMap<Node, Integer>();
public Node(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<Node,Integer> getChild() {
return child;
}
public void setChild(Map<Node,Integer> child) {
this.child = child;
}
4.初始化所有节点:
public class MapBuilder {
String nodetestdemo = null;
DijstTestDao dijks = DijstraFactory.getDijistra();
DijstTest d;
public Node build(Set<Node> open, Set<Node> close, List<Node> lists) throws Exception {
Node n1;
for (int i = 0; i < lists.size(); i++) {
n1 = lists.get(i);
for (int j = 0; j < lists.size(); j++) {
if (n1 != lists.get(j)) {
//通过两个节点信息在数据库中查找亲密度权值。
d = dijks.findByDn(lists.get(i).getName(), lists.get(j).getName());
if(d != null)
n1.getChild().put(lists.get(j), d.getQinmid());
}
}
}
// 遍历node类型的数组
// 现在求每个点到其他点的最短距离之和已经实现,要循环抽象求和的最小值,输出最小中心结点和最短距离。
Node nn = null;
//close数组用来保存源节点信息
//open数组用来保存除了源节点之外的所有节点信息
for (int i = 0; i < lists.size(); i++) {
if( nodetestdemo.equals(lists.get(i).getName()) ) {
nn = lists.get(i);
close.add(lists.get());
}
else
open.add(lists.get(i));
}
return nn;
}
}
5.核心算法:
public class Dijkstra {
ArrayList<String> list = new ArrayList<String>();
Set<Node> open = new HashSet<Node>();
Set<Node> close = new HashSet<Node>();
Map<String, Integer> path = new HashMap<String, Integer>();// 封装路径距离
Map<String, String> pathInfo = new HashMap<String, String>();// 封装路径信息
String testpppp = null;
ArrayList<String> listlist = new ArrayList<String>();
ArrayList<Integer> listlist1 = new ArrayList<Integer>();
//通过输入两个节点的名字,去数据库中查找亲密度权值大小
//可直接到达则直接返回,否则返回最大值
public int finddistance(String num1, String num2) throws Exception {
DijstTestDao dijks = DijstraFactory.getDijistra();
DijstTest d = dijks.findByDn(num1, num2);
if (d != null) {
return d.getQinmid();
} else {
return Integer.MAX_VALUE;
}
}
public Node init(List<Node> nodes) throws Exception {
// 初始路径,因没有A->E这条路径,所以path(E)设置为Integer.MAX_VALUE
//list.size()是初始输入节点的个数
String[] t = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
t[i] = list.get(i);
}
for (int i = 0; i < t.length; i++) {
if (t[i] == testpppp) {
continue;
} else {
//将两节点的路径信息和路径长度分别存储在path和pathInfo中。
path.put(t[i], finddistance(testpppp, t[i]));
pathInfo.put(t[i], testpppp + "->" + t[i]);
}
}
// 将初始节点放入close,其他节点放入open
MapBuilder mapBuilder = new MapBuilder();
mapBuilder.nodetestdemo = testpppp;
Node start = mapBuilder.build(open, close, nodes);
return start;
}
public void computePath(Node start) {
Node nearest = getShortestPath(start);// 取距离start节点最近的子节点,放入close
if (nearest == null) {
return;
}
close.add(nearest);
open.remove(nearest);
Map<Node, Integer> childs = nearest.getChild();
for (Node child : childs.keySet()) {
if (open.contains(child)) {// 如果子节点在open中
Integer newCompute = path.get(nearest.getName())
+ childs.get(child);
if (path.get(child.getName()) > newCompute) {// 之前设置的距离大于新计算出来的距离
path.put(child.getName(), newCompute);
pathInfo.put(
child.getName(),
pathInfo.get(nearest.getName()) + "->"
+ child.getName());
}
}
}
computePath(start);// 重复执行自己,确保所有子节点被遍历
computePath(nearest);// 向外一层层递归,直至所有顶点被遍历
}
@SuppressWarnings({ "static-access", "rawtypes" })
public void printPathInfo(ArrayList<String> bigList,ArrayList<Integer> bigList1) {
Set<Map.Entry<String, String>> pathInfos = pathInfo.entrySet();
Collection<Integer> values = path.values();
int sum = 0;
int sum_end = 0;
for (Map.Entry<String, String> pathInfo : pathInfos) {
listlist.add(testpppp+"->"+pathInfo.getKey());
bigList.add(testpppp+"->"+pathInfo.getKey());
}
for (Integer object : values) {
sum = Integer.parseInt(object.toString());
sum_end = sum_end + sum;
listlist1.add(sum);
bigList1.add(sum);
}
System.out.println("和为sumend=" + sum_end);
System.out.println(testpppp);
Main main = new Main();
main.sum = sum_end;
main.testp = testpppp;
}
/**
* 获取与node最近的子节点,根据距离去判断远近关系
*/
private Node getShortestPath(Node node) {
Node res = null;
int minDis = Integer.MAX_VALUE;
Map<Node, Integer> childs = node.getChild();
for (Node child : childs.keySet()) {
if (open.contai`
s(child)) {
int distance = childs.get(child);
if (distance < minDis) {
minDis = distance;
res = child;
}
}
}
return res;
}
}
6.测试main函数:
public class Main {
int sumend = 0;
static int sum = 0;
static String testp = null;
ArrayList<String> listlist = new ArrayList<String>();
ArrayList<String> listlist1 = new ArrayList<String>();
static ArrayList<String> bigList = new ArrayList<String>();
static ArrayList<Integer> bigList1 = new ArrayList<Integer>();
public static void main(String[] args) throws Exception {
//在main函数中输入测试数组
String t[] = new String[] { "A", "B", "C", "D", "E", "F", "G", "H" };
Main.getShort(t);
int instance =findShortInstance("A","D");
System.out.println(instance);
}
public static String getShort(String[] ss) throws Exception {
Map<String, Integer> map = new HashMap<String, Integer>();
String aa = null;
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < ss.length; i++) {
list.add(ss[i]);
}
Dijkstra test;
List<Node> lists = new ArrayList<Node>();
for (int i = 0; i < ss.length; i++) {
Node node = new Node(ss[i]);
lists.add(node);
}
for (int i = 0; i < ss.length; i++) {
test = new Dijkstra();
test.list = list;
test.testpppp = ss[i];
Node start = test.init(lists);
test.computePath(start);
test.printPathInfo(bigList,bigList1);
map.put(testp, sum);
}
for (Map.Entry<String, Integer> me : map.entrySet()) {
}
if (map != null) {
Collection<Integer> c = map.values();
Object[] obj = c.toArray();
Arrays.sort(obj);
int value = (int) obj[0];
System.out.println("中心点距离其他所有点的最短距离为" + value);
for (Map.Entry entry : map.entrySet()) {
if (value == (int) entry.getValue()) {
aa = (String) entry.getKey();
}
}
}
return aa;
}
public static int findShortInstance(String a, String b)throws Exception {
int instance = -1;
for(int i=0; i<bigList.size(); i++){
if(bigList.get(i).contains(a) && bigList.get(i).contains(b)){
instance = bigList1.get(i);
return instance;
}
}
return instance;
}
}