基本的图运算

本文涉及的产品
无影云电脑企业版,4核8GB 120小时 1个月
无影云电脑个人版,1个月黄金款+200核时
资源编排,不限时长
简介: 【5月更文挑战第7天】这段内容描述了一个图数据结构的实现,包括`Graph`和`Vertex`结构体。`Graph`包含顶点字典,顶点数和边数,顶点合边的操作。`Vertex`结构为邻接关系管理有ID、邻接关系、颜色、距离等属性,并能添加、删除邻接点。

1 图

图算法多种多样种,任何一种算法都有应用的适合场景。 它常见的应用场景是社交网络,金融风险,网络安全,网页排序、社群发现和计算最短路径等等。

以下是一个基本图计算的函数的实现。

  • 包括以下属性,

    我们定义一个图,它的大小最大

    var (
      max_size = 65535个边 
      )
    
  • 属性:

          Vertices  顶点总数
          NumVertices  顶点总数
          NumEdge  边总数
    

函数, 将顶点vert 加入图中,addEdge(fromVert,toVert) 添加有向边:

        AddVertex(vert) 
  • 函数, 添加带优先级的有向边

          AddEdge(fromVert, toVert, weight)
    

函数,查找名称为 vKey 的顶点,getVertices() 返回图中所有顶点列表

        GetVertex(vKey)  

函数,按照vert in graph 的语句形式,返回顶点是否在图中 true/false

因此结构体为:

    type Graph struct {
        Vertices    map[string]*Vertex
        NumVertices int
        NumEdge     int
    }
  • 顶点结构为:

     type Vertex struct {
          Id          string
          ConnectedTo map[string]int
          Color       string
          Dist        int
          Pred        string
          Disc        int
          Fin         int
      }
    

添加顶点, 并返回被添加的顶点

        func (gp *Graph) AddVertex(key string) *Vertex {
            if gp.NumEdge >= max_size {
                panic("too much edge or vertex.")
            }
            gp.NumVertices += 1
            NewVertex := MakeVertex(key)
            gp.Vertices[key] = NewVertex
            return NewVertex
        }

获取顶点信息

    func (gp *Graph) GetVertex(key string) *Vertex {
        return gp.Vertices[key]
    }

顶点是否存在该图中,通过顶点id判断

    func (gp *Graph) Contains(key string) bool {
        return gp.Vertices[key] != nil
    }

添加顶点到图中。使用顶点结构体的方法,添加邻接边

    func (gp *Graph) AddEdge(start, end string, cost int) {

        var nv *Vertex
        if !gp.Contains(start) {
            nv = gp.AddVertex(start)
        }

        if !gp.Contains(end) {
            nv = gp.AddVertex(end)
        }

        rst := gp.Vertices[start].AddNeighbor(gp.Vertices[end], cost)
        if rst {
            gp.NumEdge += 1
        }

    }

获取顶点名称的 列表集, 和值集

    func (gp *Graph) GetVertices() ([]string, []*Vertex) {
        var keys []string
        var vers []*Vertex
        for k, v := range gp.Vertices {
            keys = append(keys, k)
            vers = append(vers, v)
        }
        return keys, vers
    }

2 图的顶点

添加顶点邻居,顶点对象一个字典的key,设置边和权重信息

func (vt *Vertex) AddNeighbor(nbr *Vertex, weight int) bool {

    if nbr == nil {
        return false
    }
    if vt.ConnectedTo[nbr.Id] != 0 {
        return false
    }
    vt.ConnectedTo[nbr.Id] = weight

    return true
}

移除该顶点的一个邻接顶点

func (vt *Vertex) DelNeighbor(nbr *Vertex) {
    delete(vt.ConnectedTo, nbr.Id)
}

设置颜色 设置距离 前置 时间 完成点

func (vt *Vertex) SetColor(color string) {
    vt.Color = color
}




func (vt *Vertex) SetDistance(d int) {
    vt.Dist = d
}



func (vt *Vertex) SetPred(p string) {
    vt.Pred = p
}



func (vt *Vertex) SetDiscovery(dtime int) {
    vt.Disc = dtime
}



func (vt *Vertex) SetFinish(ftime int) {
    vt.Fin = ftime
}



