图 最短路径Floyd 算法#go语言

1 篇文章 0 订阅
1 篇文章 0 订阅

图 最短路径Floyd 算法#go语言

 

package sufa

import (
   "fmt"
   mapset "github.com/deckarep/golang-set"
   "math/rand"
   "src/goProject1/utils"
   "strconv"
)

type GNode struct {
   Name     string
   NodeList []*GNode
   EdgeList [][]*Edge
   Direct   [][]int
}
type Edge struct {
   ParentNode   *GNode
   NextNode     *GNode
   RelationShip string
   Weight       int
}

var (
   gNodes []*GNode
   edges  []*Edge
)

func init() {
   gNodes = make([]*GNode, 0)
   edges = make([]*Edge, 0)
}

func Main() {
   var i = 0
   _ = utils.ReadLine("./sufa/te.csv", func(line []byte) {
      s := string(line)
      s = utils.CompressStr(s)
      s1 := utils.SplitString(s, ",")
      //fmt.Println(s)
      //fmt.Println(len(s1), s1)
      if len(s1) == 4 && i < 10000 {
         //fmt.Print(s,s1, "\n")
         weight, err := strconv.Atoi(s1[2])
         if err != nil {
            //return
            weight = 1
         }
         addOne(s1[0], s1[3], s1[1], weight)
         fmt.Print(i, "\r")
      }
      i++
   })
   fmt.Print("\n-")

   //for i2, node := range gNodes {
   // fmt.Println(i2, node.Name, *node.NodeList[0], node.EdgeList[0], node.Direct[0])
   //}
   res, path := GetMin("mao1", "mao1000")
   //fmt.Println(gNodes)
   fmt.Print("\n")
   fmt.Println(res, path)
   //for i2, edge := range edges {
   // fmt.Println(i2, edge.ParentNode.Name, edge.NextNode.Name, edge.RelationShip,edge.Weight)
   //}

}

func addOne(p, n, relationShip string, weight int) {
   var (
      pNode *GNode
      nNode *GNode
      edge  *Edge
   )

   pNode = GetNode(p)
   nNode = GetNode(n)
   if pNode.Name == "" {
      pNode = new(GNode)
      pNode.Name = p
      gNodes = append(gNodes, pNode)

   }
   if nNode.Name == "" {
      nNode = new(GNode)
      nNode.Name = n
      gNodes = append(gNodes, nNode)
   }

   edge = GetEdge(p, n, relationShip, weight)

   if edge.ParentNode != nil || edge.NextNode != nil {
      //addRelation(pNode, nNode, edge)

      return
   }

   edge = &Edge{
      ParentNode:   pNode,
      NextNode:     nNode,
      RelationShip: relationShip,
      Weight:       weight,
   }
   edges = append(edges, edge)

   //fmt.Println(p,n)

   addRelation(pNode, nNode, edge)

}

func addRelation(pNode, nNode *GNode, edge *Edge) {
   var pFlag = 0
   var nFlag = 0
   var i1 = 0
   var i2 = 0

   for ; i1 < len(pNode.NodeList); i1++ {
      if pNode.NodeList[i1].Name == nNode.Name {
         pFlag = len(pNode.EdgeList[i1])
         break
      }
   }

   for ; i2 < len(nNode.NodeList); i2++ {
      if nNode.NodeList[i2].Name == pNode.Name {
         nFlag = len(nNode.EdgeList[i2])
         break
      }
   }
   if pFlag > 0 {
      pNode.EdgeList[i1] = append(pNode.EdgeList[i1], edge)
      pNode.Direct[i1] = append(pNode.Direct[i1], edge.Weight)
   }
   if pFlag <= 0 || i1 == 0 {
      pNode.NodeList = append(pNode.NodeList, nNode)
      pNode.EdgeList = append(pNode.EdgeList, []*Edge{edge})
      pNode.Direct = append(pNode.Direct, []int{edge.Weight})
   }

   if nFlag > 0 {
      nNode.EdgeList[i2] = append(nNode.EdgeList[i2], &Edge{
         ParentNode:   edge.ParentNode,
         NextNode:     edge.NextNode,
         RelationShip: edge.RelationShip,
         Weight:       -edge.Weight,
      })
      nNode.Direct[i2] = append(nNode.Direct[i2], -edge.Weight)
   }

   if nFlag <= 0 || i2 == 0 {
      nNode.NodeList = append(nNode.NodeList, pNode)
      nNode.EdgeList = append(nNode.EdgeList, []*Edge{&Edge{
         ParentNode:   edge.ParentNode,
         NextNode:     edge.NextNode,
         RelationShip: edge.RelationShip,
         Weight:       -edge.Weight,
      }})
      nNode.Direct = append(nNode.Direct, []int{-edge.Weight})
   }

   //fmt.Println(pFlag, nFlag,i1,i2, pNode.Name, nNode.Name, pNode.NodeList, nNode.NodeList, pNode.EdgeList, nNode.EdgeList)

}

