算法设计与分析实验报告

时间:2024.4.20

《算法设计与分析》课程报告

课题名称:_________算法设计与分析__________

课题负责人名(学号):                     

同组成员名单(角色):                     

                                          

                                          

指导教师:                                

评阅成绩:                               

评阅意见:                                

                                          

                                          

提交报告时间:20##年  6月  12日

第二章 递归与分治策略

2-3 改写二分搜索算法

1.  问题描述:设a[0:n-1]是已排好序的数组。请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。

2.       分析与证明:设a[0:n-1]是已排好序的数组。请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相等,均为x在数组中的位置。

3.  代码实现:

template<class Type>

int BinarySearch(Type a[ ],const Type& x,int left,int right, int &i, int &j )

{

     while (left<=right){

        int mid = (left+right)/2;

        if (x == a[mid]) { i=j=mid; return 1; }

        if (x < a[mid]) right = mid-1;

            else left = mid+1;

        }

     i=right; j=left;//或i=left-1;j=left

     return 0;

}

5.问题:改写二分搜索算法,返回小于x的最大元素位置i和大于x的最小元素位置j。当找到与x同的元素时,i和j相同,均为x在数组中的位置

第三章 动态规划

3-5 编辑距离问题

1.  问题描述:设A和B是两个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括:

1)  删除一个字符;

2)  插入一个字符;

3)  将一个字符改为另一个字符。

将字符串A变换为字符串B所用的最少字符操作数称谓字符串A到B的编辑距离,记为d(A,B)。试设计一个有效算法,对任给的2个字符串A和B,计算出它们的编辑距离d(A,B)。

2.       分析与证明:

a.       开一个二维数组d[i][j]来记录a0-ai与b0-bj之间的编辑距离,要递推时,需要考虑对其中一个字符串的删除操作、插入操作和替换操作分别花费的开销,从中找出一个最小的开销即为所求

b.       具体算法:

c.        首先给定第一行和第一列,然后,每个值d[i,j]这样计算:d[i][j] = min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+(s1[i]==s2[j]?0:1));  

d.        最后一行,最后一列的那个值就是最小编辑距离

3. 代码实现:

#include <iostream>

#include <fstream.h>

#include <stdio.h>

#include <string.h>

int i,j;

char* s1 = new char[80];

char* s2 = new char[80];

int md[81][81]; 

int min(int a, int b, int c); 

int editDistance(int len1, int len2);   //最短编辑距离

void main() 

{

       fstream inDst;

       inDst.open("E:\\input.txt",ios::in,0);

    inDst>>s1; 

    inDst>>s2; 

       inDst.close();

      

       fstream outDst;

       outDst.open("E:\\output.txt",ios::app,0);

    outDst<<editDistance(strlen(s1), strlen(s2)); 

       outDst.close();

}

int min(int a, int b, int c) 

    int temp=(a<b) ? a : b; 

    return (temp<c) ? temp : c; 

}

 //最短编辑距离

int editDistance(int len1, int len2) 

