Algorithm第四版算法 C++实现(二十一)——bellman-find算法(带权图最短路径算法)

bellman-find算法与dijkstra算法有一点相似,不过我们在这个算法中维护了一个队列来进行下一步的遍历。但是bellman-find算法也有一个局限,便是不呢处理具有负权重环的图。

/*bellman - find算法*/
class bellman_find
{
private:
	double *dist_to; //路径长度
	std::vector<diedge> edge_to;
	bool *onq;
	std::queue<int> q;
	int cost;
	std::vector<diedge> cycle;
	void find_necycle()
	{
		int v = edge_to.size();
		EWdigraph spt(v);
		for (int i = 0; i < v; i++)
		{
			if (edge_to[i].weight() != inf)
			{
				spt.add_edge(edge_to[i]);
			}
		}
		/*缺少类*/
	}
	void relax(EWdigraph g, int v)
	{
		for (diedge e : g.iterator(v))
		{
			int w = e.to();
			if (dist_to[w] > dist_to[v] + e.weight())
			{
				dist_to[w] = dist_to[v] + e.weight();
				edge_to[w] = e;
				if (!onq[w])
				{
					q.push(w);
					onq[w] = true;
				}
				if (cost++%g.numv() == 0)
				{
					find_necycle();
				}
			}
		}
	}
public:
	bool has_necycle()
	{
		return !cycle.empty();
	}
	bellman_find(EWdigraph g, int s)
	{
		dist_to = new double[g.numv()];
		edge_to.resize(g.numv());
		onq = new bool[g.numv()];
		std::fill(dist_to, dist_to + g.numv(), inf);
		std::fill(onq, onq + g.numv(), 0);
		dist_to[s] = 0;
		q.push(s);
		onq[s] = true;
		while (!q.empty()&&!has_necycle())
		{
			int v = q.front();
			q.pop();
			onq[v] = false;
			relax(g, v);
		}
	}
	double dist(int to)
	{
		return dist_to[to];
	}
};

运行结果

在这里插入图片描述

老规矩,你可以看到我留下了一个edge_to的vector容器,你可以增加返回路径或者其他数据的方法。此外,由于该算法只能判断无负权重环的加权有向有向图的最短路径,所以本应该有一个判断是否有负权重环的方法。由于书中调用了一个判断是否有负权重环的方法,却并没有给出相应的实现;加之并非必要,所以我在此并没有实现那个方法,而是进行了留白。感兴趣的朋友可以参考拓扑排序中寻找有向环的方法对这个类进行构造

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值