Skip to content

Commit

Permalink
feat: simplify common predecessors
Browse files Browse the repository at this point in the history
  • Loading branch information
moul committed Jul 19, 2019
1 parent 3706f90 commit 4ebaf58
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 50 deletions.
5 changes: 4 additions & 1 deletion attr.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ func (a Attrs) String() string {
}
elems := []string{}
for key, val := range a {
elems = append(elems, fmt.Sprintf("%v:%v", key, val))
valStr := fmt.Sprintf("%v", val)
if valStr != "" {
elems = append(elems, fmt.Sprintf("%s:%s", key, valStr))
}
}
sort.Strings(elems)
return fmt.Sprintf("[%s]", strings.Join(elems, ","))
Expand Down
73 changes: 71 additions & 2 deletions edge.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ package graphman

import (
"fmt"
"sort"
"strings"
)

//
// Edge
//

type Edge struct {
src *Vertex
dst *Vertex
src *Vertex
dst *Vertex
deleted bool // temporary variable used by gc()
Attrs
}

Expand Down Expand Up @@ -56,12 +62,75 @@ func (e *Edge) OtherVertex(id string) *Vertex {
return nil
}

//
// Edges
//

type Edges []*Edge

func (e Edges) filtered() Edges {
filtered := Edges{}
for _, edge := range e {
if !edge.deleted {
filtered = append(filtered, edge)
}
}
return filtered
}

func (e Edges) String() string {
items := []string{}
for _, edge := range e {
items = append(items, edge.String())
}
return fmt.Sprintf("{%s}", strings.Join(items, ","))
}

func (e Edges) Equals(other Edges) bool {
tmp := map[*Edge]int{}
for _, edge := range e {
tmp[edge]++
}
for _, edge := range other {
tmp[edge]--
}
for _, v := range tmp {
if v != 0 {
return false
}
}
return true
}

// AllCombinations returns the different combinations of Edges in a group of Edges
//
// Adapted from https://github.com/mxschmitt/golang-combinations
func (e Edges) AllCombinations() EdgesCombinations {
combinations := EdgesCombinations{}
length := uint(len(e))

for combinationBits := 1; combinationBits < (1 << length); combinationBits++ {
var combination Edges
for object := uint(0); object < length; object++ {
if (combinationBits>>object)&1 == 1 {
combination = append(combination, e[object])
}
}
combinations = append(combinations, combination)
}

return combinations
}

//
// EdgesCombinations
//

type EdgesCombinations []Edges

func (ec EdgesCombinations) LongestToShortest() EdgesCombinations {
sort.Slice(ec, func(i, j int) bool {
return len(ec[i]) > len(ec[j])
})
return ec
}
20 changes: 20 additions & 0 deletions examples/pertify/la-methode-pert-p101.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,79 @@
actions:
- id: "a"
estimate: [7]
title: "a"
- id: "b"
title: "b"
estimate: [8]
- id: "c"
title: "c"
estimate: [9]
- id: "d"
title: "d"
estimate: [10]
depends_on: ["a", "e"]
- id: "e"
title: "e"
estimate: [2]
depends_on: ["b", "f"]
- id: "f"
title: "f"
estimate: [6]
depends_on: ["c"]
- id: "g"
title: "g"
estimate: [14]
depends_on: ["b", "f"]
- id: "h"
title: "h"
estimate: [7]
depends_on: ["b", "f"]
- id: "i"
title: "i"
estimate: [6]
depends_on: ["b", "f"]
- id: "j"
title: "j"
estimate: [5]
depends_on: ["c"]
- id: "k"
title: "k"
estimate: [2]
depends_on: ["c"]
- id: "l"
title: "l"
estimate: [2]
depends_on: ["d", "g"]
- id: "m"
title: "m"
estimate: [18]
depends_on: ["l", "h"]
- id: "n"
title: "n"
estimate: [9]
depends_on: ["i", "j"]
- id: "o"
title: "o"
estimate: [16]
depends_on: ["k"]
- id: "p"
title: "p"
estimate: [21]
depends_on: ["k"]
- id: "q"
title: "q"
estimate: [9]
depends_on: ["m", "r"]
- id: "r"
title: "r"
estimate: [12]
depends_on: ["n", "o"]
- id: "s"
title: "s"
estimate: [14]
depends_on: ["p"]
- id: "t"
title: "t"
estimate: [6]
depends_on: ["s"]

