关闭

编程的乐趣

标签: Dijkstra矩阵对角线复制
282人阅读 评论(0) 收藏 举报
分类:
#include "stdio.h"
#include  "stdbool.h"
#define   NUM   5
#define    INF  9999

bool is_all_in(int set[],int n);
void path0to(int v,int path0[]);
void dist0to(int v,int dist0[]);

struct stack{
    int a[100];
    int top;
            }

main()
{
int n;
n = NUM;
int ei[(NUM-1+1)*(NUM-1)/2]={16,2,8,INF,12,INF,5,3,4,9};
int E[NUM][NUM];
int i,j,k;
for(i=0;i<n;i++)
    E[i][i] = 0;
k=0;
for(i=0;i<n-1;i++)
    for(j=i+1;j<n;j++)
        E[i][j] = ei[k++];

for(j=0;j<n-1;j++)
    for(i=j+1;i<n;i++)
        E[i][j] = E[j][i];
printf("the edge matrix following\n\n");
for(i=0;i<n;i++)
    for(j=0;j<n;j++)
        if( j == n-1 )
            printf("%-4d\n\n",E[i][j]);
        else
            printf("%-4d ",E[i][j]);
int dist0[n];
int set[n];
for(i=0;i<n;i++)
    set[i] = 0;
for(i=0;i<n;i++)
    dist0[i] = E[0][i];
int path0[n];
for(i=0;i<n;i++)
    path0[i] = -1;
set[0] = 1;
path0[0] = 0;
while(!is_all_in(set,n))
    {
    int min;
    min = INF;
    k = 0;
    for(i=0;i<n;i++)
        if( dist0[i] < min && set[i] == 0 )
            {min = dist0[i];
             k = i;}
    set[k] = 1;
    for(j=0;j<n;j++)
            if( dist0[k]+E[k][j] < dist0[j] )
                {dist0[j] =dist0[k] + E[k][j];
                 path0[j] = k;}
    }
printf("the path state below\n\n");
for(i=0;i<n;i++)
    printf("%-2d ",i);
putchar('\n');
for(i=0;i<n;i++)
    printf("%-2d ",path0[i]);
putchar('\n');
dist0to(1,dist0);
path0to(1,path0);
}
bool is_all_in(int set[],int n)
{
    int i;
    for(i=0;i<n;i++)
        if( set[i] ==0 )
            return false;
    return true;

}
void path0to(int v,int path0[])
{
printf("the shortest path from 0 to %d is \n",v);
printf("%d ",0);
struct stack s;
s.top = -1;
while ( path0[v] != -1 )
   {s.a[++s.top] = v;
    v = path0[v];}
s.a[++s.top] = v;
while(s.top >= 0)
    printf("%d ",s.a[s.top--]);
}
void dist0to(int v,int dist0[])
{
printf("the shortest length from 0 to %d is \n%d\n",v,dist0[v]);
}

我首先贴了一段代码。给人的印象一定是很枯燥吧。映入眼帘的是字母和符号,和不知所云的相等不相等的关系式。
但是,如果你听了我下面的讲解。这段代码背后的意思是展现一个很有意思的图景和动态的过程。你就不会觉得那么枯燥了。

首先看这一段代码

int E[NUM][NUM];
int i,j,k;
for(i=0;i<n;i++)
    E[i][i] = 0;
它是建立一个矩阵。大小为NUM*NUM,也就是5*5。然后把对角线的元素设置为0。


再看这一段代码

k=0;
for(i=0;i<n-1;i++)
    for(j=i+1;j<n;j++)
        E[i][j] = ei[k++];
是在矩阵的上三角填充数字。


再看这一段代码

for(j=0;j<n-1;j++)
    for(i=j+1;i<n;i++)
        E[i][j] = E[j][i];
它体现的动态过程呢,是完成矩阵上三角元素关于对角线的对称镜像。就是,以对角线为对称轴,将上三角元素复制到对称的位置 上去。结果如下。


我只画出了E[1][4]对称到E[4][1]的箭头。其他类似。
那么这个矩阵又代表什么实际场景呢。它代表几个节点之间的连接路径的关系。


这种实际的节点网状联结关系,在计算机科学中抽象为如上的图。后面的代码实现的是寻找辐射状最短路径的迪杰斯特拉算法。更加动态,更加有意思。也不是一两句话能说清楚的。后面再说。
我这里想强调的是,写代码的时候,脑子里想的,一定是一个场景,在场景上发生的一个动态变化。那么编程就是一个搭建场景,制造变化的过程。这是一个创作的过程。充满了乐趣。
<未完待续>

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:49103次
    • 积分:1049
    • 等级:
    • 排名:千里之外
    • 原创:57篇
    • 转载:0篇
    • 译文:0篇
    • 评论:6条
    最新评论