Created
December 9, 2022 17:00
-
-
Save samix73/e749fd4b62e1a6b8a4db8ca1c5601c56 to your computer and use it in GitHub Desktop.
Golang generic graph generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/gob" | |
"encoding/json" | |
"math/rand" | |
"os" | |
"strconv" | |
"strings" | |
) | |
type StringData string | |
func (s StringData) String() string { | |
return string(s) | |
} | |
func generateData() StringData { | |
nameList := []string{ | |
"Pants", | |
"Battle", | |
"Carrot", | |
"Sweet", | |
"Shadow", | |
"Shoe", | |
"Beer", | |
"Green", | |
"Yellow", | |
"Dark", | |
"White", | |
"Shirt", | |
"Monkey", | |
"Silly", | |
} | |
return StringData(nameList[rand.Intn(len(nameList))] + nameList[rand.Intn(len(nameList))]) | |
} | |
type Edge[E DataType] struct { | |
Data E `json:"data"` | |
Index int `json:"index"` | |
Score int `json:"score"` | |
} | |
func (e *Edge[E]) String() string { | |
bobTheBuilder := new(strings.Builder) | |
bobTheBuilder.WriteString(e.Data.String()) | |
bobTheBuilder.WriteString("\n\t") | |
bobTheBuilder.WriteString("Weight: " + strconv.Itoa(e.Score)) | |
bobTheBuilder.WriteString("\n\t") | |
bobTheBuilder.WriteString("-> " + strconv.Itoa(e.Index)) | |
return bobTheBuilder.String() | |
} | |
type DataType interface { | |
String() string | |
} | |
type Node[N DataType, E DataType] struct { | |
Data N `json:"data"` | |
Edges []*Edge[E] `json:"edges"` | |
} | |
func (n *Node[N, E]) String() string { | |
bobTheBuilder := new(strings.Builder) | |
bobTheBuilder.WriteString(n.Data.String()) | |
if len(n.Edges) > 0 { | |
bobTheBuilder.WriteRune('\n') | |
} | |
for j, edge := range n.Edges { | |
bobTheBuilder.WriteRune('\t') | |
bobTheBuilder.WriteString("#" + strconv.Itoa(j) + ": ") | |
bobTheBuilder.WriteString(edge.String()) | |
if j < len(n.Edges)-1 { | |
bobTheBuilder.WriteRune('\n') | |
} | |
} | |
return bobTheBuilder.String() | |
} | |
func NewNode[N DataType, E DataType](data N) *Node[N, E] { | |
return &Node[N, E]{ | |
Data: data, | |
Edges: make([]*Edge[E], 0), | |
} | |
} | |
func (n *Node[N, E]) canConnect(i int) bool { | |
for _, edge := range n.Edges { | |
if edge.Index == i { | |
return false | |
} | |
} | |
return rand.Float64() < 0.2 | |
} | |
func (n *Node[N, E]) Connect(i int, score int, data E) { | |
if !n.canConnect(i) { | |
return | |
} | |
n.Edges = append(n.Edges, &Edge[E]{ | |
Data: data, | |
Index: i, | |
Score: score, | |
}) | |
} | |
type Graph[N DataType, E DataType] struct { | |
Nodes []*Node[N, E] `json:"nodes"` | |
} | |
func NewGraph[N DataType, E DataType]() *Graph[N, E] { | |
return &Graph[N, E]{ | |
Nodes: make([]*Node[N, E], 0), | |
} | |
} | |
func (g *Graph[N, E]) AddNode(n *Node[N, E]) { | |
g.Nodes = append(g.Nodes, n) | |
} | |
func (g *Graph[N, E]) Populate(maxNodes, maxScore int, nodeDataGenerator func() N, edgeDataGenerator func() E) { | |
for i := 0; i < maxNodes; i++ { | |
g.AddNode(NewNode[N, E](nodeDataGenerator())) | |
} | |
for i, n := range g.Nodes { | |
for j := range g.Nodes { | |
if i == j { | |
continue | |
} | |
n.Connect(j, rand.Intn(maxScore), edgeDataGenerator()) | |
} | |
} | |
} | |
func (g *Graph[N, E]) String() string { | |
bobTheBuilder := new(strings.Builder) | |
for i, node := range g.Nodes { | |
bobTheBuilder.WriteString("#" + strconv.Itoa(i) + ": ") | |
bobTheBuilder.WriteString(node.String()) | |
bobTheBuilder.WriteRune('\n') | |
} | |
return bobTheBuilder.String() | |
} | |
func (g *Graph[N, E]) Dump() error { | |
f, err := os.Create("dump.json") | |
if err != nil { | |
return err | |
} | |
defer f.Close() | |
gobF, err := os.Create("dump.gob") | |
if err != nil { | |
return err | |
} | |
defer gobF.Close() | |
if err := gob.NewEncoder(gobF).Encode(g); err != nil { | |
return err | |
} | |
return json.NewEncoder(f).Encode(g) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment