diff --git a/centrality.go b/centrality.go new file mode 100644 index 0000000..246a1d2 --- /dev/null +++ b/centrality.go @@ -0,0 +1,37 @@ +// Copyright (c) 2024 Faculty of Industrial Technology and Management, KMUTNB (Provided by FITM Elite) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package grafik + +import ( + "github.com/fitm-elite/grafik/options" +) + +// WithDijkstraStandard sets the standard algorithm for the specified dijkstra properties in the returned DijkstraOptionFunc. +func WithDijkstraStandard() options.DijkstraOptionFunc { + return func(properties *options.DijkstraProperties) { + properties.UseStandard() + } +} + +// DijkstraCentrality return slice of Vertex that has result of centrality. +func DijkstraCentrality[T comparable](g Grafik[T], opts ...options.DijkstraOptionFunc) []Vertex[T] { + return DijkstraCentrality(g, opts...) +} diff --git a/centrality/dijkstra_centrality.go b/centrality/dijkstra_centrality.go index d47cef1..e71f23a 100644 --- a/centrality/dijkstra_centrality.go +++ b/centrality/dijkstra_centrality.go @@ -25,36 +25,39 @@ import ( "sync" "github.com/fitm-elite/grafik" + "github.com/fitm-elite/grafik/entity" + "github.com/fitm-elite/grafik/options" "github.com/fitm-elite/grafik/pathfinder" ) -// vertexPath represents path of vertex -type vertexPath[T comparable] struct { +// VertexPath represents path of vertex +type VertexPath[T comparable] struct { vertexLabel T averageLength float64 } // Label returns label of vertex path -func (v vertexPath[T]) Label() T { +func (v VertexPath[T]) Label() T { return v.vertexLabel } // AverageLength returns average length of vertex path -func (v vertexPath[T]) AverageLength() float64 { +func (v VertexPath[T]) AverageLength() float64 { return v.averageLength } // DijkstraCentrality It's using a dijkstra method to find shortest path in each vertex // and calculate to find an average value in each path to find a centroid. // -// Returns []vertexPath[T] -func DijkstraCentrality[T comparable](g grafik.Grafik[T], opts ...pathfinder.DijkstraOptionFunc) []vertexPath[T] { +// Returns []VertexPath[T] +func DijkstraCentrality[T comparable](g entity.Grafik[T], opts ...options.DijkstraOptionFunc) []VertexPath[T] { vertices := g.GetAllVertices() - vertexPaths := make([]vertexPath[T], 0, len(vertices)) + vertexPaths := make([]VertexPath[T], 0, len(vertices)) + var mu sync.Mutex var wg sync.WaitGroup - results := make(chan vertexPath[T], len(vertices)) + results := make(chan VertexPath[T], len(vertices)) wg.Add(len(vertices)) for _, v := range vertices { @@ -69,7 +72,7 @@ func DijkstraCentrality[T comparable](g grafik.Grafik[T], opts ...pathfinder.Dij } averageLength := totalLength / float64(len(pathLengths)) - result := vertexPath[T]{ + result := VertexPath[T]{ vertexLabel: label, averageLength: averageLength, } diff --git a/centrality/dijkstra_centrality_test.go b/centrality/dijkstra_centrality_test.go index 71881f4..86c50cf 100644 --- a/centrality/dijkstra_centrality_test.go +++ b/centrality/dijkstra_centrality_test.go @@ -24,7 +24,7 @@ import ( "testing" "github.com/fitm-elite/grafik" - "github.com/fitm-elite/grafik/pathfinder" + "github.com/fitm-elite/grafik/options" ) func TestDijkstraCentrality(t *testing.T) { @@ -38,23 +38,23 @@ func TestDijkstraCentrality(t *testing.T) { vK := g.AddVertexByLabel("K") vQ := g.AddVertexByLabel("Q") - _, _ = g.AddEdge(vA, vB, grafik.WithEdgeWeight(1)) - _, _ = g.AddEdge(vA, vE, grafik.WithEdgeWeight(5)) - _, _ = g.AddEdge(vA, vJ, grafik.WithEdgeWeight(2)) + _, _ = g.AddEdge(vA, vB, options.WithEdgeWeight(1)) + _, _ = g.AddEdge(vA, vE, options.WithEdgeWeight(5)) + _, _ = g.AddEdge(vA, vJ, options.WithEdgeWeight(2)) - _, _ = g.AddEdge(vB, vC, grafik.WithEdgeWeight(3)) - _, _ = g.AddEdge(vB, vE, grafik.WithEdgeWeight(1)) + _, _ = g.AddEdge(vB, vC, options.WithEdgeWeight(3)) + _, _ = g.AddEdge(vB, vE, options.WithEdgeWeight(1)) - _, _ = g.AddEdge(vE, vC, grafik.WithEdgeWeight(4)) - _, _ = g.AddEdge(vE, vJ, grafik.WithEdgeWeight(3)) - _, _ = g.AddEdge(vE, vQ, grafik.WithEdgeWeight(3)) - _, _ = g.AddEdge(vE, vK, grafik.WithEdgeWeight(2)) + _, _ = g.AddEdge(vE, vC, options.WithEdgeWeight(4)) + _, _ = g.AddEdge(vE, vJ, options.WithEdgeWeight(3)) + _, _ = g.AddEdge(vE, vQ, options.WithEdgeWeight(3)) + _, _ = g.AddEdge(vE, vK, options.WithEdgeWeight(2)) - _, _ = g.AddEdge(vJ, vQ, grafik.WithEdgeWeight(1)) + _, _ = g.AddEdge(vJ, vQ, options.WithEdgeWeight(1)) - _, _ = g.AddEdge(vQ, vK, grafik.WithEdgeWeight(2)) + _, _ = g.AddEdge(vQ, vK, options.WithEdgeWeight(2)) - paths := DijkstraCentrality(g, pathfinder.WithDijkstraStandard()) + paths := DijkstraCentrality(g, options.WithDijkstraStandard()) if len(paths) != 7 { t.Errorf("Expected len from paths is %d, got %d", 7, len(paths)) diff --git a/edge.go b/edge.go index fbe8163..3494f39 100644 --- a/edge.go +++ b/edge.go @@ -20,32 +20,17 @@ package grafik -// EdgeOptionFunc represent an alias of function type that -// modifies the specified edge properties. -type EdgeOptionFunc func(properties *EdgeProperties) - -// EdgeProperties represents the properties of an edge. -type EdgeProperties struct { - weight float64 -} - -// WithEdgeWeight sets the edge weight for the specified edge -// properties in the returned EdgeOptionFunc. -func WithEdgeWeight(weight float64) EdgeOptionFunc { - return func(properties *EdgeProperties) { - properties.weight = weight - } -} +import "github.com/fitm-elite/grafik/options" // Edge represents an edges in a graph. It contains start and end points. type Edge[T comparable] struct { source *Vertex[T] // start point of the edges dest *Vertex[T] // destination or end point of the edges - properties EdgeProperties + properties options.EdgeProperties } -func NewEdge[T comparable](source *Vertex[T], dest *Vertex[T], opts ...EdgeOptionFunc) *Edge[T] { +func NewEdge[T comparable](source *Vertex[T], dest *Vertex[T], opts ...options.EdgeOptionFunc) *Edge[T] { e := &Edge[T]{ source: source, dest: dest, @@ -69,5 +54,5 @@ func (e Edge[T]) Destination() *Vertex[T] { // Weight returns the weight of the edge. func (e *Edge[T]) Weight() float64 { - return e.properties.weight + return e.properties.Weight() } diff --git a/edge_test.go b/edge_test.go index 1730de2..2a9920b 100644 --- a/edge_test.go +++ b/edge_test.go @@ -20,7 +20,11 @@ package grafik -import "testing" +import ( + "testing" + + "github.com/fitm-elite/grafik/options" +) func TestEdgeSource(t *testing.T) { vA := NewVertex("A") @@ -52,7 +56,7 @@ func TestEdgeWeight(t *testing.T) { vA := NewVertex("A") vB := NewVertex("B") - e := NewEdge(vA, vB, WithEdgeWeight(weight)) + e := NewEdge(vA, vB, options.WithEdgeWeight(weight)) eWeight := e.Weight() if eWeight != weight { diff --git a/entity/grafik.go b/entity/grafik.go new file mode 100644 index 0000000..1fb302f --- /dev/null +++ b/entity/grafik.go @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Faculty of Industrial Technology and Management, KMUTNB (Provided by FITM Elite) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package entity + +import "github.com/fitm-elite/grafik" + +// Grafik[T comparable] It's using for avoid cycle import. +type Grafik[T comparable] grafik.Grafik[T] diff --git a/grafik.go b/grafik.go index 7f8719d..1cb6af4 100644 --- a/grafik.go +++ b/grafik.go @@ -22,6 +22,8 @@ package grafik import ( "errors" + + "github.com/fitm-elite/grafik/options" ) var ( @@ -42,7 +44,7 @@ type VertexFunc[T comparable] interface { // // If there is a vertex with the same label in the graph, returns nil. // Otherwise, returns the created vertex. - AddVertexByLabel(label T, options ...VertexOptionFunc) *Vertex[T] + AddVertexByLabel(label T, options ...options.VertexOptionFunc) *Vertex[T] // AddVertex adds the input vertex to the graph. It doesn't add // vertex to the graph if the input vertex label is already exists @@ -74,7 +76,7 @@ type EdgeFunc[T comparable] interface { // It creates the input vertices if they don't exist in the graph. // If any of the specified vertices is nil, returns nil. // If edge already exist, returns error. - AddEdge(from, to *Vertex[T], opts ...EdgeOptionFunc) (*Edge[T], error) + AddEdge(from, to *Vertex[T], opts ...options.EdgeOptionFunc) (*Edge[T], error) // GetAllEdges returns a slice of all edges connecting source vertex to // target vertex if such vertices exist in this graph. @@ -140,8 +142,8 @@ func (g *grafik[T]) findVertex(label T) *Vertex[T] { // // If there is a vertex with the same label in the graph, returns nil. // Otherwise, returns the created vertex. -func (g *grafik[T]) AddVertexByLabel(label T, opts ...VertexOptionFunc) *Vertex[T] { - var properties VertexProperties +func (g *grafik[T]) AddVertexByLabel(label T, opts ...options.VertexOptionFunc) *Vertex[T] { + var properties options.VertexProperties for _, opt := range opts { opt(&properties) } @@ -198,7 +200,7 @@ func (g *grafik[T]) ContainsVertex(v *Vertex[T]) bool { // the baseGraph struct. Note that it doesn't add the neighbor to the source vertex. // // It returns the created edge. -func (g *grafik[T]) addToEdgeMap(from, to *Vertex[T], opts ...EdgeOptionFunc) *Edge[T] { +func (g *grafik[T]) addToEdgeMap(from, to *Vertex[T], opts ...options.EdgeOptionFunc) *Edge[T] { edge := NewEdge(from, to, opts...) if _, ok := g.edges[from.label]; !ok { g.edges[from.label] = map[T]*Edge[T]{to.label: edge} @@ -219,7 +221,7 @@ func (g *grafik[T]) addToEdgeMap(from, to *Vertex[T], opts ...EdgeOptionFunc) *E // It creates the input vertices if they don't exist in the graph. // If any of the specified vertices is nil, returns nil. // If edge already exist, returns error. -func (g *grafik[T]) AddEdge(from, to *Vertex[T], opts ...EdgeOptionFunc) (*Edge[T], error) { +func (g *grafik[T]) AddEdge(from, to *Vertex[T], opts ...options.EdgeOptionFunc) (*Edge[T], error) { if from == nil || to == nil { return nil, ErrNilVertices } diff --git a/options/dijkstra_options.go b/options/dijkstra_options.go new file mode 100644 index 0000000..32cfa7b --- /dev/null +++ b/options/dijkstra_options.go @@ -0,0 +1,46 @@ +// Copyright (c) 2024 Faculty of Industrial Technology and Management, KMUTNB (Provided by FITM Elite) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package options + +// DijkstraOptionFunc represent an alias of function type that modifies the specified dijkstra properties. +type DijkstraOptionFunc func(properties *DijkstraProperties) + +// DijkstraProperties represents the properties of an dijkstra. +type DijkstraProperties struct { + useStandard bool +} + +// UseStandard set use standard to true +func (dj *DijkstraProperties) UseStandard() { + dj.useStandard = true +} + +// GetUseStandard return dj.useStandard from DijkstraProperties. +func (dj DijkstraProperties) GetUseStandard() bool { + return dj.useStandard +} + +// WithDijkstraStandard sets the standard algorithm for the specified dijkstra properties in the returned DijkstraOptionFunc. +func WithDijkstraStandard() DijkstraOptionFunc { + return func(properties *DijkstraProperties) { + properties.useStandard = true + } +} diff --git a/options/edge_options.go b/options/edge_options.go new file mode 100644 index 0000000..a3eef0a --- /dev/null +++ b/options/edge_options.go @@ -0,0 +1,43 @@ +// Copyright (c) 2024 Faculty of Industrial Technology and Management, KMUTNB (Provided by FITM Elite) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package options + +// EdgeOptionFunc represent an alias of function type that +// modifies the specified edge properties. +type EdgeOptionFunc func(properties *EdgeProperties) + +// EdgeProperties represents the properties of an edge. +type EdgeProperties struct { + weight float64 +} + +// Weight returns v.weight from VertexProperties +func (v EdgeProperties) Weight() float64 { + return v.weight +} + +// WithEdgeWeight sets the edge weight for the specified edge +// properties in the returned EdgeOptionFunc. +func WithEdgeWeight(weight float64) EdgeOptionFunc { + return func(properties *EdgeProperties) { + properties.weight = weight + } +} diff --git a/options/vertex_options.go b/options/vertex_options.go new file mode 100644 index 0000000..abbf40c --- /dev/null +++ b/options/vertex_options.go @@ -0,0 +1,41 @@ +// Copyright (c) 2024 Faculty of Industrial Technology and Management, KMUTNB (Provided by FITM Elite) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package options + +// VertexOptionFunc represent an alias of function type that modifies the specified vertex properties. +type VertexOptionFunc func(properties *VertexProperties) + +// VertexProperties represents the properties of an edge. +type VertexProperties struct { + weight float64 +} + +// Weight returns v.weight from VertexProperties +func (v VertexProperties) Weight() float64 { + return v.weight +} + +// WithVertexWeight sets the edge weight for the specified vertex properties in the returned VertexOptionFunc. +func WithVertexWeight(weight float64) VertexOptionFunc { + return func(properties *VertexProperties) { + properties.weight = weight + } +} diff --git a/pathfinder/dijkstra_pathfinder.go b/pathfinder/dijkstra_pathfinder.go index b4fbc18..9e190f2 100644 --- a/pathfinder/dijkstra_pathfinder.go +++ b/pathfinder/dijkstra_pathfinder.go @@ -24,24 +24,10 @@ import ( "math" "github.com/fitm-elite/grafik" + "github.com/fitm-elite/grafik/options" "github.com/fitm-elite/grafik/queue" ) -// DijkstraOptionFunc represent an alias of function type that modifies the specified dijkstra properties. -type DijkstraOptionFunc func(properties *DijkstraProperties) - -// DijkstraProperties represents the properties of an dijkstra. -type DijkstraProperties struct { - useStandard bool -} - -// WithDijkstraStandard sets the standard algorithm for the specified dijkstra properties in the returned DijkstraOptionFunc. -func WithDijkstraStandard() DijkstraOptionFunc { - return func(properties *DijkstraProperties) { - properties.useStandard = true - } -} - // dijkstraVertex represents dijkstra vertex. type dijkstraVertex[T comparable] struct { label T @@ -72,8 +58,8 @@ func newDijkstraVertex[T comparable](label T) *dijkstraVertex[T] { // // It returns the shortest distances from the starting vertex to all other vertices // in the graph. -func Dijkstra[T comparable](g grafik.Grafik[T], start T, opts ...DijkstraOptionFunc) map[T]float64 { - var properties DijkstraProperties +func Dijkstra[T comparable](g grafik.Grafik[T], start T, opts ...options.DijkstraOptionFunc) map[T]float64 { + var properties options.DijkstraProperties for _, opt := range opts { opt(&properties) } @@ -86,7 +72,7 @@ func Dijkstra[T comparable](g grafik.Grafik[T], start T, opts ...DijkstraOptionF } // useStandard checker - if !properties.useStandard { + if !properties.GetUseStandard() { vertices := g.GetAllVertices() for _, v := range vertices { dist[v.Label()] = math.MaxFloat64 diff --git a/pathfinder/dijkstra_pathfinder_test.go b/pathfinder/dijkstra_pathfinder_test.go index 92a7f06..c79423b 100644 --- a/pathfinder/dijkstra_pathfinder_test.go +++ b/pathfinder/dijkstra_pathfinder_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/fitm-elite/grafik" + "github.com/fitm-elite/grafik/options" ) func TestSimpleDijkstra(t *testing.T) { @@ -34,11 +35,11 @@ func TestSimpleDijkstra(t *testing.T) { vC := g.AddVertexByLabel("C") vD := g.AddVertexByLabel("D") - _, _ = g.AddEdge(vA, vB, grafik.WithEdgeWeight(4)) - _, _ = g.AddEdge(vA, vC, grafik.WithEdgeWeight(3)) - _, _ = g.AddEdge(vB, vC, grafik.WithEdgeWeight(1)) - _, _ = g.AddEdge(vB, vD, grafik.WithEdgeWeight(2)) - _, _ = g.AddEdge(vC, vD, grafik.WithEdgeWeight(4)) + _, _ = g.AddEdge(vA, vB, options.WithEdgeWeight(4)) + _, _ = g.AddEdge(vA, vC, options.WithEdgeWeight(3)) + _, _ = g.AddEdge(vB, vC, options.WithEdgeWeight(1)) + _, _ = g.AddEdge(vB, vD, options.WithEdgeWeight(2)) + _, _ = g.AddEdge(vC, vD, options.WithEdgeWeight(4)) // use not existing vertex dist := Dijkstra(g, "X") @@ -70,14 +71,14 @@ func TestStandardDijkstra(t *testing.T) { v3 := g.AddVertexByLabel(3) v4 := g.AddVertexByLabel(4) - _, _ = g.AddEdge(v1, v2, grafik.WithEdgeWeight(4)) - _, _ = g.AddEdge(v1, v3, grafik.WithEdgeWeight(3)) - _, _ = g.AddEdge(v2, v3, grafik.WithEdgeWeight(1)) - _, _ = g.AddEdge(v2, v4, grafik.WithEdgeWeight(2)) - _, _ = g.AddEdge(v3, v4, grafik.WithEdgeWeight(4)) + _, _ = g.AddEdge(v1, v2, options.WithEdgeWeight(4)) + _, _ = g.AddEdge(v1, v3, options.WithEdgeWeight(3)) + _, _ = g.AddEdge(v2, v3, options.WithEdgeWeight(1)) + _, _ = g.AddEdge(v2, v4, options.WithEdgeWeight(2)) + _, _ = g.AddEdge(v3, v4, options.WithEdgeWeight(4)) // use not existing vertex - dist := Dijkstra(g, 0, WithDijkstraStandard()) + dist := Dijkstra(g, 0, options.WithDijkstraStandard()) if len(dist) > 0 { t.Errorf("Expected dist map length be 0, got %d", len(dist)) } diff --git a/vertex.go b/vertex.go index aab015a..ca09e29 100644 --- a/vertex.go +++ b/vertex.go @@ -20,20 +20,7 @@ package grafik -// VertexOptionFunc represent an alias of function type that modifies the specified vertex properties. -type VertexOptionFunc func(properties *VertexProperties) - -// VertexProperties represents the properties of an edge. -type VertexProperties struct { - weight float64 -} - -// WithVertexWeight sets the edge weight for the specified vertex properties in the returned VertexOptionFunc. -func WithVertexWeight(weight float64) VertexOptionFunc { - return func(properties *VertexProperties) { - properties.weight = weight - } -} +import "github.com/fitm-elite/grafik/options" // Vertex represents a node or point in a graph type Vertex[T comparable] struct { @@ -42,10 +29,10 @@ type Vertex[T comparable] struct { neighbors []*Vertex[T] - properties VertexProperties + properties options.VertexProperties } -func NewVertex[T comparable](label T, opts ...VertexOptionFunc) *Vertex[T] { +func NewVertex[T comparable](label T, opts ...options.VertexOptionFunc) *Vertex[T] { v := &Vertex[T]{label: label} for _, opt := range opts { opt(&v.properties) @@ -109,5 +96,5 @@ func (v *Vertex[T]) Neighbors() []*Vertex[T] { // Weight returns vertex weight. func (v *Vertex[T]) Weight() float64 { - return v.properties.weight + return v.properties.Weight() } diff --git a/vertex_test.go b/vertex_test.go index 8e7da95..ce101fd 100644 --- a/vertex_test.go +++ b/vertex_test.go @@ -20,7 +20,11 @@ package grafik -import "testing" +import ( + "testing" + + "github.com/fitm-elite/grafik/options" +) func TestVertexLabelFunc(t *testing.T) { label := "A" @@ -37,7 +41,7 @@ func TestVertexWeightFunc(t *testing.T) { label := "B" weight := 4.00 - vB := NewVertex(label, WithVertexWeight(weight)) + vB := NewVertex(label, options.WithVertexWeight(weight)) vBWeight := vB.Weight() if vBWeight != weight {