func GetEdge(p, n, relationShip string, weight int) *Edge {
   for i := 0; i < len(edges); i++ {
      if p != "" && n != "" && relationShip != "" {
         if edges[i].ParentNode.Name == p &&
            edges[i].NextNode.Name == n &&
            //edges[i].RelationShip == relationShip &&
            edges[i].Weight == weight {
            return edges[i]
         }
      }
   }
   return &Edge{}
}

func GetNode(name string) *GNode {

   for i := 0; i < len(gNodes); i++ {
      if gNodes[i].Name == name {
         return gNodes[i]
      }
   }
   return &GNode{
      Name: "",
   }
}

func GetMin(pName, nName string) (li int, path []interface{}) {
   pNode := GetNode(pName)
   nNode := GetNode(nName)
   fmt.Println(pNode.Name, nNode.Name)
   if pNode.Name == "" || nNode.Name == "" || pName == nName || pNode == nil || nNode == nil {
      return
   }

   var list1 = make(map[interface{}]interface{}, 0)
   var parentNodeMap = make(map[interface{}]interface{}, 0)
   s := mapset.NewSet()
   list1[pNode] = 0

   type fType func(node *GNode)
   var f fType
   f = func(node *GNode) {
      if len(s.ToSlice()) == len(gNodes) || node == nil {
         return
      }
      //s.Add(node)

      var minL = -1
      //var minNode *GNode
      for i := 0; i < len(node.NodeList); i++ {
         nextNode := node.NodeList[i]
         edge := node.EdgeList[i]
         direct := node.Direct[i]

         var minLength = -1

         for j := 0; j < len(edge); j++ {
            //edge1:=edge[j]
            direct1 := direct[j]
            if direct1 <= 0 {
               continue
            }
            if minLength == -1 {
               minLength = direct1
            }
            if direct1 < minLength {
               minLength = direct1
            }
         }
         if minLength <= 0 {
            continue
         }

         if minL == -1 {
            minL = minLength
            //minNode = nextNode
         }
         if minLength < minL {
            minL = minLength
            //minNode = nextNode
         }

         if nextNode != nil && minLength > 0 {
            s1, ok1 := list1[node]
            s2, ok2 := list1[nextNode]
            if (!ok2 && ok1) || (ok1 && ok2 && s1.(int)+minLength <= s2.(int)) {
               list1[nextNode] = list1[node].(int) + minLength
               parentNodeMap[nextNode] = node
               s.Add(node)
               f(nextNode)
            }
            //s3, ok3 := parentNodeMap[node]
            //s4, ok4 := parentNodeMap[nextNode]
            //if s.Contains(node) && s.Contains(nextNode) && ok3 && ok4 &&
            // s3 == nextNode && s4 == node{
            // fmt.Println("=== == ")
            // continue
            //}

         }
      }

      //if minNode != nil  && minL >0{
      // s1, ok1 := list1[node]
      // s2, ok2 := list1[minNode]
      // if (!ok2 && ok1) || (ok1 && ok2 && s1.(int)+minL <= s2.(int)) {
      //    list1[minNode] = list1[node].(int) + minL
      // }
      // parentNodeMap[node.Name+minNode.Name] = minL
      // s.Add(node)
      // f(minNode)
      //}

   }
   f(pNode)

   if list1[nNode] != nil {
      li = list1[nNode].(int)
   }
   //fmt.Println(list1)
   //fmt.Println(nNode)
   //for i, i2 := range list1 {
   // if parentNodeMap[i.(*GNode)] != nil{
   //    fmt.Println(i.(*GNode).Name, i2,parentNodeMap[i.(*GNode)].(*GNode).Name)
   // }else {
   //    fmt.Println(i.(*GNode).Name, i2,parentNodeMap[i.(*GNode)])
   // }
   // //res = append(res, parentNodeMap[i.(*GNode)])
   //
   //}

   var ff fType
   ff = func(node *GNode) {
      if parentNodeMap[node] == nil {
         return
      }
      pgNode := parentNodeMap[node].(*GNode)
      path = append(path, pgNode)
      ff(pgNode)
   }
   path = append(path, nNode)
   ff(nNode)

   for i := 0; i < len(path)/2; i++ {
      var inner interface{}
      inner = path[i]
      path[i] = path[len(path)-1-i]
      path[len(path)-1-i] = inner
   }

   for i := 0; i < len(path); i++ {
      fmt.Println(path[i].(*GNode).Name)
   }

   //fmt.Println(res)
   //fmt.Println(parentNodeMap)

   return

}

utils.go

 

package utils

import (
   "bufio"
   "io"
   "os"
   "fmt"
   mapset "github.com/deckarep/golang-set" "
   regexp"
)

func ReadLine(filePth string, hookfn func([]byte)) error {
   f, err := os.Open(filePth)
   if err != nil {
      return err
   }
   defer f.Close()

   bfRd := bufio.NewReader(f)
   for {
      line, err := bfRd.ReadBytes('\n')
      hookfn(line)    //放在错误处理前面,即使发生错误,也会处理已经读取到的数据。
      if err != nil { //遇到任何错误立即返回,并忽略 EOF 错误信息
         if err == io.EOF {
            return nil
         }
         return err
      }
   }
   //return nil
}

   

