【算法基础实验】图论-构建加权无向图

news/2024/10/21 9:58:45/

构建加权无向图

理论基础

图论中,加权无向图是一种每条边都分配了一个权重或成本的图形结构。这种类型的图在许多实际应用中都非常有用,如路由算法、网络流量设计、最小生成树和最短路径问题等。

加权无向图的基本特征

  1. 顶点和边
    • 顶点(Vertex): 图中的节点,可以表示交叉点、位置点或网络中的节点等。
    • 边(Edge): 连接顶点的线,无向边意味着连接的顶点间没有方向性的区别。
  2. 权重
    • 每条边都有一个权重(或成本、长度),这个权重是一个数值,代表了从一个顶点到另一个顶点的“成本”。
    • 权重可以表示多种含义,如距离、时间、消耗或任何其他度量标准。

存储加权无向图

加权无向图通常可以通过以下几种数据结构来存储和表示:

  1. 邻接矩阵
    • 使用二维数组来表示顶点之间的连接关系,矩阵中的每个元素代表边的权重。如果两个顶点之间没有直接连接,则该位置通常用一个特殊值(如无穷大或null)来表示。
  2. 邻接表
    • 每个顶点都对应一个列表,列表中存储了与该顶点直接相连的其他顶点及相应的权重。这种表示方法更加节省空间,尤其是在稀疏图中。
  3. 边的列表
    • 维护一个所有边的列表,每条边由一对顶点和一个权重组成。

图的操作

操作加权无向图常见的算法包括但不限于:

  1. 最小生成树(MST)
    • 寻找一种方式,通过树形结构连接图中的所有顶点,使得所有边的权重总和最小。常用算法包括Kruskal算法和Prim算法
  2. 最短路径
    • 寻找顶点间的最短路径,即路径上的权重总和最小。常用算法包括Dijkstra算法和Floyd-Warshall算法
  3. 网络流量优化
    • 在网络图中,寻找最优的数据流方式,使得成本最低或效率最高。

应用实例

加权无向图的应用非常广泛,例如:

  • 交通网络:道路或铁路网中的路径规划,权重可以是距离、时间或通行费用。
  • 电信网络:数据包的传输路径优化,权重可能是延迟或带宽。
  • 物流配送:货物配送路线的优化,权重可能包括距离和成本。
  • 资源分配:如电网中电力的分配。

加权无向图的研究和应用提供了一种强大的工具,可以解决实际中的许多优化和规划问题。在算法和数据结构的领域中,理解并有效使用这些工具是非常重要的。

数据结构和实验数据

请添加图片描述

代码实现

myEdge

java">public class myEdge implements Comparable<myEdge>
{private final int v;private final int w;private final double weight;public myEdge(int v,int w,double weight){this.v = v;this.w = w;this.weight = weight;}public double weight(){return weight;}public int either(){ return v;}public int other(int vertex){if(vertex == v) return w;else if(vertex == w) return v;else throw new IllegalArgumentException("Invalid vertex");}public int compareTo(myEdge that){if(this.weight()<that.weight()) return -1;else if(this.weight()>that.weight()) return 1;else return 0;}public String toString(){ return String.format("%d-%d %.2f",v,w,weight);}
}

这段代码定义了一个名为 myEdge 的类,代表加权无向图中的一条边。类实现了 Comparable 接口,允许边对象之间进行比较,这通常用于算法中需要对边进行排序的情况,例如在构建最小生成树时。以下是对该类中每个部分的详细解释:

类定义和字段

java">
public class myEdge implements Comparable

这段代码定义了一个名为 myEdge 的类,代表加权无向图中的一条边。类实现了 Comparable 接口,允许边对象之间进行比较,这通常用于算法中需要对边进行排序的情况,例如在构建最小生成树时。以下是对该类中每个部分的详细解释:

类定义和字段

java">
public class myEdge implements Comparable

