Skip to content

Commit

Permalink
Improved the memory overhead of GetComponent
Browse files Browse the repository at this point in the history
  • Loading branch information
cem-okulmus authored and cem-okulmus committed Aug 6, 2022
1 parent 3e4e843 commit 24fb6d0
Show file tree
Hide file tree
Showing 15 changed files with 62 additions and 35 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2021 Cem Okulmus
Copyright (c) 2022 Cem Okulmus

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
4 changes: 3 additions & 1 deletion algorithms/balsepGlobal.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"runtime"

"github.com/cem-okulmus/BalancedGo/lib"
"github.com/cem-okulmus/disjoint"
)

// BalSepGlobal implements the global Balanced Separator algorithm.
Expand Down Expand Up @@ -124,6 +125,7 @@ func (b BalSepGlobal) findDecomp(H lib.Graph) lib.Decomp {
generators := lib.SplitCombin(edges.Len(), b.K, runtime.GOMAXPROCS(-1), false)
parallelSearch := b.Generator.GetSearch(&H, &edges, b.BalFactor, generators)
pred := lib.BalancedCheck{}
var Vertices = make(map[int]*disjoint.Element)
parallelSearch.FindNext(pred) // initial Search

OUTER:
Expand All @@ -132,7 +134,7 @@ OUTER:

// log.Printf("Balanced Sep chosen: %+v\n", Graph{Edges: balsep})

comps, _, _ := H.GetComponents(balsep)
comps, _, _ := H.GetComponents(balsep, Vertices)

// log.Printf("Comps of Sep: %+v\n", comps)

Expand Down
6 changes: 4 additions & 2 deletions algorithms/balsepHybrid.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strconv"

"github.com/cem-okulmus/BalancedGo/lib"
"github.com/cem-okulmus/disjoint"
)

