基本的图运算

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

1 图

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

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

  • 包括以下属性,

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

    var (
      max_size = 65535个边 
      )
    
    AI 代码解读
  • 属性:

          Vertices  顶点总数
          NumVertices  顶点总数
          NumEdge  边总数
    
    AI 代码解读

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

        AddVertex(vert) 
AI 代码解读
  • 函数, 添加带优先级的有向边

          AddEdge(fromVert, toVert, weight)
    
    AI 代码解读

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

        GetVertex(vKey)  
AI 代码解读

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

因此结构体为:

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

     type Vertex struct {
          Id          string
          ConnectedTo map[string]int
          Color       string
          Dist        int
          Pred        string
          Disc        int
          Fin         int
      }
    
    AI 代码解读

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

        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
        }
AI 代码解读

获取顶点信息

    func (gp *Graph) GetVertex(key string) *Vertex {
        return gp.Vertices[key]
    }
AI 代码解读

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

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

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

    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
        }

    }
AI 代码解读

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

    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
    }
AI 代码解读

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
}
AI 代码解读

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

func (vt *Vertex) DelNeighbor(nbr *Vertex) {
    delete(vt.ConnectedTo, nbr.Id)
}
AI 代码解读

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

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
}
AI 代码解读

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

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
}
AI 代码解读

返回该顶点的连接的全部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

}
AI 代码解读

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

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

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

func (vt *Vertex) GetWeight(nbrKey string) int {
    return vt.ConnectedTo[nbrKey]
}
AI 代码解读

返回该顶点的基本信息

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)
}
AI 代码解读

返回该顶点的ID

func (vt *Vertex) GetId() string {
    return vt.Id
}
AI 代码解读

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 
AI 代码解读

此时该图应该有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)
}
AI 代码解读

4 小结:

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

完整代码如下连接:

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

目录
打赏
0
2
3
0
172
分享
相关文章
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
844 0
数字图像处理实验(七)| 形态学图像处理{生成结构元素strel、腐蚀运算imerode、膨胀运算imdilate、开运算imopen、闭运算imclose}(附代码和实验截图、汉字视力表项目、总结)
使用工厂方法模式设计能够实现包含加法(+)、减法(-)、乘法(*)、除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果。要求使用相关的工具绘制UML类图并严格按照类图的设计编写程序实
该博客文章通过UML类图和Java代码示例,展示了如何使用工厂方法模式设计一个支持加法、减法、乘法和除法运算的计算机程序,并严格按照类图设计实现程序。
无法针对行和行之间的运算
无法针对行和行之间的运算
53 0
数据的表示及运算
一、数据的表示及运算 数据的表示和运算是计算机系统中非常重要的概念,它们决定了计算机如何处理和操作数据。 1. 数据的表示:计算机使用二进制(0和1)来表示和存储数据。二进制是一种只有两个状态的编码方式,可以通过开关电路的开和关来表示0和1。计算机将二进制编码与不同的数据类型关联,例如整数、浮点数、字符等。 2. 整数运算:计算机可以对整数进行基本的算术运算,包括加法、减法、乘法和除法。这些运算是通过电子电路中的逻辑门实现的,逻辑门可以对二进制数进行逻辑运算和移位操作。 3. 浮点数运算:计算机可以进行浮点数的运算,浮点数是一种用于表示带有小数部分的数值的数据类型。浮点数运算涉及到浮点数的表示
112 0
|
10月前
|
你知道几种乘法的计算方式?
你知道几种乘法的计算方式?
244 0
图计算中的顶点和边是什么?请解释其概念和作用。
图计算中的顶点和边是什么?请解释其概念和作用。
267 0
Python 分解质因数(编写函数实现:输入一个正整数n,把数字n分解成不能再分解因子的乘法,比如:8=2*2*2, 10 = 2*5,而不是 8 = 2 * 4 这种可以再分解的。)
Python 分解质因数(编写函数实现:输入一个正整数n,把数字n分解成不能再分解因子的乘法,比如:8=2*2*2, 10 = 2*5,而不是 8 = 2 * 4 这种可以再分解的。)
963 0
113.实矩阵乘法运算
113.实矩阵乘法运算
137 0
图神经网络16-DGL实战:图、节点和边创建与运算
DGL 框架是由纽约大学和 AWS 工程师共同开发的开源框架,旨在为大家提供一个在图上进行深度学习的工具,帮助大家更高效的实现算法。
1176 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等