Expand Down
47 changes: 47 additions & 0 deletions examples/pertify/pert-and-cpm-p35.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
actions:
- id: A
title: A
- id: B
title: B
- id: C
title: C
- id: D
title: D
depends_on: ["3"]
- id: E
title: E
depends_on: ["4"]
- id: F
title: F
depends_on: ["5"]
- id: G
title: G
depends_on: ["6"]
- id: H
title: H
- id: I
title: I
depends_on: ["7"]

states:
- id: "1"
title: "1"
depends_on: ["A"]
- id: "2"
title: "2"
depends_on: ["B"]
- id: "3"
title: "3"
depends_on: ["C", "1"]
- id: "4"
title: "4"
depends_on: ["1", "2"]
- id: "5"
title: "5"
depends_on: ["1", "2"]
- id: "6"
title: "6"
depends_on: ["1", "2"]
- id: "7"
title: "7"
depends_on: ["2", "H"]
37 changes: 32 additions & 5 deletions graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (g Graph) SinkVertices() Vertices {
sinks = append(sinks, vertex)
}
}
return sinks
return sinks.filtered()
}

func (g Graph) ConnectedSubgraphs() Graphs {
Expand Down Expand Up @@ -81,7 +81,7 @@ func (g Graph) ConnectedSubgraphFromVertex(start *Vertex) *Graph {
func (g Graph) SourceVertices() Vertices {
sources := Vertices{}
for _, vertex := range g.vertices {
if vertex.IsSource() {
if !vertex.deleted && vertex.IsSource() {
sources = append(sources, vertex)
}
}
Expand Down Expand Up @@ -186,7 +186,32 @@ func (g Graph) Edges() Edges {

func (g Graph) Vertices() Vertices {
sort.Sort(g.vertices)
return g.vertices
return g.vertices.filtered()
}

func (g *Graph) gc() uint {
removed := uint(0)
verticesToDelete := Vertices{}
for _, vertex := range g.vertices {
if vertex.deleted {
verticesToDelete = append(verticesToDelete, vertex)
}
}
edgesToDelete := Edges{}
for _, edge := range g.edges {
if edge.deleted {
edgesToDelete = append(edgesToDelete, edge)
}
}
for _, edge := range edgesToDelete {
removed++
g.RemoveEdge(edge.src.id, edge.dst.id)
}
for _, vertex := range verticesToDelete {
removed++
g.RemoveVertex(vertex.id)
}
return removed
}

func (g *Graph) AddVertex(id string, attrs ...Attrs) *Vertex {
Expand All @@ -211,6 +236,7 @@ func (g *Graph) AddVertex(id string, attrs ...Attrs) *Vertex {
func (g *Graph) RemoveVertex(id string) bool {
for k, v := range g.vertices {
if v.id == id {
v.deleted = true
g.vertices = append(g.vertices[:k], g.vertices[k+1:]...)
return true
}
Expand All @@ -219,8 +245,9 @@ func (g *Graph) RemoveVertex(id string) bool {
}

func (g *Graph) RemoveEdge(src, dst string) bool {
for k, v := range g.edges {
if v.src.id == src && v.dst.id == dst {
for k, e := range g.edges {
if e.src.id == src && e.dst.id == dst {
e.deleted = true
g.edges = append(g.edges[:k], g.edges[k+1:]...)
return true
}
Expand Down
Loading

0 comments on commit 4ebaf58

Please sign in to comment.