// BalSepHybrid implements a hybridised algorithm, using BalSep Local and DetKDecomp in tandem
Expand Down Expand Up @@ -79,6 +80,7 @@ func (b BalSepHybrid) findDecomp(currentDepth int, H lib.Graph) lib.Decomp {
generators := lib.SplitCombin(edges.Len(), b.K, runtime.GOMAXPROCS(-1), true)
parallelSearch := b.Generator.GetSearch(&H, &edges, b.BalFactor, generators)
pred := lib.BalancedCheck{}
var Vertices = make(map[int]*disjoint.Element)
parallelSearch.FindNext(pred) // initial Search

var cache map[uint32]struct{}
Expand All @@ -96,7 +98,7 @@ func (b BalSepHybrid) findDecomp(currentDepth int, H lib.Graph) lib.Decomp {

INNER:
for !exhaustedSubedges {
comps, _, _ := H.GetComponents(balsep)
comps, _, _ := H.GetComponents(balsep, Vertices)

// log.Printf("Comps of Sep: %+v\n", comps)

Expand Down Expand Up @@ -175,7 +177,7 @@ func (b BalSepHybrid) findDecomp(currentDepth int, H lib.Graph) lib.Decomp {
continue thisLoop
}

if pred.Check(&H, &balsep, b.BalFactor) {
if pred.Check(&H, &balsep, b.BalFactor, Vertices) {
cache[lib.IntHash(balsep.Vertices())] = lib.Empty
nextBalsepFound = true
}
Expand Down
6 changes: 4 additions & 2 deletions algorithms/balsepHybridSeq.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strconv"

"github.com/cem-okulmus/BalancedGo/lib"
"github.com/cem-okulmus/disjoint"
)

// BalSepHybridSeq is a purely sequential version of BalSepHybrid
Expand Down Expand Up @@ -67,6 +68,7 @@ func (s BalSepHybridSeq) findDecomp(currentDepth int, H lib.Graph) lib.Decomp {
generators := lib.SplitCombin(edges.Len(), s.K, 1, true) // create just one goroutine, making this sequential
parallelSearch := s.Generator.GetSearch(&H, &edges, s.BalFactor, generators)
pred := lib.BalancedCheck{}
var Vertices = make(map[int]*disjoint.Element)
parallelSearch.FindNext(pred) // initial Search

var cache map[uint32]struct{}
Expand All @@ -85,7 +87,7 @@ func (s BalSepHybridSeq) findDecomp(currentDepth int, H lib.Graph) lib.Decomp {

INNER:
for !exhaustedSubedges {
comps, _, _ := H.GetComponents(balsep)
comps, _, _ := H.GetComponents(balsep, Vertices)

// log.Printf("Comps of Sep: %+v\n", comps)

Expand Down Expand Up @@ -165,7 +167,7 @@ func (s BalSepHybridSeq) findDecomp(currentDepth int, H lib.Graph) lib.Decomp {
continue thisLoop
}

if pred.Check(&H, &balsep, s.BalFactor) {
if pred.Check(&H, &balsep, s.BalFactor, Vertices) {
cache[lib.IntHash(balsep.Vertices())] = lib.Empty
nextBalsepFound = true
}
Expand Down
9 changes: 6 additions & 3 deletions algorithms/balsepLocal.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"runtime"

"github.com/cem-okulmus/BalancedGo/lib"
"github.com/cem-okulmus/disjoint"
)

// BalSepLocal implements the local Balanced Separator algorithm for computing GHDs.
Expand Down Expand Up @@ -56,13 +57,14 @@ func searchSubEdge(g *BalSepLocal, H *lib.Graph, balsepOrig lib.Edges, sepSub *l
}
nextBalsepFound := false
pred := lib.BalancedCheck{}
var Vertices = make(map[int]*disjoint.Element)

for !nextBalsepFound {
if sepSub.HasNext() {
balsep = sepSub.GetCurrent()
// log.Printf("Testing SSSep: %v of %v , Special Edges %v \n", Graph{Edges: balsep},
// Graph{Edges: balsepOrig}, Sp)
if pred.Check(H, &balsep, g.BalFactor) {
if pred.Check(H, &balsep, g.BalFactor, Vertices) {
nextBalsepFound = true
}
} else {
Expand Down Expand Up @@ -91,6 +93,7 @@ func (b BalSepLocal) findDecomp(H lib.Graph) lib.Decomp {
generators := lib.SplitCombin(edges.Len(), b.K, runtime.GOMAXPROCS(-1), true)
parallelSearch := b.Generator.GetSearch(&H, &edges, b.BalFactor, generators)
pred := lib.BalancedCheck{}
var Vertices = make(map[int]*disjoint.Element)
parallelSearch.FindNext(pred) // initial Search

var cache map[uint32]struct{}
Expand All @@ -108,7 +111,7 @@ func (b BalSepLocal) findDecomp(H lib.Graph) lib.Decomp {

INNER:
for !exhaustedSubedges {
comps, _, _ := H.GetComponents(balsep)
comps, _, _ := H.GetComponents(balsep, Vertices)

// log.Printf("Comps of Sep: %v for H %v \n", comps, H)

Expand Down Expand Up @@ -143,7 +146,7 @@ func (b BalSepLocal) findDecomp(H lib.Graph) lib.Decomp {
if ok { //skip since already seen
continue thisLoop
}
if pred.Check(&H, &balsep, b.BalFactor) {
if pred.Check(&H, &balsep, b.BalFactor, Vertices) {
cache[lib.IntHash(balsep.Vertices())] = lib.Empty
nextBalsepFound = true
}
Expand Down
5 changes: 4 additions & 1 deletion algorithms/detKDecomp.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"reflect"

"github.com/cem-okulmus/BalancedGo/lib"
"github.com/cem-okulmus/disjoint"
)

// DetKDecomp computes for a graph and some width K a HD of width K if it exists
Expand Down Expand Up @@ -106,6 +107,8 @@ func (d *DetKDecomp) findDecomp(H lib.Graph, oldSep []int, recDepth int) lib.Dec

gen := lib.NewCover(d.K, conn, bound, H.Edges.Vertices())

var Vertices = make(map[int]*disjoint.Element)

OUTER:
for gen.HasNext {
out := gen.NextSubset()
Expand Down Expand Up @@ -167,7 +170,7 @@ OUTER:
for true {

// log.Println("Sep chosen ", sepActual, " out ", out)
comps, _, _ := H.GetComponents(sepActual)
comps, _, _ := H.GetComponents(sepActual, Vertices)

//check cache for previous encounters
if d.cache.CheckNegative(sepActual, comps) {
Expand Down
6 changes: 4 additions & 2 deletions algorithms/jCostBalsepLocal.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"runtime"

"github.com/cem-okulmus/BalancedGo/lib"
"github.com/cem-okulmus/disjoint"
)

// BalSepLocal implements the local Balanced Separator algorithm for computing GHDs.
Expand Down Expand Up @@ -176,6 +177,7 @@ func (b JCostBalSepLocal) findDecomp(H lib.Graph) lib.Decomp {
generators := lib.SplitCombin(edges.Len(), b.K, runtime.GOMAXPROCS(-1), false)
parallelSearch := b.Generator.GetSearch(&H, &edges, b.BalFactor, generators)
pred := lib.BalancedCheck{}
var Vertices = make(map[int]*disjoint.Element)
// parallelSearch.FindNext(pred) // initial Search

var cache map[uint32]struct{}
Expand All @@ -196,7 +198,7 @@ func (b JCostBalSepLocal) findDecomp(H lib.Graph) lib.Decomp {

INNER:
for !exhaustedSubedges {
comps, _, _ := H.GetComponents(balsep)
comps, _, _ := H.GetComponents(balsep, Vertices)

// log.Printf("Comps of Sep: %v for H %v \n", comps, H)

Expand Down Expand Up @@ -231,7 +233,7 @@ func (b JCostBalSepLocal) findDecomp(H lib.Graph) lib.Decomp {
if ok { //skip since already seen
continue thisLoop
}
if pred.Check(&H, &balsep, b.BalFactor) {
if pred.Check(&H, &balsep, b.BalFactor, Vertices) {
cache[lib.IntHash(balsep.Vertices())] = lib.Empty
nextBalsepFound = true
}
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.12

require (
github.com/alecthomas/participle v0.3.0
github.com/cem-okulmus/disjoint v1.1.2
github.com/google/go-cmp v0.3.1
github.com/json-iterator/go v1.1.12 // indirect
github.com/spakin/disjoint v0.0.0-20170506060253-925e67a26b59
github.com/json-iterator/go v1.1.12
)
5 changes: 2 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/alecthomas/participle v0.3.0 h1:e8vhrYR1nDjzDxyDwpLO27TWOYWilaT+glkwbPadj50=
github.com/alecthomas/participle v0.3.0/go.mod h1:SW6HZGeZgSIpcUWX3fXpfZhuaWHnmoD5KCVaqSaNTkk=
github.com/cem-okulmus/disjoint v1.1.2 h1:1sqm6+PUZ32ZDOSlKf0ouQPfpLFvLKEoQqjVmknI/NQ=
github.com/cem-okulmus/disjoint v1.1.2/go.mod h1:EvfCBnA21Jt7LcF3pPDUXgKH6VbZx3MTclls/UzuCQU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -14,10 +16,7 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spakin/disjoint v0.0.0-20170506060253-925e67a26b59 h1:WXIGODNpYrroHXcn28J3u4XA0Fa3vwxw27uJZVwCrAI=
github.com/spakin/disjoint v0.0.0-20170506060253-925e67a26b59/go.mod h1:847lZUtrAEz7RTzAsdAiOC8gq4kqb3lbmtQjWo6naTA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
12 changes: 8 additions & 4 deletions lib/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package lib
import (
"bytes"

"github.com/cem-okulmus/disjoint"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/spakin/disjoint"
)

// A Graph is a collection of (special) edges
Expand Down Expand Up @@ -100,10 +100,10 @@ func (g Graph) GetSubset(s []int) Edges {
}

// GetComponents uses Disjoint Set data structure to compute connected components
func (g Graph) GetComponents(sep Edges) ([]Graph, map[int]int, []Edge) {
func (g Graph) GetComponents(sep Edges, vertices map[int]*disjoint.Element) ([]Graph, map[int]int, []Edge) {
var outputG []Graph

var vertices = make(map[int]*disjoint.Element, len(g.Vertices()))
// var vertices = make(map[int]*disjoint.Element, len(g.Vertices()))
var comps = make(map[*disjoint.Element][]Edge)
var compsSp = make(map[*disjoint.Element][]Edges)

Expand All @@ -115,7 +115,11 @@ func (g Graph) GetComponents(sep Edges) ([]Graph, map[int]int, []Edge) {

// Set up the disjoint sets for each node
for _, i := range g.Vertices() {
vertices[i] = disjoint.NewElement()
if e, ok := vertices[i]; ok {
e.Reset()
} else {
vertices[i] = disjoint.NewElement()
}
}

// Merge together the connected components
Expand Down
5 changes: 4 additions & 1 deletion lib/hinge.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"bytes"
"log"
"reflect"

"github.com/cem-okulmus/disjoint"
)

type hingeEdge struct {
Expand Down Expand Up @@ -109,8 +111,9 @@ func (h Hingetree) expandHingeTree(isUsed map[int]bool, parentE int) Hingetree {
continue
}

var Vertices = make(map[int]*disjoint.Element)
sepEdge := NewEdges([]Edge{*e})
hinges, gamma, _ := h.hinge.GetComponents(sepEdge)
hinges, gamma, _ := h.hinge.GetComponents(sepEdge, Vertices)

// Skip reordering step if only single component
if len(hinges) <= 1 {
Expand Down
19 changes: 11 additions & 8 deletions lib/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package lib
import (
"runtime"
"sync"

"github.com/cem-okulmus/disjoint"
)

// A Search implements a parallel search for separators fulfilling some given predicate
Expand Down Expand Up @@ -62,7 +64,7 @@ func (s *ParallelSearch) GetResult() []int {

// A Predicate checks if for some subgraph and a separator, some condition holds
type Predicate interface {
Check(H *Graph, sep *Edges, balancedFactor int) bool
Check(H *Graph, sep *Edges, balancedFactor int, Vertices map[int]*disjoint.Element) bool
}

// FindNext starts the search and stops if some separator which satisfies the predicate
Expand Down Expand Up @@ -117,6 +119,7 @@ func (s ParallelSearch) worker(workernum int, found chan []int, wg *sync.WaitGro
}
}()
defer wg.Done()
var Vertices = make(map[int]*disjoint.Element)

gen := s.Generators[workernum]

Expand All @@ -130,7 +133,7 @@ func (s ParallelSearch) worker(workernum int, found chan []int, wg *sync.WaitGro
j := gen.GetNext()

sep := GetSubset(*s.Edges, j)
if pred.Check(s.H, &sep, s.BalFactor) {
if pred.Check(s.H, &sep, s.BalFactor, Vertices) {
gen.Found() // cache result
found <- j
// log.Println("Worker", workernum, "won, found: ", j)
Expand All @@ -146,10 +149,10 @@ func (s ParallelSearch) worker(workernum int, found chan []int, wg *sync.WaitGro
type BalancedCheck struct{}

// Check performs the needed computation to ensure whether sep is a Balanced Separator
func (b BalancedCheck) Check(H *Graph, sep *Edges, balFactor int) bool {
func (b BalancedCheck) Check(H *Graph, sep *Edges, balFactor int, Vertices map[int]*disjoint.Element) bool {

//balancedness condition
comps, _, _ := H.GetComponents(*sep)
comps, _, _ := H.GetComponents(*sep, Vertices)

balancednessLimit := (((H.Len()) * (balFactor - 1)) / balFactor)

Expand All @@ -170,10 +173,10 @@ func (b BalancedCheck) Check(H *Graph, sep *Edges, balFactor int) bool {
}

// CheckOut does the same as Check, except it also passes on the components found, if output is true
func (b BalancedCheck) CheckOut(H *Graph, sep *Edges, balFactor int) (bool, []Graph, []Edge) {
func (b BalancedCheck) CheckOut(H *Graph, sep *Edges, balFactor int, Vertices map[int]*disjoint.Element) (bool, []Graph, []Edge) {

//balancedness condition
comps, _, isolated := H.GetComponents(*sep)
comps, _, isolated := H.GetComponents(*sep, Vertices)

balancednessLimit := (((H.Len()) * (balFactor - 1)) / balFactor)

Expand Down Expand Up @@ -201,10 +204,10 @@ type ParentCheck struct {
}

// Check performs the needed computation to ensure whether sep is a good parent
func (p ParentCheck) Check(H *Graph, sep *Edges, balFactor int) bool {
func (p ParentCheck) Check(H *Graph, sep *Edges, balFactor int, Vertices map[int]*disjoint.Element) bool {

//balancedness condition
comps, _, _ := H.GetComponents(*sep)
comps, _, _ := H.GetComponents(*sep, Vertices)

foundCompLow := false
var compLow Graph
Expand Down
4 changes: 3 additions & 1 deletion test/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/cem-okulmus/BalancedGo/lib"
"github.com/cem-okulmus/disjoint"
)

var EDGE int
Expand Down Expand Up @@ -86,9 +87,10 @@ func TestCache(t *testing.T) {
var cache lib.Cache
var cacheCopy lib.Cache

var Vertices = make(map[int]*disjoint.Element)
cache.CopyRef(&cacheCopy)

comps, _, _ := randomGraph.GetComponents(randomSep)
comps, _, _ := randomGraph.GetComponents(randomSep, Vertices)

if len(comps) == 0 { // randomSep covers the entire hypergraph. Nothing you can do
return
Expand Down
Loading

0 comments on commit 24fb6d0

Please sign in to comment.