算法题!!!求解

TBNoO 2012-12-04 08:28:16
输入一张图:


说明:边的数值代表从A到B的代价;

输出:从a到G的路线,要求,代价最小:

求解:算法:
1
先随便输出5条路径:
比如:abeg adbeg adfg abceg adefg
2,计算每条路径的健康度:也就是花费:
比如:abeg=7+7+9;
3,选出5条中最健康的4条。两两进行交配。

交配就是如果有相同节点,则交换路径:
比如:
abc d efg
afscv d fdsg

他们俩交换以后是
afscv d efg
abc d fdsg

然后在计算这四条的健康度。

以此类推。直到只有一条
...全文
286 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lost_guy_in_scut 2012-12-05
  • 打赏
  • 举报
回复
用最短路径算法,即可达到楼主的要求了。 http://java.chinaitlab.com/base/832683.html
kosora曹 2012-12-05
  • 打赏
  • 举报
回复
思想本身就不是最权威的,而且,这种问题最好自己去实现,不要总是想着用别人提供好的API,虽然咱身为码工,但是一定要有成为设计人员的目标。 试试用迪杰斯特拉算法,参考http://baike.baidu.com/view/1939816.htm。 基本思想: 将图G中所有的顶点V分成两个顶点集合S和T。以v为源点已经确定了最短路径的终点并入S集合中,S初始时只含顶点v,T则是尚未确定到源点v最短路径的顶点集合。然后每次从T集合中选择S集合点中到T路径最短的那个点,并加入到集合S中,并把这个点从集合T删除。直到T集合为空为止。 首先,你要明白“图”是点的集合与关系的集合这两个集合组合在一起的数据结构,而“邻接表”是最常用的描述无向图或者有向图的方法 图论算法我研究过一段时间,所以这里就把我写的代码直接贴上去了,会有一些用不到的代码,请大家见谅: 迪杰斯特拉算法的类,对照这个类来看下面三个类吧!
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;
}

}
zhangchao19890805 2012-12-05
  • 打赏
  • 举报
回复
引用 5 楼 SmallYamateh 的回复:
思想本身就不是最权威的,而且,这种问题最好自己去实现,不要总是想着用别人提供好的API,虽然咱身为码工,但是一定要有成为设计人员的目标。 试试用迪杰斯特拉算法,参考http://baike.baidu.com/view/1939816.htm。 基本思想: 将图G中所有的顶点V分成两个顶点集合S和T。以v为源点已经确定了最短路径的终点并入S集合中,S初始时只含顶点v,T则是尚未确定到源点v最……
xingfuzhuzi1314 2012-12-05
  • 打赏
  • 举报
回复
引用 5 楼 SmallYamateh 的回复:
思想本身就不是最权威的,而且,这种问题最好自己去实现,不要总是想着用别人提供好的API,虽然咱身为码工,但是一定要有成为设计人员的目标。 试试用迪杰斯特拉算法,参考http://baike.baidu.com/view/1939816.htm。 基本思想: 将图G中所有的顶点V分成两个顶点集合S和T。以v为源点已经确定了最短路径的终点并入S集合中,S初始时只含顶点v……
学习下!
TBNoO 2012-12-04
  • 打赏
  • 举报
回复
找不到~你看见过? 麻烦你发个链接。谢谢
引用 3 楼 pagen_hd 的回复:
目测有现成的类提供解法,先到util里面找?
pagen_hd 2012-12-04
  • 打赏
  • 举报
回复
目测有现成的类提供解法,先到util里面找?
一起来玩玩呗 2012-12-04
  • 打赏
  • 举报
回复
这好像是数据结构里面求最短路径的问题吧。
Jacky-止涯 2012-12-04
  • 打赏
  • 举报
回复
引用 楼主 badyflf 的回复:
选出5条中最健康的4条。两两进行交配。 交配就是如果有相同节……
楼主,你这是遗传算法吧?这样效率不是很高的样子!还不如用贪心算法或者其他别的!

62,612

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