{  

    //当某一个字符串为空时,最短编辑距离是另外一个字符串的长度。   

    for(i=0; i<=len1; i++)

       {

        md[i][0]=i;

       }

    for(j=0; j<=len2; j++)

       {

        md[0][j]=j;

       }

    for(i=1; i<=len1; i++) 

    { 

        for(j=1; j<=len2; j++) 

        { 

            int cost=(s1[i-1]==s2[j-1]) ? 0 : 1;       

            int delet=md[i-1][j]+1; 

                     int insert=md[i][j-1]+1; 

            int substit=md[i-1][j-1]+cost; 

            md[i][j]=min(delet, insert, substit); 

        } 

    } 

    return md[len1][len2]; 

4.  测试数据:

Input.txt

fxpimu

xwrs

运行结果:

Output.txt

   5

5复杂度分析:二重for循环复杂度为O(n^2)

第四章 贪心算法

4-9 汽车加油问题

1.  问题描述:一辆汽车加满油后可行驶nkm。旅途中有若干加油站。设计一个有效算法,指出应在哪些加油站停靠加油,使沿途加油次数最少。

2.  证明与分析:

① 解题思路:
    先判断是否有解,再对数组从1到k+1计算尽量往前走,直至不能走就+1,计算出最大

② 算法策略:贪心算法

③ 基本变量描述:
     data[]和数组a[]都是用来保存k+1个距离值,sum和total均用来记录最少加油次数,total=-1表无解

3.  代码实现:

#include<stdio.h>

#include<stdlib.h>

#include<iostream.h>

#include<fstream.h>

int CarInGas(int a[],int n,int k);

int main()

{

       int i,k,n,data[100],total;

       fstream rData;

       rData.open("E:\\input.txt",ios::in,0);

      

       rData>>n>>k;

       for(i=1;i<=k+1;i++)

       {

              rData>>data[i];

       }

       total = CarInGas(data,n,k);

       rData.close();

       fstream wData;

       wData.open("E:\\output.txt",ios::app,0);

       if(!wData)

       {

              cout<<"False to open file."<<endl;

       }

      

       if(total==-1)

       {

              cout<<"No solution!"<<endl;

              wData<<"No solution!"<<endl;

       }

       else

       {

              cout<<total<<endl;

              wData<<total<<endl;

       }

       wData.close();

       system("pause");

       return 0;

}

int CarInGas(int a[100],int n,int k)

{

       int i,sum=0,curDistan=0;

       for(i=1;i<=k+1;i++)

       {

              if(a[i]>n)

                     return -1;

       }

       for(i=1;i<=k+1;i++)

       {

              curDistan= a[i]+curDistan;

              if(curDistan>n)

              {

                     sum++;

                     curDistan=a[i];

              }

       }

       return sum;

}

4.  测试数据:

Input.txt

7 7

1 2 3 4 5 1 6 6

运行结果:

Output.txt

4

5.       复杂度分析:
        for(i=1;i<=k+1;i++)
           rData>>data[i];
        复杂度为:O(n)
       CarInGas(a,n,k)也为 O(n)
        两者互不嵌套,所以为O(n)

第五章 回溯法

5-13 工作分配问题

1.     问题描述:设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为Cij。试设计一个算法。为每一个人都分配1件不同的工作,并使总费用达到最小。

2.     分析与证明:

由于每个人都必须分配到工作,在这里可以建一个二维数组allot[i][j],用以表示i号工人完成j号工作所需的费用。给定一个循环,从第1个工人开始循环分配工作,直到所有工人都分配到。为第i个工人分配工作时,再循环检查每个工作是否已被分配,没有则分配给i号工人,否则检查下一个工作。可以用一个一维数组flag[j]来表示第j 号工作是否被分配,未分配则flag[j]=0,否则flag[j]=1。利用回溯思想,在工人循环结束后回到上一工人,取消此次分配的工作,而去分配下一工作直到可以分配为止。这样,一直回溯到第1个工人后,就能得到所有的可行解。在检查工作分配时,其实就是判断取得可行解时的二维数组的一下标都不相同,二下标同样不相同。

这样,得到了所有的可行解。为了得到最少的费用,即可行解中和最小的一个,故需要再定义一个全局变量cost表示最终的总费用,初始cost为allot[i][i]之和,即对角线费用相加。在所有工人分配完工作时,比较sumFare与cost的大小,如果sumFare小于cost,证明在回溯时找到了一个最优解,此时就把sumFare赋给cost。
    考虑到算法的复杂度,可以设计一个剪枝函数。就是在每次计算局部费用变量sumFare的值时,如果判断sumFare已经大于cost,就没必要再往下分配了,因为这时得到的解必然不是最优解。

3.     代码实现:

#include<iostream.h>

#include <fstream.h>

//using namespace std;

#include <stdlib.h>

int n;        

int cost=0;   //现行最小费用

int flag[100];     //工作是否被分配,“1”代表已分配

int allot[100][100];    //表示i号工人完成j号工作的费用

int WorkAllocation(int i,int sumFare);

int main()

{

       fstream rData;

       rData.open("E:\\input.txt",ios::in,0);

       rData>>n;

    for(int i=1;i<=n;i++)  

       {

              for(int j=1;j<=n;j++)

              {

                     rData>>allot[i][j];

                     flag[j] = 0; 

              }

              cost+=allot[i][i];   //对角线费用相加,用于剪枝

    }

       rData.close();

       fstream wData;

       wData.open("E:\\output.txt",ios::app,0);

       if (!wData)

       {

              cout<<"False to open file."<<endl;

       }

    wData<<WorkAllocation(1,0)<<endl;

       wData.close();

    system("pause");

    return 0;

}

int WorkAllocation(int i,int sumFare)

{

    if(i>n && sumFare<cost)       //大于cost则必定不是最优解,跳过

       {

              cost = sumFare;

              return 1;

    }

    if(sumFare<cost)

       {

              for(int j=1;j<=n;j++)

              {

                     if(flag[j] == 0)

                     { 

                            flag[j] = 1; 

                            WorkAllocation(i+1,sumFare+allot[i][j]); 

                            flag[j] = 0; 

                     }

              }

       }

       return cost;

}

4. 测试数据:

Input.txt

3

10 2 3

2 3 4

3 4 5

运行结果:

Output.txt

   9

5.复杂度分析:从main函数中的for循环中可以看出其算法复杂度为O(n^2)

第六章 分支限界法

6-6 n皇后问题

1. 问题描述:在n x n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n皇后问题等价于在n x n各的棋盘上放置n个皇后,任何两个皇后不放在同一行或者同一列或者同一斜线上。设计一个解n皇后问题的队列式分支限界法,计算在n x n个方格上放置彼此不受攻击的n个皇后的一个放置方案。

2. 分析与证明:题目要求我们只需要输出摆放皇后的一中解,所以在分支限界法时,每一种皇后的摆放即为一条分支,而遍历解空间相当于广度优先遍历树,因此只要将n个皇后摆放完成,便可以输出解,并不存在最优解的情况。

3. 代码实现:

#include <iostream>

#include <fstream>

#include <queue>

using namespace std;

fstream minput("D:\\input.txt"); 

fstream moutput("D:\\output.txt"); 

class Node

{

public: 

    Node(int n)

       { 

        t=0;

        this->n=n;

        loc = new int[n+1];

        for (int i=0;i<=n;++i)

        {

            loc[i]=0;

        } 

    } 

    Node(const Node &other)

       { 

        this->t=other.t; 

        this->n=other.n; 

        this->loc=new int[n+1]; 

        for (int i=0;i<=n;++i)

              { 

            this->loc[i]=other.loc[i]; 

        } 

    } 

    int t;

    int *loc;

    int n;

    bool checkNext(int next);

    void printQ();

};

bool Node::checkNext(int next)

{

    int i;

    for (i=1;i<=t;++i)

    {

        if (loc[i]==next)

        {

            return false;

        }

        if (loc[i]-next==t+1-i)

        {

            return false;

        }

        if (loc[i]-next==i-t-1)

        {

            return false;

              }

    }

    return true;

}

void Node::printQ()

{

    for (int i=1;i<=n;++i)

    {

        moutput<<loc[i]<<" ";

    }

    moutput<<endl;

}

class Queen

{

public:

    int n;

    int ansNum;

    Queen(int n){

        this->n=n;

        ansNum=0;

    }

    void ArrangQueen();

};

void Queen::ArrangQueen()

{

    queue<Node> Q;

    Node ini(n);

    Q.push(ini);

    while(!Q.empty())

       {

        Node father=Q.front();

        Q.pop();

        if (father.t==n)

        {

            father.printQ();

            ++ansNum;

                     break;

        }

        for (int i=1;i<=n;++i)

        {

            if (father.checkNext(i))

            {

                Node Child(father);

                ++Child.t;

                Child.loc[Child.t]=i;

                Q.push(Child);

            }

        }

    }

}

int main(void)

{

    int num;

    minput>>num;

    Queen Q(num); 

    Q.ArrangQueen();

    return 0;

}

4. 测试数据:

Input.txt

5

运行结果:

Output.txt

1 3 5 2 4

5.复杂度分析:递归调用for循环,算法复杂度为O(n!)

更多相关推荐:
算法设计与分析实验报告1

攀枝花学院实验报告实验名称算法设计与分析课程实验实验内容比较排序算法的效率实验日期20xx0326院系数学与计算机姓名吴永昊学号20xx10804043同组人指导老师银星成绩一目的与任务通过算法的程序实现和执行...

计算机算法与设计分析实验报告

计算机算法与设计分析实验报告班级姓名学号目录实验一分治与递归11基本递归算法12棋盘覆盖问题23二分搜索34实验小结5实验二动态规划算法51最长公共子序列问题52最大子段和问题73实验小结8实验三贪心算法81多...

算法设计与分析实验报告格式

算法设计与分析实验报告一实验名称统计数字问题评分实验日期年月日指导教师刘长松姓名刘飞初专业班级计算机0901学号10一实验要求1掌握算法的计算复杂性概念2掌握算法渐近复杂性的数学表述3掌握用C语言描述算法的方法...

算法设计与分析实验报告

算法分析与设计实验报告实验报告题目实验一递归与分治策略一实验目的1加深学生对分治法算法设计方法的基本思想基本步骤基本方法的理解与掌握2提高学生利用课堂所学知识解决实际问题的能力3提高学生综合应用所学知识解决实际...

算法设计与分析实验报告格式

算法设计与分析实验报告班级姓名学号20xx年11月18日目录实验一二分查找程序实现01页实验二棋盘覆盖问题04页实验三01背包问题的动态规划算法设计07页实验四背包问题的贪心算法10页指导教师对实验报告的评语成...

算法设计与分析试验报告

武汉理工大学学生实验报告书实验课程名称算法设计与分析开课学院计算机科学与技术学院指导老师姓名何九周学生姓名王鹏学生专业班级软件100420xx20xx学年第1学期实验课程名称算法设计与分析intmiddleif...

算法设计与分析实验报告

算法设计实验报告课程设计报告题目计算机算法基础实验报告课程名称专业班级学号姓名指导教师报告日期117算法设计实验报告计算机科学与技术学院目录一实验目的3二实验题目3三设计分析31生成最短路径问题设计分析32最优...

算法设计与分析实验报告

课程报告课程名称算法设计与分析专业名称计算机科学与技术学号姓名指导教师完成时间20xx年12月1目录一设计目的4二设计内容421整数背包问题简介422算法分析423最优解存在证明4三穷举法求解整数背包问题531...

《算法设计与分析》实验报告

算法设计与分析实验报告网络101李俊实验一分治与递归基本题一基本递归算法四程序清单includeltiostreamgtusingnamespacestdintqintnintmifnlt1mlt1return...

终稿- -算法设计与分析实验报告格式 3

算法设计与分析实验报告一实验名称统计数字问题评分实验日期年月日指导教师姓名专业班级学号20xx1一实验要求1掌握算法的计算复杂性概念2掌握算法渐近复杂性的数学表述3掌握用C语言描述算法的方法4实现具体的编程与上...

-算法设计与分析实验报告格式 2

算法设计与分析实验报告一实验名称统计数字问题评分实验日期年月日指导教师刘长松姓名兜兜专业班级计算机10学号20xx一实验要求1掌握算法的计算复杂性概念2掌握算法渐近复杂性的数学表述3掌握用C语言描述算法的方法4...

算法分析实验报告

实验一最大公约数问题用连续整除法求最大公约数includeltstdiohgtintgcdintmintnintminifngtmminmelseminnforminnmingt1minifmmin0ampam...

算法设计与分析实验报告(40篇)