以下的更改基于上一篇博客。
首先,vertex类的d由整型改变为float型。
有两种方法(都是作用于update函数)
第一:
将边的权重取对数。通过率越大,则对数越接近0(总为负数),由此,将update函数改为:
void Graph::update(Vertex* v)
{
list<Edge*> inc = incMap[v];
if (inc.size() == 0)
{
cerr << "No out degree!" << endl;
exit(EXIT_FAILURE);
}
list<Edge*>::iterator it;
for (it = inc.begin(); it != inc.end(); it++)
{
float d = v->d - log((*it)->getPassRate()); // only change here
if ((*it)->head->d > d)
{
(*it)->head->parent = v;
(*it)->head->d = d;
}
}
}
即可,同时注意引入#include <cmath>
第二种方法最直接,加变成乘,初始化的时候变一下。排序的时候变一下。总体发动如下:
bool comp(Vertex* a, Vertex* b)
{
return a->d > b->d;
}
void Graph::update(Vertex* v)
{
list<Edge*> inc = incMap[v];
if (inc.size() == 0)
{
cerr << "No out degree!" << endl;
exit(EXIT_FAILURE);
}
list<Edge*>::iterator it;
for (it = inc.begin(); it != inc.end(); it++)
{
float d = v->d * (*it)->getPassRate();
if ((*it)->head->d < d)
{
(*it)->head->parent = v;
(*it)->head->d = d;
}
}
}
void Graph::dijkstra(int sid, int did)
{
Vertex* s = vertexMap[sid];
Vertex* temp;
s->d = 1;
map<int, Vertex*>::iterator it;
for (it = vertexMap.begin();
it != vertexMap.end();
it++)
if (it->second->ID != sid)
{
it->second->d = 0;
notMarkedVertex.push_back(it->second);
}
update(s);
do
{
notMarkedVertex.sort(comp);
temp = notMarkedVertex.front();
notMarkedVertex.pop_front();
if (temp->ID == did)
break;
update(temp);
}while(!notMarkedVertex.empty());
path = new Path(*vertexMap[did]);
path->print();
}
即:comp函数:通过率大的优先(而非距离近的优先)
update函数:当前通过率乘以边的通过率为新通过率。若存在更大的通过率,则更新。
初始化时:s为1(100%),其它为0(0%)