电网建设造价计算

课程设计目录

哈夫曼编码/译码器

教室数据管理



一、设计任务及要求

假设一个城市有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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

比特冬哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值