func (vt *Vertex) GetFinish(ftime int) int {
    return vt.Fin
}

获取检测 前置 权重,成本 顶点颜色

func (vt *Vertex) GetDiscovery() int {
    return vt.Disc
}



func (vt *Vertex) GetPred() string {
    return vt.Pred
}



func (vt *Vertex) GetDistance() int {
    return vt.Dist
}



func (vt *Vertex) GetColor() string {
    return vt.Color
}

返回该顶点的连接的全部key,@param item = key 返回全部key

func (vt *Vertex) GetConnections(item string) []int {
    var keys []string
    var vts []int
    for k, v := range vt.ConnectedTo {
        keys = append(keys, k)
        vts = append(vts, v)
    }
    return vts

}

返回该顶点边的 全部 权重信息

func (vt *Vertex) GetAllWeights(nbrKey string) []int {
    var weights []int
    for _, w := range vt.ConnectedTo {
        weights = append(weights, w)
    }
    return weights
}

返回该顶点到某个边的信息

func (vt *Vertex) GetWeight(nbrKey string) int {
    return vt.ConnectedTo[nbrKey]
}

返回该顶点的基本信息

func (vt *Vertex) GetStr(nbr string) string {
    return fmt.Sprintf("%v:color:%v:disc:%v:fin:%v:dist:%v:connect and weight info:%v:pred:%v",
        vt.Id, vt.Color, vt.Disc, vt.Fin, vt.Dist, vt.ConnectedTo, vt.Pred)
}

返回该顶点的ID

func (vt *Vertex) GetId() string {
    return vt.Id
}

3 使用图计算类

首先添加两个顶点,然后设置顶点1的 权重成本 2,

再重复添加该顶点1 到顶点2 的成本1

新增从顶点1 一条边 到顶点3 成本2

新增 顶点1 添加一条边 到顶点4 成本1

新增顶点2 添加一条边 到顶点3 成本2

新增顶点2 添加一条边 到顶点4 成本3

新增 顶点3 添加一条边 到顶点4 成本4

新增 顶点2 添加一条边 到顶点1 成本2

设置顶点3 距离为4

设置顶点2 距离为3

显示基本信息:

 顶点总数:%v, 边总数:%v, \n顶点1的信息:%v", Gp.NumVertices, Gp.NumEdge, Gp.GetVertex 

此时该图应该有4个顶点,7个边。 如下所示:

image.png

然后删除顶点1的一条到顶点2的边,那么还剩下 6条边。

完整代码如下:

func TestSetup(t *testing.T) {

Gp := MakeGraph()
Gp.AddVertex(fmt.Sprintf("%v", 1))
Gp.AddVertex(fmt.Sprintf("%v", 2))

Gp.Vertices[fmt.Sprintf("%v", 1)].SetDistance(2)

//顶点1 添加一条边 到顶点2 成本1
Gp.AddEdge(fmt.Sprintf("%v", 1), fmt.Sprintf("%v", 2), 1)
//重复添加一条边 到顶点2
Gp.AddEdge(fmt.Sprintf("%v", 1), fmt.Sprintf("%v", 2), 1)
//添加一条边 到顶点3  成本2
Gp.AddEdge(fmt.Sprintf("%v", 1), fmt.Sprintf("%v", 3), 2)
//顶点1 添加一条边 到顶点4  成本1
Gp.AddEdge(fmt.Sprintf("%v", 1), fmt.Sprintf("%v", 4), 1)
//顶点2 添加一条边 到顶点3  成本2
Gp.AddEdge(fmt.Sprintf("%v", 2), fmt.Sprintf("%v", 3), 2)
//顶点2 添加一条边 到顶点4  成本3
Gp.AddEdge(fmt.Sprintf("%v", 2), fmt.Sprintf("%v", 4), 3)
//顶点3 添加一条边 到顶点4  成本4
Gp.AddEdge(fmt.Sprintf("%v", 3), fmt.Sprintf("%v", 4), 4)
//顶点2 添加一条边 到顶点1  成本2
Gp.AddEdge(fmt.Sprintf("%v", 2), fmt.Sprintf("%v", 1), 2)

//设置顶点3 距离为4
Gp.Vertices[fmt.Sprintf("3")].SetDistance(4)
//设置顶点2 距离为3
Gp.Vertices[fmt.Sprintf("2")].SetDistance(3)  

if Gp.NumVertices != 4 || Gp.NumEdge != 7 {
    t.Fatalf("vertices number should be 4, have:%v, edge number should be 7   have:%v \n", Gp.NumVertices, Gp.NumEdge)
}

vert := Gp.GetVertex(fmt.Sprintf("1"))

new_color := "blcak"
vert.SetColor(new_color)

if nc := vert.GetColor(); nc != new_color {
    t.Fatalf("color set fail hope:%v, have:%v \n", new_color, nc)
}

//删除
vert.DelNeighbor(Gp.GetVertex(fmt.Sprintf("2")))
Gp.NumEdge -= 1
if Gp.NumVertices != 4 || Gp.NumEdge != 6 {
    t.Fatalf("vertices number should be 4, have:%v, edge number should be 7   have:%v \n", Gp.NumVertices, Gp.NumEdge)
}

4 小结:

完成基本图的使用,可以帮助我们理解矩阵服务。图计算现在也是一门利用人工智能提取、理解、解析、总结学习现实世界中的事物关联的技术。

完整代码如下连接:

github.com/hahamx/utools/utils/queues/Graph

目录
相关文章
|
存储 C++
深度复杂空间结构运算的逻辑
深度复杂空间结构运算的逻辑
|
计算机视觉
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
741 0
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
|
4月前
|
Java uml
使用工厂方法模式设计能够实现包含加法(+)、减法(-)、乘法(*)、除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果。要求使用相关的工具绘制UML类图并严格按照类图的设计编写程序实
该博客文章通过UML类图和Java代码示例,展示了如何使用工厂方法模式设计一个支持加法、减法、乘法和除法运算的计算机程序,并严格按照类图设计实现程序。
|
4月前
|
Java uml
1、使用简单工厂模式设计能够实现包含加法(+)、减法(-)、乘法(*)、除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果。要求使用相关的工具绘制UML类图并严格按照类图的设计编写程
该博客文章展示了如何使用简单工厂模式设计一个程序,该程序能够根据用户输入的运算符(加、减、乘、除)对两个数进行计算,并提供了相应的UML类图和Java源码实现。
1、使用简单工厂模式设计能够实现包含加法(+)、减法(-)、乘法(*)、除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果。要求使用相关的工具绘制UML类图并严格按照类图的设计编写程
|
7月前
|
SQL 关系型数据库 MySQL
无法针对行和行之间的运算
无法针对行和行之间的运算
45 0
|
存储 算法 数据处理
数据的表示及运算
一、数据的表示及运算 数据的表示和运算是计算机系统中非常重要的概念,它们决定了计算机如何处理和操作数据。 1. 数据的表示:计算机使用二进制(0和1)来表示和存储数据。二进制是一种只有两个状态的编码方式,可以通过开关电路的开和关来表示0和1。计算机将二进制编码与不同的数据类型关联,例如整数、浮点数、字符等。 2. 整数运算:计算机可以对整数进行基本的算术运算,包括加法、减法、乘法和除法。这些运算是通过电子电路中的逻辑门实现的,逻辑门可以对二进制数进行逻辑运算和移位操作。 3. 浮点数运算:计算机可以进行浮点数的运算,浮点数是一种用于表示带有小数部分的数值的数据类型。浮点数运算涉及到浮点数的表示
87 0
|
7月前
|
语音技术 Python
量化模型是将浮点数运算转换为整数运算的过程
【2月更文挑战第32天】量化模型是将浮点数运算转换为整数运算的过程
69 1
|
7月前
|
算法
你知道几种乘法的计算方式?
你知道几种乘法的计算方式?
128 0
|
7月前
|
存储 搜索推荐 Java
图计算中的顶点和边是什么?请解释其概念和作用。
图计算中的顶点和边是什么?请解释其概念和作用。
198 0
|
C++ 计算机视觉
【OpenCv • c++】形态学技术操作 —— 开运算与闭运算
【OpenCv • c++】形态学技术操作 —— 开运算与闭运算
476 0