247 lines
6.7 KiB
C++
247 lines
6.7 KiB
C++
/*Copyright (c) 2010, Robin Message <Robin.Message@cl.cam.ac.uk>
|
||
All rights reserved.
|
||
|
||
Redistribution and use in source and binary forms, with or without
|
||
modification, are permitted provided that the following conditions are met:
|
||
* Redistributions of source code must retain the above copyright
|
||
notice, this list of conditions and the following disclaimer.
|
||
* Redistributions in binary form must reproduce the above copyright
|
||
notice, this list of conditions and the following disclaimer in the
|
||
documentation and/or other materials provided with the distribution.
|
||
* Neither the name of the Univsersity of Cambridge nor the
|
||
names of its contributors may be used to endorse or promote products
|
||
derived from this software without specific prior written permission.
|
||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||
DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF CAMBRIDGE OR ROBIN MESSAGE
|
||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
*/
|
||
|
||
#include "dijstra_MinHeap.h"
|
||
#include "dijstra_fibonacci.h"
|
||
#include "graph.h"
|
||
#include "fibonacci.h"
|
||
#define INT_MAX 2147483647
|
||
using namespace std;
|
||
//P[v]保存路径(即每个节点的前驱节点)
|
||
FibonacciHeap h;
|
||
/*
|
||
void print_path(struct Path* p,int V,int src){
|
||
//int V = graph->V;
|
||
for(int i=0;i<V;++i)
|
||
{
|
||
printf("v%d - v%d : %d\n",src,i,p[i].dist);
|
||
|
||
}
|
||
for(int i=0;i<V;++i)
|
||
{
|
||
printf("v%d - v%d : ",src,i);
|
||
int j=i;
|
||
while(p[j].pre!=0)
|
||
{
|
||
printf("%d ",p[j].pre);
|
||
j=p[j].pre;
|
||
}
|
||
printf("\n");
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
int isIn(set<int> v1,struct Path* p){
|
||
set<int>::iterator it; //定义前向迭代器
|
||
|
||
for(it=v1.begin();it!=v1.end();it++){
|
||
if(p[*it].dist>=INT_MAX)
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
*/
|
||
struct Path* dijkstra_fibonacci(struct Graph* graph, int src) {
|
||
|
||
int V = graph->V;
|
||
struct Path* p=new struct Path[V];
|
||
h.capacity=V;
|
||
// 初始化堆包含所有的顶点
|
||
for (int v = 0; v < V; ++v) {
|
||
p[v].dist = INT_MAX;
|
||
p[v].pre=0;
|
||
h.insert(v,INT_MAX);
|
||
}
|
||
h.pos[src]->value=0;
|
||
|
||
// 把 源点 src 的距离设置为0,第一个取出的点即为源点
|
||
p[src].dist = 0;
|
||
|
||
|
||
h.decreaseKey(h.pos[src],p[src].dist);
|
||
|
||
|
||
|
||
|
||
// 这个循环中,h包含的是所有未在SPT中的顶点
|
||
while (!h.isEmpty()) {
|
||
// 取得堆顶节点,即最小距离的顶点
|
||
|
||
int u = h.heap->v;
|
||
h.removeMinimum();
|
||
// 只需要遍历和u相邻的顶点进行更新
|
||
struct AdjListNode* pCrawl = graph->array[u].head;
|
||
while (pCrawl != NULL) {
|
||
int v = pCrawl->dest;
|
||
// 松弛操作,更新距离
|
||
if (h.pos[v]!=NULL && p[u].dist != INT_MAX
|
||
&& pCrawl->weight + p[u].dist < p[v].dist) {
|
||
p[v].dist = p[u].dist + pCrawl->weight;
|
||
p[v].pre=u;
|
||
//距离更新了之后,要调整最小堆
|
||
//decreaseKey(minHeap, v, p[v].dist);
|
||
h.decreaseKey(h.pos[v],p[v].dist);
|
||
}
|
||
pCrawl = pCrawl->next;
|
||
}
|
||
}
|
||
//print_path(p,V,src);
|
||
return p;
|
||
}
|
||
|
||
struct Path* dijkstra_fibonacci_v1(struct Graph* graph, int src,set<int> v1) {
|
||
|
||
int V = graph->V;
|
||
struct Path* p=new struct Path[V];
|
||
h.capacity=V;
|
||
// 初始化堆包含所有的顶点
|
||
for (int v = 0; v < V; v++) {
|
||
p[v].dist = INT_MAX;
|
||
p[v].pre=0;
|
||
h.insert(v,INT_MAX);
|
||
}
|
||
h.pos[src]->value=0;
|
||
|
||
// 把 源点 src 的距离设置为0,第一个取出的点即为源点
|
||
p[src].dist = 0;
|
||
|
||
|
||
h.decreaseKey(h.pos[src],p[src].dist);
|
||
|
||
|
||
|
||
|
||
// 这个循环中,h包含的是所有未在SPT中的顶点
|
||
while (!h.isEmpty() && v1.size()!=0) {
|
||
// 取得堆顶节点,即最小距离的顶点
|
||
|
||
int u = h.heap->v;
|
||
v1.erase(u);
|
||
h.removeMinimum();
|
||
// 只需要遍历和u相邻的顶点进行更新
|
||
struct AdjListNode* pCrawl = graph->array[u].head;
|
||
while (pCrawl != NULL) {
|
||
int v = pCrawl->dest;
|
||
// 松弛操作,更新距离
|
||
if (h.pos[v]!=NULL && p[u].dist != INT_MAX
|
||
&& pCrawl->weight + p[u].dist < p[v].dist) {
|
||
p[v].dist = p[u].dist + pCrawl->weight;
|
||
p[v].pre=u;
|
||
//距离更新了之后,要调整最小堆
|
||
//decreaseKey(minHeap, v, p[v].dist);
|
||
h.decreaseKey(h.pos[v],p[v].dist);
|
||
}
|
||
pCrawl = pCrawl->next;
|
||
}
|
||
}
|
||
//print_path(p,V,src);
|
||
return p;
|
||
}
|
||
|
||
|
||
struct Path* dijkstra_fibonacci_drop_v(struct Graph* source_graph, int src,set<int> v1,set <int> v) {
|
||
struct Graph* graph=drop_ver(source_graph,v);
|
||
int V = graph->V;
|
||
struct Path* p=new struct Path[V];
|
||
h.capacity=V;
|
||
// 初始化堆包含所有的顶点
|
||
for (int v = 0; v < V; ++v) {
|
||
p[v].dist = INT_MAX;
|
||
p[v].pre=0;
|
||
h.insert(v,INT_MAX);
|
||
}
|
||
h.pos[src]->value=0;
|
||
|
||
// 把 源点 src 的距离设置为0,第一个取出的点即为源点
|
||
p[src].dist = 0;
|
||
//minHeap->array[src] = newMinHeapNode(src, p[src].dist);
|
||
// minHeap->array[src]->dist=0;
|
||
|
||
h.decreaseKey(h.pos[src],p[src].dist);
|
||
// decreaseKey(minHeap, src, p[src].dist);
|
||
|
||
// minHeap->size = V;
|
||
|
||
// 这个循环中,minHeap包含的是所有未在SPT中的顶点
|
||
while (!h.isEmpty() && v1.size()!=0) {
|
||
// 取得堆顶节点,即最小距离的顶点
|
||
// struct MinHeapNode* minHeapNode = extractMin(minHeap);
|
||
int u = h.heap->v;
|
||
v1.erase(u);
|
||
h.removeMinimum();
|
||
// 只需要遍历和u相邻的顶点进行更新
|
||
struct AdjListNode* pCrawl = graph->array[u].head;
|
||
while (pCrawl != NULL) {
|
||
int v = pCrawl->dest;
|
||
// 松弛操作,更新距离
|
||
if (h.pos[v]!=NULL && p[u].dist != INT_MAX
|
||
&& pCrawl->weight + p[u].dist < p[v].dist) {
|
||
p[v].dist = p[u].dist + pCrawl->weight;
|
||
p[v].pre=u;
|
||
//距离更新了之后,要调整最小堆
|
||
//decreaseKey(minHeap, v, p[v].dist);
|
||
h.decreaseKey(h.pos[v],p[v].dist);
|
||
}
|
||
pCrawl = pCrawl->next;
|
||
}
|
||
}
|
||
//print_path(p,V,src);
|
||
return p;
|
||
}
|
||
|
||
void test() {
|
||
int V = 4;
|
||
set<int> v1;
|
||
v1.insert(2);
|
||
//v1.insert(3);
|
||
v1.insert(4);
|
||
v1.insert(1);
|
||
set<int> v;
|
||
v.insert(3);
|
||
//v.insert(13);
|
||
struct Graph* graph = createGraph(V);
|
||
addEdge(graph, 0, 1, 1);
|
||
addEdge(graph, 0, 3, 2);
|
||
addEdge(graph, 1, 2, 1);
|
||
addEdge(graph, 1, 3, 20);
|
||
addEdge(graph, 2, 3, 3);
|
||
// print_graph(graph);
|
||
//print_graph(drop_ver(graph,v));
|
||
//print_graph(graph);
|
||
print_path(dijkstra_fibonacci(graph,1),V,1);
|
||
print_path(dijkstra(graph,1),V,1);
|
||
//dijkstra_fibonacci_v1(graph,0,v1);
|
||
//dijkstra_fibonacci_drop_v(graph,0,v1,v);
|
||
|
||
}
|
||
|
||
|
||
int main() {
|
||
test();
|
||
return 0;
|
||
}
|
||
|
||
|