首页 范文大全 古典文学 职场知识 中国文学 公文书信 外国名著 寓言童话 百家讲坛 散文/诗歌 美文欣赏 礼仪知识 民俗风情
  • 工作总结
  • 工作计划
  • 心得体会
  • 竞聘演讲
  • 会议发言
  • 爱国演讲
  • 就职演说
  • 开业开幕
  • 思想学习
  • 征文演讲
  • 经验材料
  • 述职报告
  • 调研报告
  • 工作汇报
  • 年终总结
  • 申报材料
  • 学习体会
  • 企划方案
  • 活动方案
  • 技巧经验
  • 模板范例
  • 思想宣传
  • 经济工作
  • 工作报告
  • 组织人事
  • 反腐倡廉
  • 慰问贺电
  • 先进事迹
  • 思想汇报
  • 入党申请书
  • 党会发言
  • 先进性教育
  • 入团申请书
  • 个人简历
  • 演讲稿
  • 调查报告
  • 实习报告
  • 和谐社会
  • 观后感
  • 读后感
  • 作文范文
  • 自我鉴定
  • 讲话稿
  • 自查报告
  • 人工智能课程报告--分别用宽度优先、深度优先、贪婪算法和A_算法求解“罗马利亚度假问题”

    时间:2021-02-28 12:05:13 来源:蒲公英阅读网 本文已影响 蒲公英阅读网手机站

    相关热词搜索:算法 优先 罗马

    人工智能课程报告--分别用宽度优先、深度优先、贪婪算法和A_算法求解“罗马利亚度假问题” 本文关键词:算法,优先,罗马,求解,人工智能

    人工智能课程报告--分别用宽度优先、深度优先、贪婪算法和A_算法求解“罗马利亚度假问题” 本文简介:人工智能课程报告课程:人工智能实验报告班级:191121班学号:20121004362学生姓名:李华勇指导教师:赵曼2014年11月目录一、罗马利亚度假问题31.问题描述32.数据结构42.1广度优先算法42.2深度优先算法42.3贪婪算法42.4A*算法43.算法思想53.1广度优先搜索算法53.

    人工智能课程报告--分别用宽度优先、深度优先、贪婪算法和A_算法求解“罗马利亚度假问题” 本文内容:

    人工智能课程报告

    程:

    人工智能实验报告

    级:

    191121班

    号:

    20121004362

    学生姓名:

    指导教师:

    2014年11月

    目录

    一、罗马利亚度假问题3

    1.

    问题描述3

    2.

    数据结构4

    2.1

    广度优先算法4

    2.2

    深度优先算法4

    2.3

    贪婪算法4

    2.4

    A*算法4

    3.

    算法思想5

    3.1

    广度优先搜索算法5

    3.2

    深度优先搜索算法5

    3.3

    贪婪算法6

    3.4

    A*算法6

    4.

    运行结果7

    5.

    比较讨论8

    6.

    主要代码8

    二、N皇后问题13

    1.问题描述13

    2.数据结构13

    2.1

    回溯法(递归)13

    2.2

    GA算法13

    2.3

    CSP的最小冲突法13

    3.算法思想14

    3.1

    回溯法(递归)14

    3.2

    CSP的最小冲突法14

    3.3

    GA算法15

    4.运行结果16

    5.比较讨论17

    6.主要代码18

    一、罗马利亚度假问题

    题目:

    分别用宽度优先、深度优先、贪婪算法和A*算法求解“罗马利亚度假问题”。

    要求:

    分别用文件存储地图和启发函数表,用生成节点数比较几种算法在问题求解时的效率,并列表给出结果。

    1.

    问题描述

    从文件中读取图和启发函数,分别用广度优先、深度优先、贪婪算法、A*算法得到从起始点Arad到目标点Bucharest的一条路径,即为罗马尼亚问题的一个解。在求解的过程中记录生成扩展节点的个数(用于比较几种算法的优劣),用堆栈记录DepthFSearch和BroadFSearch的路径。

    2.

    数据结构

    分别使用了图结构,顺序队列,顺序表以及堆栈。对于每一个图中的结点,定义了一个结构体HeuristicG,结构体中包含结点的名称以及对应的启发函数值。

    typedef

    struct{

    char

    G[20];

    int

    value;

    }HeuristicG;

    typedef

    struct

    //图结构:

    typedef

    struct

    //链表

    {

    {

    SeqList

    Vertices;

    string

    list[20];

    int

    edge[20][20];

    int

    size;

    int

    numedge;

    }SeqList;

    }AdjMGraph;

    typedef

    struct

    //队列

    typedef

    struct

    //栈

    {int

    queue[20];

    {

    int

    rear;

    int

    stack[20];

    int

    front;

    int

    top;

    int

    count;

    }SeqStack;

    }SeqCQueue;

    2.1

    广度优先算法

    使用了数据结构中的图、队列和堆栈。

    2.2

    深度优先算法

    使用了数据结构中的图和堆栈。

    2.3

    贪婪算法

    使用了数据结构中的图。

    2.4

    A*算法

    使用了数据结构中的图。

    3.

    算法思想

    3.1

    广度优先搜索算法

    void

    BF_Search(AdjMGraph

    G,HeuristicG

    data[],int

    v0,int

    vg,intExpand,int

    count,int

    visited[],int

    BFS_path[])

    v0---起始节点

    vg---目标节点

    Expand---返回扩展结点数

    count---返回路径结点数

    BFS_path[]---存储路径信息

    G、data[]---用来读取图的各种信息

    visited[]---用来存储节点是否已经被访问的信息

    广度优先搜索是分层搜索的过程,广度优先搜索算法思想是用一个队列来保存访问过的顶点的顺序,以便按顺序访问这些顶点的邻接顶点,并把这些邻接顶点依次入栈。在函数中我还创建了两个栈,SeqStack

    SaveQ,LineSave,SaveQ将出队列的节点全部进栈,LineSave用于保存路径。广度优先搜索算法如下:

    1)

    访问顶点v0并标记v0已被访问,把v0输出到屏幕。

    2)

    顶点v0入队列。

    3)

    若队列非空,则继续执行,否则算法结束。

    4)

    出队列取得队头顶点u,并把u入SaveQ栈。

    5)

    查找顶点u的第一个邻接顶点w。

    6)

    如果w

    =

    vg,即找到目标节点,算法结束。

    7)

    若顶点u的邻接顶点w不存在,则转到步骤3),否则循环执行:

    (a)若顶点w尚未被访问,则访问顶点w并标记w为已访问;

    (b)顶点w入队列,Expand++;

    (c)查找顶点u的w邻接顶点后的下一个邻接顶点w,转到步骤7)。

    广度优先搜索起始节点到目标节点的路径的算法是:

    1)

    把顶点vg以及vg的父节点u入栈。

    2)

    把SaveQ栈顶元素出栈到u,当SaveQ非空是执行以下步骤:

    (a)把SaveQ栈顶元素出栈到u

    (b)取LineSave栈顶元素给y。

    (c)如果u和y没有相同的父亲,没被访问过,并且之间有边则保存路

    径,把u压入LineSave栈。

    3.2

    深度优先搜索算法

    void

    DF_Search(AdjMGraph

    G,SeqStack

    S,HeuristicG

    data[],int

    Expand,int

    v0,int

    vg,int

    visited[])

    v0---起始节点

    vg---目标节点

    Expand---返回扩展结点数

    SeqStack

    S---用堆栈存储路径信息

    visited[]---存储路径是否被访问的信息

    G、data[]---用来读取图的各种信息

    深度优先搜索的算法思想是用栈来保存已经访问过的节点,递归找该节点的第一个邻接顶点并把把顶点入栈,直到找不到顶点的邻接顶点为止,然后回溯,找该顶点父顶点的下一个邻接顶点。

    使用深度优先搜索算法,每次都在访问完当前顶点后首先访问当前顶点的第一个邻接顶点。深度优先搜索算法如下:

    1)

    访问顶点v并标记顶点v为以访问,把v0压入栈S,并在屏幕上输出v。

    2)

    如果v0!=

    -1,查找顶点v的第一个邻接顶点w

    3)

    若顶点v的邻接顶点w存在且为被访问,则继续执行,否则算法结束。

    4)

    若果w

    =

    vg,即找到目标节点,算法结束。

    5)

    弹出S栈顶元素。

    6)

    查找顶点v的w邻接顶点的下一个邻接顶点w,转到步骤3)。

    3.3

    贪婪算法

    void

    Greedy_Search(AdjMGraph

    G,HeuristicG

    data[],int

    v0,int

    vg,intExpand,int

    visited[])

    v0---起始节点

    vg---目标节点

    Expand---返回扩展结点数

    G、data[]---用来读取图的各种信息

    贪心算法思想是找到当前顶点的所有邻接顶点中h(x)值最小的邻接顶点,并把该顶点设置为下一个起始节点,递归直到找到目标节点。算法如下:

    1)

    访问v0,并将v0设为以访问,把v0输出到屏幕。

    2)

    如果v0

    =

    vg,即找到目标节点,算法结束。

    3)

    找到v0的所有邻接顶点,并比较邻接顶点的h(x)值,把h(x)最小

    的邻接顶点w,把w设置为起始顶点v0,转到步骤1)。

    3.4

    A*算法

    void

    A_Search(AdjMGraph

    G,HeuristicG

    data[],int

    v0,int

    vg,int

    distance,intExpand,int

    visited[])

    v0---起始节点

    vg---目标节点

    distance---用来保存已经过路径值

    Expand---返回扩展结点数

    G、data[]---用来读取图的各种信息

    A*算法思想是找到起始节点v0的所有邻接顶点,比较所有邻接顶点的fx值(fx

    =

    到v0已经经过路径值+v0到邻接顶点w的边的路径值distance+邻接顶点w的hx值),找到fx最小的邻接顶点w作为下一个起始顶点v0,同时更新距离diatance

    =

    diatance

    +

    v0到w边的路径值,直到找到目标节点。算法如下:

    1)访问v0,并将v0设为以访问,把v0输出到屏幕。

    2)如果v0

    =

    vg,即找到目标节点,算法结束。

    3)找到v0的所有邻接顶点w,并比较所有邻接顶点的fx值,

    fx=ditance+v0到w的距离+w的启发函数值,找到fx最小的邻接顶点w

    令v0

    =

    w,更新distance

    =

    distance

    +

    edge[v0][w],转到步骤1)。

    4.

    运行结果

    深度优先搜索

    宽度优先搜索

    A*算法

    贪婪算法

    扩展节点数

    12

    11

    5

    4

    路径节点数

    5

    4

    5

    4

    5.

    比较讨论

    从运行结果中可以看出,在搜索的过程中:

    DFS算法扩展结点数为12

    BFS算法扩展结点数为11

    A*算法扩展结点数为5

    贪婪算法扩展结点数为4

    所以在求解该问题时,贪婪算法的效率最高,其次是A*算法,然后是BFS算法,最后是DFS算法。但是贪婪算法和A*算法生成的节点数依赖于启发函数的值,因此虽然对于本题来说贪婪算法和A*算法的效率很高,但是不能说在所有搜索问题中贪婪算法和A*算法的效率都是最高的。

    6.

    主要代码

    1)深度优先搜索

    //

    v0---起始节点

    vg---目标节点

    //

    //

    Expand---返回扩展结点数

    //

    //

    SeqStack

    S---用堆栈存储路径信息

    //

    //

    visited[]---存储路径访问信息

    //

    //

    G、data[]---用来读取图的各种信

    //

    void

    DF_Search(AdjMGraph

    G,SeqStack

    S,HeuristicG

    data[],int

    Expand,int

    v0,int

    vg,int

    visited[])

    {

    int

    t,w;

    //用于寻找目标节点

    static

    int

    flag

    =

    0;

    static

    int

    DFS_flag

    =

    0;

    //标志位---找到目标节点后退出递归

    StackPush(S,v0);

    //首先将起始节点入栈

    flag++;

    printf(“%s-->

    “,data[v0].G);

    visited[v0]=1;

    if(v0

    !=

    -1)

    w=GetFirstVex(G,v0,visited);

    //获取第一个临接点

    while(!DFS_flagExpand

    =

    flag;

    break;

    }

    if(!

    visited[w]

    if(DFS_flag)

    break;

    StackPop(S,w

    =

    GetNextVex(G,v0,w,visited);

    }

    }

    2)宽度优先搜索

    //

    v0---起始节点

    vg---目标节点

    //

    //

    Expand---返回扩展结点数

    //

    //

    count---返回路径结点数

    //

    //

    BFS_path[]---存储路径信息

    //

    //

    G、data[]---用来读取图的各种信息

    //

    void

    BF_Search(AdjMGraph

    G,HeuristicG

    data[],int

    v0,int

    vg,intExpand,int

    count,int

    visited[],int

    BFS_path[])

    {

    int

    u,w,y,SumExpand=1,i=0;

    SeqCQueue

    Q;

    SeqStack

    SaveQ,LineSave;

    //SaveQ将出队列的节点全部进栈,LineSave用于保存路径

    StackInitiate(

    StackInitiate(

    printf(“%s-->

    “,data[v0].G);

    visited[v0]=1;

    QueueInitiate(

    QueueAppend(

    //首先将起始节点入队列

    while(QueenNotEmpty(Q))

    {

    QueueDelete(

    StackPush(

    //将每一个出队列的结点进行保存

    w

    =

    GetFirstVex(G,u,visited);

    if(w

    ==

    vg)

    {

    SumExpand++;Expand

    =

    SumExpand;

    break;

    }

    while(w

    !=

    -1)

    {

    if(

    !visited[w])

    {

    printf(“%s-->

    “,data[w].G);

    visited[w]

    =

    1;

    QueueAppend(

    SumExpand++;

    }

    w

    =

    GetNextVex(G,u,w,visited);

    }

    }

    StackPush(//此时w为目标节点

    StackPush(

    //此时u为w的父节点

    StackPop(

    while(StackNotEmpty(SaveQ))

    {

    StackPop(

    StackTop(LineSave,if

    (

    Edge(G,u,y)==1

    }

    while(StackNotEmpty(LineSave))

    {

    StackPop(

    BFS_path[i++]=u;

    count

    =

    i;

    }

    }

    3)A*

    搜索

    //

    v0---起始节点

    vg---目标节点

    //

    //

    distance---用来保存已经过路径值

    //

    //

    Expand---返回扩展结点数

    //

    //

    G、data[]---用来读取图的各种信息

    //

    void

    A_Search(AdjMGraph

    G,HeuristicG

    data[],int

    v0,int

    vg,int

    distance,intExpand,int

    visited[])

    {

    int

    i,u,temp=10000;

    static

    int

    path_num

    =

    0;

    static

    int

    A_Search_flag

    =

    0;

    //标志位---找到目标节点后退出递归

    static

    int

    fx

    =

    0;

    if(v0

    ==

    2)

    printf(“%s“,data[v0].G);

    else

    printf(“%s-->“,data[v0].G);

    visited[v0]

    =

    1;

    path_num++;

    if(v0

    ==

    vg)

    {

    A_Search_flag

    =

    1;Expand

    =

    path_num;

    return;

    }

    for(i=0;i“,data[v0].G);

    visited[v0]

    =

    1;

    path_num++;

    if(v0

    ==

    vg)

    {

    G_Search_flag

    =

    1;Expand

    =

    path_num;

    return;

    }

    for(i=0;i30时,回溯法已经很难找到解,运行时超过了20s。

    当N>50时,GA算法运行时间开始逐渐变长,当N>90时运行时间已经超过了60s。

    当N=200时,CSP的最小冲突法时间才仅为7.699s。

    对比可知当N较大时,CSP的最小冲突法的效率最高,GA算法次之,回溯法在求解大的皇后数是效率最低。

    对于回溯法的时间复杂度,最好情况是O(n^2),最坏情况是O(n!)。

    对于CSP的最小冲突法的时间复杂度,最好的情况是O(n^3),最坏的情况是O(m*n^3)。

    对于GA算法的时间复杂度,最好情况是O(n^3),最坏的情况是O(p*n^3)。

    6.主要代码

    1、回溯法:

    void

    backtrack(int

    column)

    //以列作为判断点

    {

    int

    row,i,j;

    double

    secs,ms;

    BK_stop

    =clock();

    ms

    =

    (double)(BK_stop

    -

    BK_start);

    if(ms>20000)

    //回溯法运行超过20s就退出

    {

    printf(“BackT_Queen

    Calculations

    took

    more

    than

    20

    seconds

    !/n“);

    exit(0);

    }

    if

    (

    column==BK_Q_num)

    {

    BK_end

    =

    clock

    ()

    ;

    secs

    =

    (double)(BK_end

    -

    BK_start)

    /

    CLOCKS_PER_SEC

    ;

    printf(“Back_Queen

    Calculations

    took

    %.3lf

    second%s./n“,secs,(secs

    eachFitness[i]

    eachFitness[worst])

    worst

    =

    i

    ;

    if(p->eachFitness[worst]

    ==

    GA_Q_num-1)

    return;

    baby

    =p

    ;

    for

    (i

    =

    0

    ;

    i

    p->unitFitness

    ||

    (double)rand()

    /

    RAND_MAX

    slice)

    {

    selection

    =

    i;

    break;

    }

    }

    return

    selection;

    }

    //

    杂交

    father,mother,

    产生的子代保存在

    baby中

    void

    CrossOverFM

    (Population

    father,Population

    mother,Populationbaby)

    {

    int

    flag[MAX_QUEENS]

    ;

    int

    pos1,pos2,tmp

    ;

    int

    i,j

    ;

    //

    随机产生两个基因断点

    do

    {

    pos1

    =

    rand()

    %

    GA_Q_num

    ;

    pos2

    =

    rand()

    %

    GA_Q_num

    ;

    }

    while

    (pos1

    ==

    pos2)

    ;

    if

    (pos1

    >

    pos2)

    {

    tmp

    =

    pos1

    ;

    pos1

    =

    pos2

    ;

    pos2

    =

    tmp;

    }

    for

    (j

    =

    0

    ;

    j

    pos2)

    {

    while

    (flag[mother.queen[j]])

    j++

    ;

    //保证每个皇后都不在同一行

    baby->queen[i]

    =

    mother.queen[j]

    ;

    j

    ++

    ;

    }

    else

    baby->queen[i]

    =

    father.queen[i]

    ;

    }

    UpdateFitnessScore

    (baby)

    ;

    }

    //

    杂交产生子代

    void

    CrossOver

    ()

    {

    int

    i

    ;

    int

    father,mother

    ;

    Population

    p[30

    +

    MAX_QUEENS

    /

    10]

    ;

    int

    count

    ;

    //

    计算总共的

    Fitness,

    用于轮盘赌局规则时候的选择

    m_totFitness

    =

    0

    ;

    for

    (i

    =

    0

    ;

    i

    <

    m_size

    ;

    i++)

    m_totFitness

    +=

    m_population[i].unitFitness

    ;

    for

    (count

    =

    0

    ;

    count

    <

    m_size

    -

    2

    ;

    count++)

    {

    father

    =

    RouletteWheelSelection

    ()

    ;

    mother

    =

    RouletteWheelSelection

    ()

    ;

    CrossOverFM

    (m_population[father],m_population[mother],//

    杂交,后代保存

    }

    //

    将结果覆盖回原种群,加上原种群中适应度最高的两个个体组成新的进化后的种群

    for

    (count

    =

    0

    ;

    count

    <

    m_size

    -

    2

    ;

    count++)

    m_population[count+2]

    =

    p[count]

    ;

    }

    31

    • 范文大全
    • 职场知识
    • 精美散文
    • 名著
    • 讲坛
    • 诗歌
    • 礼仪知识