这段代码定义了一个名为 myEdge 的 Java 类,用于表示加权无向图的一条边。这个类实现了 `Comparable

这段代码定义了一个名为 myEdge 的 Java 类,用于表示加权无向图的一条边。这个类实现了 Comparable 接口,使得边可以根据权重进行排序,这是在图算法中常见的需求,特别是在最小生成树和最短路径算法中。

类字段

  • vw:这两个 private final int 类型的字段代表边连接的两个顶点。final 表明一旦边被创建,这两个顶点不可更改。
  • weight:这是一个 private final double 类型的字段,存储边的权重。同样,final 表示权重在创建后不可更改。

构造函数

java">
public myEdge(int v, int w, double weight) {this.v = v;this.w = w;this.weight = weight;
}

构造函数接收两个顶点标识和一个权重,初始化边的基本属性。

方法

  • weight():返回边的权重。

    java">
    public double weight() { return weight; }
  • either():返回边的一个顶点。此方法用于访问边的任一端点,通常在边的迭代中使用。

    java">
    public int either() { return v; }
  • other(int vertex):给定边的一个顶点,返回另一个顶点。如果传入的顶点不是这条边的一部分,抛出 IllegalArgumentException

    java">
    public int other(int vertex) {if (vertex == v) return w;else if (vertex == w) return v;else throw new IllegalArgumentException("Invalid vertex");
    }
  • compareTo(myEdge that):实现 `Comparable接口的方法,用于比较两条边的权重。这使得边可以被排序,通常用于算法如 Kruskal 的最小生成树算法中。

    java">
    public int compareTo(myEdge that) {return Double.compare(this.weight, that.weight);
    }
  • toString():提供边的字符串表示,格式为 “v-w weight”,其中 vw 是顶点标识,weight 是边的权重。这对于打印和调试很有用。

    java">
    public String toString() {return String.format("%d-%d %.2f", v, w, weight);
    }

总结

myEdge 类提供了一个结构化的方式来表示图中的边,包括边的两个端点和权重。实现 Comparable 接口允许边根据权重进行排序,这在很多图算法中非常重要,特别是那些需要考虑边权重的算法,如最小生成树或最短路径算法。通过方法 either()other(),可以方便地在图的上下文中使用边,而 toString() 方法则提供了边的直观表达,便于输出和调试。

myEdgeWeightedGraph

java">import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;public class myEdgeWeightedGraph
{private int V;private int E;private myBag<myEdge>[] adj;private static final String NEWLINE = System.getProperty("line.separator");public myEdgeWeightedGraph(int V){this.V = V;this.E = E;adj = (myBag<myEdge>[]) new myBag[V];for(int v=0;v<V;v++)adj[v]=new myBag<myEdge>();}public myEdgeWeightedGraph(In in){this(in.readInt());int E = in.readInt();for (int i = 0; i < E; i++){int v = in.readInt();int w = in.readInt();double weight = in.readDouble();myEdge e = new myEdge(v,w,weight);addEdge(e);}}public int V() {return V;}public int E() {return E;}public void addEdge(myEdge e){int v = e.either(),w=e.other(v);adj[v].add(e);adj[w].add(e);E++;}public Iterable<myEdge> adj(int v){return adj[v];}public Iterable<myEdge> edges(){myBag<myEdge> b = new myBag<myEdge>();for(int v=0;v<V;v++)for(myEdge e: adj[v])if(e.other(v)<v) b.add(e);return b;}public String toString(){StringBuilder s = new StringBuilder();s.append(V +" vertexes "+ E + " edges " + NEWLINE);for(int v = 0; v<V; v++) {s.append(v + ": ");for(myEdge e:adj(v))s.append(e + "  ");s.append(NEWLINE);}return s.toString();}public static void main(String[] args){In in = new In(args[0]);myEdgeWeightedGraph G = new myEdgeWeightedGraph(in);StdOut.print(G);}
}

这段代码定义了一个表示加权无向图的类 myEdgeWeightedGraph。这里的每个重要组成部分我将逐一说明:

  1. 构造函数
    • 第一个构造函数接受一个顶点数 V,初始化图,为每个顶点创建一个用于存储边的链表。
    • 第二个构造函数通过读取一个输入源来构建图。它首先读取顶点数和边数,然后连续读取每条边的两个顶点和权重,并将这些边添加到图中。
  2. 边的添加
    • addEdge 方法用于向图中添加一条边,同时将边添加到两个顶点的邻接链表中。
  3. 图的信息获取
    • V()E() 方法分别返回图的顶点数和边数。
    • adj(int v) 方法返回与顶点 v 相连的所有边。
    • edges() 方法返回图中的所有边,确保每条边只被列出一次。
  4. 图的字符串表示
    • toString 方法生成并返回图的字符串描述,包括每个顶点及其相邻的边。
  5. 主函数
    • main 方法从文件读取图数据,构建图对象,并打印图的字符串表示。