func SplitString1(str string, part string) []string {
   set1 := SplitStringT(str, part)
   set2 := SplitStringB(str, part)

   set3 := set1.Union(set2)
   //fmt.Println(set1, set2)

   s2 := make([]string, len(set3.ToSlice()))
   for i, v := range set3.ToSlice() {
      s2[i] = v.(string)
      //fmt.Println(i,v)
   }

   //
   //for i := len(s1)-1; i >= 0; i-- {
   // for j := len(s2)-1; j >= 0; j-- {
   //    if s1[i] == s2[j] {
   //       s1 = append(s1[:i],s1[i+1: ]...)
   //    }
   // }
   //}
   //s2 = append(s2, s1...)

   //fmt.Printf("%v", s2)
   return s2
}

func SplitString(str string, part string) []string {
   //str = str[-1:0]

   part = partner(part)
   var l = len(part)
   var res []string
   var (
      start int = 0
      end   int = 0
      i         = 0
   )
   end = len(str)
   start = end

   for i = len(str) - 1; i >= 0; i-- {
      if i-l < 0 {
         break
      }
      if str[i-l:i] == part {
         start = i
         res = append(res, str[start:end])
         end = start - l
         break
      }
   }

   for i = i - 1; i >= 0; i-- {
      if i-l <= 0 {
         start = 0
         res = append(res, str[start:end])
         break
      }

      //fmt.Println(start, end)
      if str[i-l:i] == part {
         start = i
         //fmt.Println(start, end)
         res = append(res, str[start:end])
      }
      end = start - l

   }

   for i := 0; i < len(res)/2; i++ {
      var st string
      st = res[i]
      res[i] = res[len(res)-i-1]
      res[len(res)-i-1] = st
   }

   return res

}

func SplitStringB(str string, part string) mapset.Set {
   part = CompressStr(part)
   reg := regexp.MustCompile(part + `*[\W\w ]+` + part + ``)
   if reg == nil {
      fmt.Println("MustCompile err")
      return nil
   }
   s := reg.FindAllString(str, -1)
   //if part == "\\\\"{
   // part = part[1:]
   //}
   fmt.Println(part, s, str)
   part = partner(part)

   var s2 = mapset.NewSet()
   for _, i2 := range s {

      if string(i2[0]) == part {
         i2 = string(i2[1:])
      }
      if string(i2[len(i2)-1]) == part {
         i2 = i2[:len(i2)-1]
      }
      s2.Add(i2)
      //fmt.Println(i2)
   }

   return s2
}

func SplitStringT(str string, part string) mapset.Set {
   part = CompressStr(part)
   reg := regexp.MustCompile(part + `[\W\w ]+` + part + `*`)
   if reg == nil {
      fmt.Println("MustCompile err")
      return nil
   }
   s := reg.FindAllString(str, -1)
   var s2 = mapset.NewSet()
   fmt.Println(part, s, str)
   part = partner(part)
   for _, i2 := range s {
      if string(i2[0]) == part {
         i2 = string(i2[1:])
      }
      if string(i2[len(i2)-1]) == part {
         i2 = i2[:len(i2)-1]
      }
      s2.Add(i2)
      //fmt.Println(i2)
   }

   //fmt.Printf("%v", s2)
   return s2
}

func se() {
   kide := mapset.NewSet()
   kide.Add("xiaorui.cc")
   kide.Add("blog.xiaorui.cc")
   kide.Add("vps.xiaorui.cc")
   kide.Add("linode.xiaorui.cc")

   special := []interface{}{"Biology", "Chemistry"}
   scienceClasses := mapset.NewSetFromSlice(special)

   address := mapset.NewSet()
   address.Add("beijing")
   address.Add("nanjing")
   address.Add("shanghai")

   bonusClasses := mapset.NewSet()
   bonusClasses.Add("Go Programming")
   bonusClasses.Add("Python Programming")

   //一个并集的运算
   allClasses := kide.Union(scienceClasses).Union(address).Union(bonusClasses)
   fmt.Println(allClasses)

   //是否包含"Cookiing"
   fmt.Println(scienceClasses.Contains("Cooking")) //false

   //两个集合的差集
   fmt.Println(allClasses.Difference(scienceClasses)) //Set{Music, Automotive, Go Programming, Python Programming, Cooking, English, Math, Welding}

   //两个集合的交集
   fmt.Println(scienceClasses.Intersect(kide)) //Set{Biology}

   //有多少基数
   fmt.Println(bonusClasses.Cardinality()) //2

}

func partner(part string) string {
   for i := len(part) - 1; i >= 0; i-- {
      if len(part) < 2 || i < 2 {
         break
      }
      var ca bool
      ca = string(part[i-1]) == "\\" ||
         string(part[i]) == "?" ||
         string(part[i]) == "+" ||
         string(part[i]) == "-" ||
         string(part[i]) == "*"

      if ca {
         part = part[:i-1] + part[i:]
         i = i - 1
      }
   }
   return part
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值