新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → 递归算法---vc版 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 6020 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 递归算法---vc版 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 递归算法---vc版

    现有一路径数据,已知路径上有2点,求从起点到终点的最短路径.并保存最短路径的数据,即(从起点到终点所经过的节点和通过节点的方向).
    路径节点数据结构如下:
    typedef struct tagPathNode           
    {
    int pos_row;          //current node row in the map
    int pos_column;       //current node column in the map
    int left_step;        //==0:left no relate node,!=0:left
                                   //relate node and distance is left_step.
    int right_step;       
    int up_step;          
    int down_step;        
    }PathNode;


    问题描述

    给定一个带权有向图 G=(V,E) ,其中每条边的权是一个非负实数。
    另外,还给定 V 中的一个项点,称为源。
    现在我们要计算从源到所有其他各项点的最短路径长度。
    这里的长度是指路上各边权之和。
    这个问题通常称为单源最短路径问题。


    算法基本思想

    Dijkstra算法是解单源最短路径问题的一个贪心算法。
    其基本思想是,设置一个基点集合 S ,并不断地作贪心
    选择来扩充这个集合。
    一个项点属于集合 S 当且仅当从源到该项点的最短路
    径长度已知。
    初始时,S中仅含有源。设 u 是 G 的某一个项点,
    我们把从源到 u 且中间只有经过 S 中项点的路称为
    从源到 u 的特殊路径,并且数组 dist 来记录当前每个
    项点所对应的最短特殊路径长度。
    Dijkstra算法每次从 V-S 中取出具有最短特殊路径长度
    的项点 u ,将 u 添加到 S 中,同时对数组 dist 作必要
    的修改。


    源程序:

    ////////////////////////////////////////////////////////////
    // 功能:用 "贪心法" 解 "单源最短路径"
    ////////////////////////////////////////////////////////////


    ////////////////////////////////////////////////////////////
    // Graph.h
    #pragma once

    #define maxPoint 100

    class CGraph
    {
    public:
    CGraph(void);
    ~CGraph(void);

    bool SetGraph( double g[maxPoint][maxPoint] , int startPoint , int size );
    bool Dijkstra();
    void Display();
    int GetStartPoint();
    double GetBestWay( int dest , int path[] , int &pathLen );
    private:
    //标志当前图是否已经求解
    bool solved;
    //当前图布局
    double graph[maxPoint][maxPoint];
    //地图大小
    int size;
    //起点
    int startPoint;
    //当前图的解
    double dist[maxPoint];
    int prev[maxPoint];
    };

    ////////////////////////////////////////////////////////////
    // Graph.cpp
    #include "StdAfx.h"
    #include ".\graph.h"

    CGraph::CGraph(void)
    {
    for( int i = 0 ; i < maxPoint ; i++ )
    {
      for( int j = 0 ; j < maxPoint ; j++ )
       graph[i][j] = -1;
    }
    startPoint = -1;
    size = -1;
    //当前图还没有求解
    solved = false;
    }

    CGraph::~CGraph(void)
    {
    }
    //
    //
    bool CGraph::SetGraph( double g[maxPoint][maxPoint] , int startPoint , int size )
    {
    for( int i = 0 ; i < size ; i++ )
    {
      for( int j = 0 ; j < size ; j++ )
       graph[i][j] = g[i][j];
    }
    this->startPoint = startPoint;
    this->size = size;
    solved = false;

    Dijkstra();
    return true;
    }
    //
    //
    bool CGraph::Dijkstra()
    {
    bool s[maxPoint];
    for( int j = 0 ; j < size ; j++ )
    {
      dist[j] = graph[startPoint][j];
      s[j] = false;
      //dist[i]<0,表示没有路径连接 结点startPoint 与 结点j
      if( dist[j] < 0 )
       prev[j] = 0;
      else
       prev[j] = startPoint;
    }
    //从起点出发
    dist[startPoint] = 0;
    s[startPoint] = true;
    for( int i = 0 ; i < size ; i++ )
    {
      double temp;
      int u = startPoint;
      bool flag = false;
      for( int j = 0 ; j < size ; j++ )
      {
       if( !s[j] )
       {
        //如果不是第一次比较,temp u,都已经赋值,则
        if( flag )
        {
         if( dist[j] > 0 && dist[j] < temp )
         {
          u = j;
          temp = dist[j];
         }
        }
        else
        {
         u = j;
         temp = dist[j];
         flag = true;
        }
       }
      }
      s[u] = true;
      for( int j = 0 ; j < size ; j++ )
      {
       if( !s[j] && graph[u][j] > 0 )
       {
        double newDist = dist[u] + graph[u][j];
        if( dist[j] < 0 || newDist < dist[j] )
        {
         dist[j] = newDist;
         prev[j] = u;
        }
       }
      }
    }
    //标记当前问题已经解决
    solved = true;
    return true;
    }
    //
    //
    void CGraph::Display()
    {
    printf( "当前地图的邻接矩阵\n" );
    for( int i = 0 ; i < size ; i++ )
    {
      for( int j = 0 ; j < size ; j++ )
      {
       printf( "%5.f" , graph[i][j] );
      }
      printf( "\n" );
    }
    }
    //
    //
    double CGraph::GetBestWay( int dest , int path[] , int &pathLen )
    {
    int p = dest;
    int theway[maxPoint];
    int len = 0;
    while( p != startPoint )
    {
      theway[len] = p;
      p = prev[p];
      len++;
    }
    theway[len] = startPoint;
    len++;
    for( int i = 0 , j = len - 1 ; i < len ; i++ , j-- )
      path[i] = theway[j];
    pathLen = len;
    return dist[dest];
    }
    //
    //
    int CGraph::GetStartPoint()
    {
    return startPoint;
    }
    //


    ////////////////////////////////////////////////////////////
    // Dijkstra.cpp : 定义控制台应用程序的入口点。
    //

    #include "stdafx.h"
    #include "conio.h"
    #include "Graph.h"

    int _tmain(int argc, _TCHAR* argv[])
    {
    double graph[][maxPoint] =
    {
      { 1 , 10 , -1 , 30 , 100 } ,
      { -1 , 0 , 50 , -1 , -1 } ,
      { -1 , -1 , 0 , -1 , 10 } ,
      { -1 , -1 , 20 , 0 , 60 } ,
      { -1 , -1 , -1 , -1 , -1 }
    };
    int size = 5;
    int start = 0;
    int dest = 1;
    int pathlen;
    int path[maxPoint];
    double dist;

    CGraph g;
    g.SetGraph( graph , start , size );
    g.Display();
    printf( "----------------------------------------\n" );
    for( dest = 0 ; dest < size ; dest++ )
    {
      dist = g.GetBestWay( dest , path , pathlen );

      printf( "从 %d 到 %d 的最短路径长 %.f\n" , g.GetStartPoint() , dest , dist );
      printf( "所经结点为:\n" );
      for( int i = 0 ; i < pathlen ; i++ )
       printf( "%3d" , path[i] );
      printf( "\n----------------------------------------\n" );
    }
    getch();
    return 0;
    }


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/1/17 15:31:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客2
    发贴心情 
    单源最短路径bellman-ford算法:

    求的是arc数组中存储的第一个顶点到其他顶点的最短路径,结果存在dis数组中。

    #i nclude <stdio.h>
    #i nclude <malloc.h>

    #define MAX 100
    #define MAXNUM 10000000

    typedef struct graphnode
    {
    int vexnum;
    int arcnum;
    int gra[MAX][MAX];
    }Graph;

    int dis[MAX];
    int arc[MAX][MAX];

    void bellman(Graph *g);

    int main()
    {
    int i,j;
    Graph *G;
    G=(Graph *)malloc(sizeof(Graph));
    printf("vexnum:\n");
    scanf("%d",&G->vexnum);
    printf("arcnum:\n");
    scanf("%d",&G->arcnum);
    printf("graph:\n");
    for(i=0;i<G->vexnum;i++)
      for(j=0;j<G->vexnum;j++)
       scanf("%d",&G->gra[i][j]);
    for(i=0;i<G->arcnum;i++)
    {
      printf("the %dth arc:\n");
      scanf("%d%d",&arc[i][0],&arc[i][1]);
    }
    bellman(G);
    return 0;
    }


    void bellman(Graph *G)
    {
    int i,j;
    bool sign;
    for(i=0;i<G->vexnum;i++)
      dis[i]=MAXNUM;
    dis[1]=0;
    sign=true;
    for(i=1;i<G->vexnum;i++)
    {
      sign=false;
      for(j=0;j<G->arcnum;j++)
      {
       if(dis[arc[j][0]]<MAXNUM && dis[arc[j][1]]&gt;dis[arc[j][0]]+G->gra[arc[j][0]][arc[j][1]])
       {
        dis[arc[j][1]]=dis[arc[j][0]]+G->gra[arc[j][0]][arc[j][1]];
        sign=true;
       }
      }
    }
    return;
    }

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/1/17 15:33:00
     
     一分之千 帅哥哟,离线,有人找我吗?射手座1984-11-30
      
      
      威望:1
      等级:研一(随老板参加了WWW大会还和Tim Berners-Lee合了影^_^)
      文章:632
      积分:4379
      门派:XML.ORG.CN
      注册:2006/12/31

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给一分之千发送一个短消息 把一分之千加入好友 查看一分之千的个人资料 搜索一分之千在『 C/C++编程思想 』的所有贴子 引用回复这个贴子 回复这个贴子 查看一分之千的博客3
    发贴心情 
    这个挺好的,谢楼主分享~记下了

    ----------------------------------------------
    越学越无知

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/1/18 12:25:00
     
     GoogleAdSense射手座1984-11-30
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/23 1:25:32

    本主题贴数3,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    108.887ms