国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

首頁 > 編程 > C > 正文

基于稀疏圖上的Johnson算法的詳解

2020-01-26 16:18:23
字體:
來源:轉載
供稿:網友

算法步驟簡述:

1.計算圖G加入新結點后的圖G',加入的新結點0到所有原結點之間距離為0,同時形成新的邊集E';

2.使用Bellman-Ford算法處理G',并形成0結點到各結點的最小距離d。

3.如果Bellman-Ford算法檢測出有負權回路則提示FALSE并退出,否則繼續。

4.對所有G'中的頂點v,根據0結點到v的最小距離,將h(v)設置為這個值。

5.對所有的邊w(u,v),權值更新為w(u,v)+h(u)-h(v)

6.對圖G中所有結點運行Dijkstra算法計算與其他頂點最短距離d'[u][v]

(此處假定G和w集合是分開存儲的。直接使用G'也可以,因為0結點對其他結點是不可達的,但這顯然浪費了計算時間。如果權值信息存在G'中,可以對G'進行操作,只不過跳過了0結點的處理)

7.原圖G中最短距離d[u][v] = d'[u][v] +h(v)-h(u)

  代碼中有的地方沒有優化,比如輔助結構vassist其實在Bellman-Ford算法和Dijkstra算法兩個函數中用法稍微有所不同,而且成員變量在前者中只用了2個;同時松弛算法relax也有類似的情況。前者是簡單的復用,后者直接用名字區分。

  代碼包含三部分:Bellman-Ford算法、Dijkstra算法、用二項堆實現的優先級數組(Dijkstra算法要用到)。以下是算法的C語言版本,測試實例同《算法導論》圖25-1

復制代碼 代碼如下:

#include <stdio.h>
#include <stdlib.h>

#define U    65535
#define PARENT(i)    ((i-1)/2)
#define LEFT(i)        (2*(i)+1)
#define RIGHT(i)    (2*(i)+2)
#define N 5

struct vertex {
    int key;
    struct vtable *adj;
};

struct vtable {
    int key;//這個key是在vertex數組的序號
    //struct vertext *v;
    int w;
    struct vtable *next;
};

struct vassist {
    int d;
    int p;
    int key;
};

 


int insert(struct vertex *,int,int,int,int);
int walk(struct vertex *,int,int);
struct vassist *initialize_ss(int,int);
int relaxd(int *,int ,int ,int);
int relaxb(struct vassist *,int ,int ,int);
int build_min_heap(struct vassist *,int);
int min_heapify(struct vassist *, int ,int);
int heap_extract_min(struct vassist *,int);
int inheap(struct vassist *,int ,int );
int heap_decrease(struct vassist *,int ,int);
int dijkstra(struct vertex *,int,int,int **);
int bellman_ford(struct vertex *,int*, int,int);

int insert(struct vertex *p,int len,int i,int j,int w) {
    struct vtable *q,*prev;
    q = p[i].adj;
    printf("key:%d/n",p[i].key);
    prev = NULL;
    while(q!=NULL) {
        if (q->key == j) {
            printf("error: v %d to %d already exist./n",i,j);
            return 0;
        }
        else {
            prev = q;
            q=q->next;
        }
    }
    q = (struct vtable*)malloc(sizeof(struct vtable));
    q->key = j;
    q->w = w;
    q->next = NULL;
    if(prev!=NULL)
        prev->next = q;
    else
        p[i].adj = q;
    return 1;
}

int walk(struct vertex *p,int len,int i) {
    struct vtable *q = p[i].adj;   
    while(q!=NULL) {
        printf(" %d,w is %d/n",q->key,q->w);
        q=q->next;
    }
    printf("/n");
}

struct vassist *initialize_ss(int size,int s) {
    int i;
    struct vassist *va;
    va = (struct vassist *)malloc(size*sizeof(struct vassist));
    for(i=0;i<size;i++) {
        va[i].key = i;//建堆后i!=key
        va[i].d = U;
        va[i].p = -1;
    }
    va[s].d = 0;
    return va;
}

//relax for dijkstra
int relaxd(int *p,int u,int v,int w) {//w=w(u,v)
    if(p[v]>p[u]+w) {
        p[v] = p[u]+w;
        //為了簡單處理,p使用的是數組
        //沒有父母標記
        //如果想用父母標記,請將p改為一個自定義的結構體
    }
    return 1;
}

//relax for beltman_ford
int relaxb(struct vassist *va,int u,int v,int w) {//w=w(u,v)
    if(va[v].d>va[u].d+w) {
        va[v].d = va[u].d+w;
        va[v].p = u;
    }
    return 1;
}


int bellman_ford(struct vertex *graph,int *h,int size,int s) {//算法要求不含源點可達的負權回路
    int i,j;
    struct vtable *p;
    struct vassist *va;
    va = initialize_ss(size,s);
    for(i=1;i<size;i++)
        for(j=0;j<size-1;j++) {
            p = graph[j].adj;
            while(p!=NULL) {
                relaxb(va,j,p->key,p->w);
                p=p->next;
            }
        }

    printf("from %d,/n",s);
    for(j=0;j<size;j++)
        printf("to %d: %d/n",j,va[j].d);
       

    for(j=0;j<size;j++) {//對0結點不必要
        p = graph[j].adj;
        while(p!=NULL) {
            if(va[p->key].d>va[j].d+p->w)
                return 0;
            p = p->next;
        }
    }
    for(j=1;j<=size;j++)
        h[j] = va[j].d;
    free(va);
    h[0] = 0;
    return 1;
}

int build_min_heap(struct vassist *va,int size) {//建堆
    int i;
    for (i =size/2-1; i>=0; i--)
        min_heapify(va,i,size);

    return 1;
}


int min_heapify(struct vassist *va, int i,int heap_size) {
    int l,r,min;
    struct vassist temp;
    int tmin = U;
    l = LEFT(i);
    r = RIGHT(i);
    if ((l < heap_size) &&(va[l].d<va[i].d)) {
        min = l;
        tmin = va[l].d;
    }
    else {
        min = i;
        tmin = va[i].d;
    }
    if ((r < heap_size) &&(va[r].d<va[min].d)) {
        min = r;
        tmin = va[r].d;
    }
    if (!(min == i)) {
        temp.d = va[min].d;
        temp.p = va[min].p;
        temp.key = va[min].key;

        va[min].d = va[i].d;
        va[min].p = va[i].p;
        va[min].key = va[i].key;

        va[i].d = temp.d;
        va[i].p = temp.p;
        va[i].key = temp.key;

        min_heapify(va,min,heap_size);
    }
    return 1;
}

int heap_extract_min(struct vassist *va,int heap_size) {
    int min;   
    if ( heap_size<1 )
        return -1;
    min = va[0].key;
    va[0].p = va[heap_size -1].p;
    va[0].d = va[heap_size -1].d;
    va[0].key = va[heap_size -1].key;
    heap_size = heap_size -1;
    min_heapify(va,0,heap_size);
    return min;
}

int inheap(struct vassist *va,int heap_size,int j) {
    int i;
    for(i=0;i<heap_size;i++)
        if(va[i].key == j)
            return i;
    return -1;
}

int heap_decrease(struct vassist *va,int i,int key_new) {
    struct vassist temp;   
    if(key_new>va[i].d)
        return 0;
    va[i].d = key_new;
    while((i>0)&&(va[PARENT(i)].d > va[i].d)) {
        temp.d = va[i].d;
        temp.p = va[i].p;
        temp.key = va[i].key;
        va[i].d = va[PARENT(i)].d;
        va[i].p = va[PARENT(i)].p;
        va[i].key = va[PARENT(i)].key;
        va[PARENT(i)].d = temp.d;
        va[PARENT(i)].p = temp.p;
        va[PARENT(i)].key = temp.key;
        i = PARENT(i);
    }
    return 1;       
}

int dijkstra(struct vertex *graph,int len,int s,int **delta) {
    int i,j,heap_size;
    struct vtable *q;
    struct vassist *va;
    int *p;
    p = (int *)malloc(len * sizeof(int));
    for(i=0;i<len;i++)
        p[i] = U;
    p[s] = 0;
    heap_size = len;

    va = initialize_ss(len,s);
    build_min_heap(va,heap_size);//va被拿去建堆,后續輸出距離時不能再用了


    while(heap_size>0) {
        i = heap_extract_min(va,heap_size);
        printf("node:%d/n",i);
        heap_size--;
        for(j=0;j<heap_size;j++)
            printf("key:%d,d:%d, in array:%d/n",va[j].key,va[j].d,p[va[j].key]);
        q = graph[i].adj;
        while(q!=NULL) {
            j=inheap(va,heap_size,q->key);
            if(j>=0)
                if(va[j].d>p[i]+q->w)   
                    heap_decrease(va,j,p[i]+q->w);
            relaxd(p,i,q->key,q->w);//其實可以合并heap_decreas和relax,不過為了接口簡單沒有這樣做
            printf("relax %d to %d ,w is %d/n",i,q->key,q->w);
            q = q->next;
        }
        for(j=0;j<heap_size;j++)
            printf("key:%d,d:%d, in array:%d/n",va[j].key,va[j].d,p[va[j].key]);
    }
    for(i=0;i<len;i++)
        printf("from %d to %d, distance is %d/n",s,i,p[i]);

    free(va);

    for(i=0;i<len;i++) {
        delta[s][i] = p[i];
    }
    free(p);   

}

int **johnson(struct vertex *g, int n) {
    int i,j;
    int *h,**delta,**d;
    struct vertex *gn;
    struct vtable *p;
    gn = (struct vertex *)malloc(n*sizeof(struct vertex));
    h = (int *)malloc(n*sizeof(int));
    delta = (int**)malloc(n*sizeof(int *));
    d = (int**)malloc(n*sizeof(int *));
    for(i=0;i<n;i++) {
        delta[i]=(int*)malloc(n*sizeof(int));
        d[i]=(int*)malloc(n*sizeof(int));
    }
    for(i=0;i<n;i++)
        gn[i] = g[i];

    for(i=1;i<n;i++)
            insert(gn,n,0,i,0);
    if(!bellman_ford(gn,h,n,0)) {
        printf("the input graph contains a negative-weight cycle./n");
        return NULL;
    }

    for(i=0;i<n;i++) {
        p = gn[i].adj;
        while(p!=NULL) {
            p->w = p->w+h[i]-h[p->key];
            p=p->next;
        }
    }
    for(i=0;i<n;i++)
        walk(gn,n,i);

    printf("before dijkstra/n");
    for(i=1;i<n;i++) {
        dijkstra(gn,n,i,delta);
        for(j=1;j<n;j++)
            d[i][j] = delta[i][j] + h[j] - h[i];

    }
    for(i=1;i<n;i++) {
        for(j=1;j<n;j++)
            printf("%d/t",d[i][j]);
        printf("/n");
    }
    return d;
}

int main(){
    int i,j;
    int **d;
    struct vertex vt[N+1];//為0結點的加入預留位置
    for(i=0;i<N+1;i++) {
        vt[i].adj = NULL;
        vt[i].key = i;
    }

    insert(vt,N+1,1,2,3);
    insert(vt,N+1,1,3,8);
    insert(vt,N+1,1,5,-4);
    insert(vt,N+1,2,4,1);
    insert(vt,N+1,2,5,7);
    insert(vt,N+1,3,2,4);
    insert(vt,N+1,4,3,-5);
    insert(vt,N+1,4,1,2);
    insert(vt,N+1,5,4,6);
    d = johnson(vt,N+1);

    return 1;
}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
中文字幕在线视频网| av中文在线| 国产字幕在线看| 女同一区二区免费aⅴ| wwwww亚洲| 成视频年人免费看黄网站| 福利视频网站导航| 尤物视频网站在线观看| 国产亚洲精品久久久久久移动网络 | 国产porn在线| 尤物视频在线观看视频| 日本亚洲欧美| 中文字幕成人乱码在线电影| 精品一区二区三区在线观看l| 四虎www视频| √天堂中文在线| 午夜影院免费看| 国产三级在线| 久热精品免费视频| 精品极品三级久久久久| 久久精品免视着国产成人| 国产精品欧美色图| 欧美性猛交p30| 国产小视频在线观看| 在线视频中文字幕第一页| 激情视频国产| av在线播放av| 国产叼嘿网站免费观看不用充会员| 亚洲综合在线不卡| 2021天堂中文幕一二区在线观| 欧美艹逼视频| 天天噜天天色| 精品推荐蜜桃传媒| 国产黄色在线网站| 中文字幕在线观看日本| 九九久久久2| 日本高清不卡中文字幕| 999精品网| 中文字幕在线免费视频| 国产在线激情视频| 一级二级三级在线观看| 99热99re6国产在线播放| 国产一区二区在线|播放| 九九热视频在线观看| 久久久久久久久免费视频| 亚洲综合天堂网| 伊人伊人av电影| 伊人影院在线观看| 在线播放国产区| 在线观看av资源网| 亚洲国产精华液| www.三级.com| 久草.com| 最新黄网在线观看| 国产成人高清精品| 怡红院av在线| 日本电影全部在线观看网站视频| av在线首页| 国产在线二区| 国产图片综合| 在线天堂中文| 欧洲有码在线视频| 中文字幕一区二区三区免费视频| 国产人成在线视频| 6699久久国产精品免费| 日韩亚洲一区中文字幕| 久草在线视频网| 国产三级在线| 亚洲欧美国产另类首页| 超碰在线影院| 精品视频vs精品视频| 欧美视频免费一区二区三区| 午夜视频99| 亚洲天堂视频在线观看免费| 久草在线视频网| 国产二区在线播放| 免费a级毛片在线播放| 天堂在线中文资源| 亚洲尤物在线视频| 天天操天天射天天插| 96久久久久久| 国产精品作爱| 四虎成人免费观看在线网址| 国产有码在线| 国产porn在线| 国产亚洲精品午夜高清影院| 免费在线高清av| 在线国产一区二区三区| 国产精品视频二区三区| 男人天堂亚洲| 在线视频观看你懂的| 国产小视频免费在线观看| www.狠狠| 亚洲精品天堂在线观看| 中文字幕在线免费观看| 黄色毛片在线观看| 超碰91在线| 一区二区三区免费视频网站| 国产一二三四| 91av资源在线| 国产一级片麻豆| 最近中文字幕av免费高清| 久久av少妇| 国内精品一区视频| 激情在线视频播放| 久精品在线观看| 高清av中文在线字幕观看1| 国产美女福利在线| 丁香花高清在线观看完整版 | 尤物视频在线观看视频| 精品国产白色丝袜高跟鞋| 国产精品剧情一区二区在线观看| 五月婷婷在线视频| 国产一级性片| 国产高清大尺度一区二区不卡| 国产精品合集一区二区| 在线国产三级| 超碰免费在线观看| √天堂8资源中文在线| 国产精品秘入口| 一区二区三区免费视频网站| jizz亚洲大全| 久草网在线视频| 国产视频一二区| a√在线视频| а天堂8中文最新版在线官网| 九色在线网站| 精品剧情v国产在线观看| 蜜桃视频网站在线| 国产福利小视频在线| 亚洲精品xxxxx| 在线91av| 天天插天天操| 国产网站av| 九九精品视频在线观看九九| 国产成人久久精品77777| 狠狠插狠狠操| 国产精品18久久久久网站| 夜夜操com| 中文字幕在线免费观看| 亚洲精品天堂在线观看| 国产人成精品| 国产麻豆精品高清在线播放| 在线免费国产视频| 国产美女福利在线| xxx国产精品| 中文资源在线网| 中文字幕中文字幕在线中高清免费版 | 男女午夜视频在线观看| 国产二级片在线| 国产一级在线观看www色| 麻豆精品免费视频入口| 在线成人综合色一区| 国产高清视频在线| 中文字幕一区二区三区免费视频| 牛牛热在线视频| 日本黄在线观看| 日韩国产成人| 日韩a视频在线观看| 亚色视频在线观看| 国产精品视频二区三区| 国产无遮挡又黄又爽免费网站 | 国产偷倩在线播放| 国产一区精品| 国产偷倩在线播放| 国产一级在线| 国产va在线| 一区二区精品区| 日本视频二区| 超碰免费在线播放| 尤物网站在线| 国产免费av网站| 高潮白浆视频| 国产精品二线| 97中文字幕| 午夜影院在线| 久久久久久久久免费视频| 高清av中文在线字幕观看1| 九九热在线视频观看| 成人av小说网| 国产精品视频流白浆免费视频| 国产精彩视频在线观看免费蜜芽| 国产麻豆视频| 91精品国产高久久久久久五月天| 中文日本在线观看| 久草在线视频网| 国产一二三区在线视频| 国产超碰在线| 青青在线视频| 国产视频你懂的| av在线免费播放网站| 国产精品一区二区三区高清在线| 国产精品视频二区三区| 免费a级在线播放| 91九色在线看| 国产三级av在线| 麻豆精品免费视频入口| 在线a人片免费观看视频| 尤物视频在线观看| 欧美性受xxxx免费视频|