电网建设:预算控制与造价计算

课程设计目录

哈夫曼编码/译码器

教室数据管理


文章目录

  • 一、设计任务及要求
  • 二、设计导向
  • 1. 设计目的
  • 2. 设计课题
  • 3. 总体设计方案
  • 4. 详细设计
  • 5. 系统测试与结果分析
  • 三、课程设计总结
  • 四、附录:源程序清单

  • 一、设计任务及要求

    假设一个城市有n个小区,要实现n个小区之间的电网都能够相互接通,构造这个城市n个小区之间的电网,使总工程造价最低。请设计一个能满足要求的造价方案。

    最小生成树总体功能要求:在 n 个城市之间建设网络,只需保证连通即可,求最经济的架设方法,存储结构采用多种,求解算法多种。

    基本功能:在 n 个城市之间建设网络,只需要架设 n-1 条线路,建立最小生成树即可实现最经济的架设方法,程序可利用克鲁斯卡尔算法或 prim 算法生成最小生成树。

    二、设计导向

    1. 设计目的

    1. 巩固和加深对数据结构课程所学知识的理解,了解并掌握数据结构与算法的设计方法;
    2. 初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;
    3. 提高综合运用所学的理论知识和方法,独立分析和解决问题的能力;
    4. 训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风;
    5. 培养查阅资料,独立思考问题的能力。

    2. 设计课题

    在 n 个城市之间建设网络,只需保证连通即可,求最经济的架设方法,存储结构采用多种,求解算法多种。在 n 个城市之间建设网络,只需要架设 n-1 条线路,建立最小生成树即可实现最经济的架设方法,程序可利用克鲁斯卡尔算法或 prim 算法生成最小生成树。

    3. 总体设计方案

    在每个小区之间都可以设置一条电网线路,相应的都要付出一点经济代价。n个小区之间最多可以有n(n-1)/2条线路,选择其中的n-1条使总的耗费最少。可以用连通网来表示n个城市之间以及n个城市之间可能设置的电网线路,其中网的顶点表示小区,边表示两个小区之间的线路,赋予边的权值表示相应的代价。对于n个顶点的连通网可以建立许多不同的生成树,每一颗生成树都可以是一个电路网。现在,我们要选择总耗费最少的生成树,就是构造连通网的最小代价生成树的问题,一颗生成树的代价就是树上各边的代价之和。

    设G=(V, E)是具有n个顶点的网络,T=(U, TE)为G的最小生成树,U是T的顶点集合,TE是T的边集合。Prim算法的基本思想是:首先从集合V中任取一顶点(例如去顶点v0)放入集合U中,这时U={ v0},TE=NULL。然后找出所有一个顶点在集合U里,另一个顶点在集合V-U里的边,使权(u, v)(u∈U, v∈V-U)最小,将该边放入TE,并将顶点v加入集合U。重复上诉操作直到U=V为止。这时TE中有n-1条边,T=(U, TE)就是G的一颗最小生成树。

    4. 详细设计

    (1)数据类型的定义

    typedef struct
    {
        char D[MAXNUM];
        int arcs[MAXNUM][MAXNUM];
        int vexnum, arcnum;//顶点数和边数
    }AMGraph;
    struct//辅助数组的定义
    {
        char begin;
        char end;
        int weight;
    }FuZhu[(MAXNUM * (MAXNUM - 1)) / 2];
    int Vexset[MAXNUM];
    

    (2)创建无向网G

    void CreateG(AMGraph& G)//创建无向网G
    {
        int i, j, t;
        cout << "请输入城市小区的总个数和小区之间的总电路数:";
        cin >> G.vexnum >> G.arcnum;
        cout << endl;
        cout << "输入小区的名称:如a" << endl;
        for (i = 0; i < G.vexnum; i++)
        {
            cout << "请输入第" << (i + 1) << "个小区的名称:";
            cin >> G.D[i];
        }
        cout << endl;
        for (i = 0; i < G.vexnum; i++)
        {
            for (j = 0; j < G.vexnum; j++)
                G.arcs[i][j] = MAXINT;
        }
        cout << "请输入电路的起点,终点和造价,例如a b 4" << endl;
        for (t = 0; t < G.arcnum; t++)
        {
            char x, y;
            int z;
            cout << "请输入第" << (t + 1) << "条电路的起点终点和造价:";
            cin >> x >> y >> z;
            i = LocateVex(G, x);
            j = LocateVex(G, y);
            G.arcs[i][j] = z;
            G.arcs[j][i] = z;
            FuZhu[t].begin = x;
            FuZhu[t].end = y;
            FuZhu[t].weight = z;
        }
    }
    

    (3)prim算法
    假设G=(V,E)是连通的,TE是G上最小生成树中边的集合。算法从U={u0}(u0∈V)、TE={}开始。重复执行下列操作:
    在所有u∈U,v∈V-U的边(u,v)∈E中找一条权值最小的边(u0,v0)并入集合TE中,同时v0并入U,直到V=U为止。此时,TE中必有n-1条边,T=(V,TE)为G的最小生成树。

    Prim算法的核心:始终保持TE中的边集构成一棵生成树。

    5. 系统测试与结果分析




    三、课程设计总结

    我们课程设计的主要就是最小生成树普利姆算法的实现,在这次实践中遇到了各种问题,碰到问题有时总是百思不得其解。

    在最开始,分析题目时知道本题就是书上最小生成树的问题,于是将书上内容复习一遍。在程序完成 后也出现过多次问题,比如printf后面的中文提示多次错误,另外最后的输出结果也出现问题,输出的点与实际相差1,最后修改程序的普里姆算法段完成。

    除此之外,通过本次课程设计巩固了课本的基本知识,熟练运用课程知识。提高我们组织数据及编写程序的能力,使我们能够根据问题要求和数据对象的特性,学会数据组织的方法,把现实世界中的问题在计算机内部表示出来并用软件解决问题,本次实验大大提高了我们对编程的爱好。

    四、附录:源程序清单

    #include <iostream>
    using namespace std;
    #define MAXNUM 100
    #define MAXINT 1000
    typedef struct
    {
        char D[MAXNUM];
        int arcs[MAXNUM][MAXNUM];
        int vexnum, arcnum;//顶点数和边数
    }AMGraph;
    struct//辅助数组的定义
    {
        char begin;
        char end;
        int weight;
    }FuZhu[(MAXNUM * (MAXNUM - 1)) / 2];
    int Vexset[MAXNUM];
    int LocateVex(AMGraph G, char v)//确定v在G中的位置
    {
        for (int i = 0; i < G.vexnum; ++i)
            if (G.D[i] == v)
                return i;
        return -1;
    }
    void CreateG(AMGraph& G)//创建无向网G
    {
        int i, j, t;
        cout << "请输入城市小区的总个数和小区之间的总电路数:";
        cin >> G.vexnum >> G.arcnum;
        cout << endl;
        cout << "输入小区的名称:如a" << endl;
        for (i = 0; i < G.vexnum; i++)
        {
            cout << "请输入第" << (i + 1) << "个小区的名称:";
            cin >> G.D[i];
        }
        cout << endl;
        for (i = 0; i < G.vexnum; i++)
        {
            for (j = 0; j < G.vexnum; j++)
                G.arcs[i][j] = MAXINT;
        }
        cout << "请输入电路的起点,终点和造价,例如a b 4" << endl;
        for (t = 0; t < G.arcnum; t++)
        {
            char x, y;
            int z;
            cout << "请输入第" << (t + 1) << "条电路的起点终点和造价:";
            cin >> x >> y >> z;
            i = LocateVex(G, x);
            j = LocateVex(G, y);
            G.arcs[i][j] = z;
            G.arcs[j][i] = z;
            FuZhu[t].begin = x;
            FuZhu[t].end = y;
            FuZhu[t].weight = z;
        }
    }
    void Sort(AMGraph G)//冒泡排序
    {
        int m = G.arcnum - 2;
        int n = 1;
        while ((m > 0) && n == 1)
        {
            n = 0;
            for (int j = 0; j <= m; j++)
            {
                if (FuZhu[j].weight > FuZhu[j + 1].weight)
                {
                    n = 1;
                    char Begin = FuZhu[j].begin;
                    FuZhu[j].begin = FuZhu[j + 1].begin;
                    FuZhu[j + 1].begin = Begin;
                    char End = FuZhu[j].end;
                    FuZhu[j].end = FuZhu[j + 1].end;
                    FuZhu[j + 1].end = End;
                    char Weight = FuZhu[j].weight;
                    FuZhu[j].weight = FuZhu[j + 1].weight;
                    FuZhu[j + 1].weight = Weight;
                }
            }
        }
    }
    int MinSpanTree(AMGraph G)//构造最小生成树
    {
        int i, j, v1, v2, m, n, sum=0;
        Sort(G);
        for (i = 0; i < G.vexnum; i++)
        {
            Vexset[i] = i;
        }
        for (i = 0; i < G.arcnum; i++)
        {
            v1 = LocateVex(G, FuZhu[i].begin);
            v2 = LocateVex(G, FuZhu[i].end);
            m = Vexset[v1];
            n = Vexset[v2];
            if (m != n)
            {
                sum += FuZhu[i].weight;
                cout << FuZhu[i].begin << "-->" << FuZhu[i].end << endl;
                for (j = 0; j < G.vexnum; j++)
                {
                    if (Vexset[j] == n)
                        Vexset[j] = m;
                }
            }
        }
        return sum;
    }
    int main()
    {
        int money;
        AMGraph G;
        CreateG(G);
        cout << endl;
        cout << "******无向网创建完成******" << endl;
        cout << endl;
        money = MinSpanTree(G);
        cout << "电路总造价为:" << money << endl;
        return 0;
    }
    
    物联沃分享整理
    物联沃-IOTWORD物联网 » 电网建设:预算控制与造价计算

    发表评论