实验

代码编译

$ javac myEdge.java
$ javac myEdgeWeightedGraph.java

代码运行

$ java myEdgeWeightedGraph ..\data\tinyEWG.txt
8 vertexes 16 edges 
0: 6-0 0.58  0-2 0.26  0-4 0.38  0-7 0.16
1: 1-3 0.29  1-2 0.36  1-7 0.19  1-5 0.32
2: 6-2 0.40  2-7 0.34  1-2 0.36  0-2 0.26  2-3 0.17
3: 3-6 0.52  1-3 0.29  2-3 0.17
4: 6-4 0.93  0-4 0.38  4-7 0.37  4-5 0.35
5: 1-5 0.32  5-7 0.28  4-5 0.35
6: 6-4 0.93  6-0 0.58  3-6 0.52  6-2 0.40
7: 2-7 0.34  1-7 0.19  0-7 0.16  5-7 0.28  4-7 0.37

http://www.ppmy.cn/news/1439810.html

相关文章

小程序使用阿里巴巴矢量图标库

一、登录官网 www.iconfont.cn 二、在搜索框中搜索想要的图标&#xff0c;将鼠标移动到图标上会看到三个标记 可以使用下载&#xff0c;直接使用&#xff1a; 可以使用css文件使用&#xff1a; 首先点击购物车样式的选项&#xff0c;而后点击下图位置&#xff1a; 点击自己创…

docker使用,安装go和centos7

一、安装docker 二、使用docker 1、下载镜像centos docker pull centos:7.2.1511 2、查看容器 docker ps -a 3、创建容器&#xff0c;创建后 状态&#xff1a;CREATE docker create -it centos:7.2.1511 /bin/bash 4、启动容器 &#xff08;先查看容器id启动 CONTAINER…

[华为OD] 给航天器一侧加装长方形或正方形的太阳能板 100

给航天器一侧加装长方形或正方形的太阳能板&#xff08;图中的红色斜线区域&#xff09;&#xff0c;需要先安装两个支 柱&#xff08;图中的黑色竖条&#xff09;&#xff0c;再在支柱的中间部分固定太阳能板。但航天器不同位置的支柱长度 不同&#xff0c;太阳能板的安装面…

Springboot整合文心一言----非流式响应与流式响应(前后端)

所谓非流式响应就是直接等待百度把答案生成好之后直接返回给你&#xff0c;而后者这是一一种流的形式&#xff0c;百度一边生成答案&#xff0c;一边将答案进行返回&#xff0c;这样就是我们在使用ChatGPT中最常见的一种表现了&#xff0c;它回答问题的时候总是一个字一个字的出…

汇编语言(详解)

汇编语言安装指南 第一步&#xff1a;在github上下载汇编语言的安装包 网址&#xff1a;GitHub - HaiPenglai/bilibili_assembly: B站-汇编语言-pdf、代码、环境等资料B站-汇编语言-pdf、代码、环境等资料. Contribute to HaiPenglai/bilibili_assembly development by creat…

LMDeploy量化部署LLMVLM实践-笔记五

本次课程由西北工业大学博士生、书生浦源挑战赛冠军队伍队长、第一期书生浦语大模型实战营优秀学员【安泓郡】讲解【OpenCompass 大模型评测实战】课程 课程视频&#xff1a;https://www.bilibili.com/video/BV1tr421x75B/ 课程文档&#xff1a;https://github.com/InternLM/…

美国言语听力学会(ASHA)关于非处方 (OTC) 助听器的媒体声明(翻译稿)

美国国会于 2021 年 4 月 13 日批准美国听力学会积极提供建议&#xff0c;并一直积极参与制定FDA关于非处方助听器销售的拟议法规。根据2017年通过的立法授权。学院积极参与帮助塑造授权立法&#xff0c;并就即将出台的条例分享了建议。 根据美国卫生与公众服务部NIH / NIDCD的…

通过 API从 0 到 1 构建 本地 GPTs——1.构建Builder‘s Prompt

目的&#xff1a;帮助小白用户生成结构化 prompt 功能清单 搭建本地 gpts 能力&#xff0c;构建本地企业知识库助手Builder’s Prompt -对话引导构建 prompt 示例&#xff0c;生成助手信息function_call的用法prompt 示例 GPTs 的 Create 能力 用于引导用户构建结构化的 pr…