62,612
社区成员
发帖
与我相关
我的任务
分享
package tm.cao.tu;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
//专门用于迪杰斯特拉算法的类
public class Dijkstra{
//顶点集合
private List<DingDian> dianList;
//关系集合
private List<GuanXi> guanxiList;
public List<DingDian> getDianList() {
return dianList;
}
public List<GuanXi> getGuanxiList() {
return guanxiList;
}
public void setDianList(List<DingDian> dianList) {
this.dianList = dianList;
}
public void setGuanxiList(List<GuanXi> guanxiList) {
this.guanxiList = guanxiList;
}
//构造器
public Dijkstra(List<DingDian> dianList, List<GuanXi> guanxiList, Integer flag) {
super();
this.dianList = dianList;
//有向图
if(flag==0){
this.guanxiList=guanxiList;
}else if(flag==1){
//如果是无向图,则需要加入反序的关系
List<GuanXi> list2=new ArrayList<GuanXi>();
for(GuanXi gx:guanxiList){
GuanXi fan=new GuanXi(gx.getWei(), gx.getTou(), gx.getQuan());
list2.add(fan);
}
guanxiList.addAll(list2);
this.guanxiList=guanxiList;
}else{
//无论如何也不扩展边集 相当于只创建边集数组
this.guanxiList=guanxiList;
}
}
//构造邻接表
public void createLingJieBiao(){
if(guanxiList.size()>0){
Collections.sort(guanxiList);
}
for(GuanXi gx:guanxiList){
DingDian tou=gx.getTou();
Hu q=new Hu(gx.getWei(), gx.getQuan());
q.setId(gx.getId());
//入度+1 对应于拓扑排序
DingDian wei=gx.getWei();
int rudu=wei.getRudu();
rudu++;
wei.setRudu(rudu);
if(tou.getFirstHu()==null){
tou.setFirstHu(q);
}else{
Hu p=tou.getFirstHu();
while(p.getNextHu()!=null){
p=p.getNextHu();
}
p.setNextHu(q);
}
}
}
/**迪杰斯克拉算法 http://baike.baidu.com/view/1939816.htm
*sList:需要求的顶点集合 一开始只有一个点 dist属性:记录长度,path属性:记录路径的数组
*/
public List<DingDian> disjaktra(DingDian which){
this.createLingJieBiao();
List<DingDian> sList=new ArrayList<DingDian>();
//为了计算dist方便 设置一个动态集合 用于记录dist已经不是null的点
List<DingDian> dongtaiList=new ArrayList<DingDian>();
//所需要求的点已经被遍历过
which.setShenduFlag(1);
//先设置第一个点的相关属性
sList.add(which);
which.setDist(0);
//如果他没有出度 则没有通路
if(which.getFirstHu()==null){
System.out.println("没有通路!");
return null;
}else{
//遍历邻接表的所有弧 设置相应点的dist以及path 但并不添加到sList
this.findAllChudu(which, dongtaiList);
}
while(dongtaiList.size()>0){
DingDian minDian=dongtaiList.get(0);
Integer min=minDian.getDist();
//擂台算法找出最小的dist
for(DingDian d:dongtaiList){
if(d.getDist()<min){
min=d.getDist();
minDian=d;
}
}
minDian.setShenduFlag(1);
dongtaiList.remove(minDian);
sList.add(minDian);
if(minDian.getFirstHu()==null){
continue;
}else{
//遍历这个点的邻接表
this.findAllChudu(minDian, dongtaiList);
//继续
}
}
return sList;
}
//遍历这个顶点的邻接表 找到所有的弧
public void findAllChudu(DingDian minDian,List<DingDian> dongtaiList){
Hu hu=minDian.getFirstHu();
while(hu!=null){
DingDian find=hu.getDian();
//对于对称关系的无向图 如果该点已经被遍历过 则跳过
if(find.getShenduFlag()==1){
hu=hu.getNextHu();
continue;
}
// 算出值最小的dist或者上一个(dist+quan)
if(find.getDist()==null){
//如果没有 则把他的前驱结点的路径添加到自己的路径
find.setDist(hu.getQuan()+minDian.getDist());
find.getPath().addAll(minDian.getPath());
find.getPath().add(minDian);
}
else{
if(find.getDist()<(hu.getQuan()+minDian.getDist())){
}else{
//如果这次加起来的路径比上次的小 则先removeAl 然后add minDian 的路径以及minDian
find.setDist(hu.getQuan()+minDian.getDist());
find.getPath().clear();
find.getPath().addAll(minDian.getPath());
find.getPath().add(minDian);
}
}
if(!dongtaiList.contains(find)){
dongtaiList.add(find);
}
hu=hu.getNextHu();
}
}
}
顶点类:
package tm.cao.tu;
import java.util.ArrayList;
import java.util.List;
//所有的顶点
public class DingDian implements Comparable<DingDian>{
//迪杰斯特拉的dist长度
private Integer dist;
//记录路径的集合
private List<DingDian> path=new ArrayList<DingDian>();
public Integer getDist() {
return dist;
}
public void setDist(Integer dist) {
this.dist = dist;
}
public List<DingDian> getPath() {
return path;
}
public void setPath(List<DingDian> path) {
this.path = path;
}
//数据域
private String data;
//第一个弧 对应十字链表的firstOut
private Hu firstHu;
public String getData() {
return data;
}
public Hu getFirstHu() {
return firstHu;
}
public void setData(String data) {
this.data = data;
}
public void setFirstHu(Hu firstHu) {
this.firstHu = firstHu;
}
public DingDian(String data, Hu firstHu) {
super();
this.data = data;
this.firstHu = firstHu;
}
public DingDian() {
super();
}
public DingDian(String data) {
super();
this.data = data;
}
@Override
public String toString() {
return "DingDian [data=" + data + "]";
}
//第一个进来的弧
private Hu firstIn;
public Hu getFirstIn() {
return firstIn;
}
public void setFirstIn(Hu firstIn) {
this.firstIn = firstIn;
}
public int compareTo(DingDian other) {
return data.compareTo(other.getData());
}
//遍历时候的Flag 0表示未遍历 1表示已经遍历
private int shenduFlag;
public int getShenduFlag() {
return shenduFlag;
}
public void setShenduFlag(int shenduFlag) {
this.shenduFlag = shenduFlag;
}
//非递归深度遍历的时候当前弧
private Hu currentHu;
public Hu getCurrentHu() {
return currentHu;
}
public void setCurrentHu(Hu currentHu) {
this.currentHu = currentHu;
}
//prim算法的Flag
private int primFlag=1;
public int getPrimFlag() {
return primFlag;
}
public void setPrimFlag(int primFlag) {
this.primFlag = primFlag;
}
//为了prim算法方便 所以设置一个整数的id
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public DingDian(String data, int id) {
super();
this.data = data;
this.id = id;
}
//记录入度 用于拓扑排序
private int rudu;
public int getRudu() {
return rudu;
}
public void setRudu(int rudu) {
this.rudu = rudu;
}
//最早发生时间
private int ee;
//最晚发生时间
private int le;
public int getEe() {
return ee;
}
public int getLe() {
return le;
}
public void setEe(int ee) {
this.ee = ee;
}
public void setLe(int le) {
this.le = le;
}
}
关系类:
package tm.cao.tu;
//关系
public class GuanXi implements Comparable<GuanXi>{
public GuanXi() {
super();
}
//权
private Integer quan;
public Integer getQuan() {
return quan;
}
public void setQuan(Integer quan) {
this.quan = quan;
}
//直接设置头和尾
private DingDian tou;
private DingDian wei;
public DingDian getTou() {
return tou;
}
public DingDian getWei() {
return wei;
}
public void setTou(DingDian tou) {
this.tou = tou;
}
public void setWei(DingDian wei) {
this.wei = wei;
}
public GuanXi(DingDian tou, DingDian wei,Integer quan) {
super();
this.quan = quan;
this.tou = tou;
this.wei = wei;
}
@Override
public String toString() {
return "GuanXi [data1=" + tou.getData() + ", data2=" + wei.getData() + ", quan=" + quan
+ "]";
}
private int sortFlag;
public int getSortFlag() {
return sortFlag;
}
public void setSortFlag(int sortFlag) {
this.sortFlag = sortFlag;
}
//先比较权的大小 然后头的大小 然后比较尾的大小 排序权值 适用于Kruscal算法
public int compareTo(GuanXi other) {
//如果需要排序权
if(this.getSortFlag()==1){
return this.getQuan().compareTo(other.getQuan());
}
else if(!this.getTou().getData().equals(other.getTou().getData())){
return this.getTou().getData().compareTo(other.getTou().getData());
}else{
return this.getWei().getData().compareTo(other.getWei().getData());
}
}
public GuanXi(DingDian tou, DingDian wei, Integer quan, int sortFlag) {
super();
this.quan = quan;
this.tou = tou;
this.wei = wei;
this.sortFlag = sortFlag;
}
public GuanXi(DingDian tou, DingDian wei) {
super();
this.tou = tou;
this.wei = wei;
}
//为了计算方便
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public GuanXi(Integer quan, DingDian tou, DingDian wei, String id) {
super();
this.quan = quan;
this.tou = tou;
this.wei = wei;
this.id = id;
}
}
弧类:
package tm.cao.tu;
//所有的弧
public class Hu {
//为了表示方便 所以有id
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
//所指向的点 对应邻接表 此点为弧所指向的点
private DingDian dian;
//权
private Integer quan;
//下一个弧
private Hu nextHu;
public Integer getQuan() {
return quan;
}
public Hu getNextHu() {
return nextHu;
}
public void setQuan(Integer quan) {
this.quan = quan;
}
public void setNextHu(Hu nextHu) {
this.nextHu = nextHu;
}
public DingDian getDian() {
return dian;
}
public void setDian(DingDian dian) {
this.dian = dian;
}
public Hu() {
super();
}
public Hu(Integer quan, Hu nextHu, DingDian dian) {
super();
this.quan = quan;
this.nextHu = nextHu;
this.dian = dian;
}
public Hu(DingDian dian, Integer quan) {
super();
this.dian = dian;
this.quan = quan;
}
//以下四个属性 对应十字链表
private String qidian;
private String zhongdian;
private Hu hlink;
private Hu tlink;
public String getQidian() {
return qidian;
}
public String getZhongdian() {
return zhongdian;
}
public Hu getHlink() {
return hlink;
}
public Hu getTlink() {
return tlink;
}
public void setQidian(String qidian) {
this.qidian = qidian;
}
public void setZhongdian(String zhongdian) {
this.zhongdian = zhongdian;
}
public void setHlink(Hu hlink) {
this.hlink = hlink;
}
public void setTlink(Hu tlink) {
this.tlink = tlink;
}
public Hu(Integer quan, String qidian, String zhongdian, Hu hlink, Hu tlink) {
super();
this.quan = quan;
this.qidian = qidian;
this.zhongdian = zhongdian;
this.hlink = hlink;
this.tlink = tlink;
}
@Override
public String toString() {
return "Hu [id=" + id + ", dian=" + dian + ", quan=" + quan + "]";
}
//关键路径的权
private Integer guanJianQuan;
public Integer getGuanJianQuan() {
return guanJianQuan;
}
public void setGuanJianQuan(Integer guanJianQuan) {
this.guanJianQuan = guanJianQuan;
}
}