func removeExactEdges(n *coupling.Node, exact [][]bool) { n.Visited = true for _, row := range n.Adj { for _, edge := range row { // if the edge node adj matrix is nill, we do not have to recursivevly call it, // and just just delete n from its successor slice if edge.To.Adj == nil { coupling.DeleteNodeInSlice(n, &edge.To.Succ) continue } // if the edge has already been visited, we do not have have to recursively call if edge.To.Visited { coupling.DeleteNodeInSlice(n, &edge.To.Succ) continue } // recursively removes edges and successor node bottom up removeExactEdges(edge.To, exact) coupling.DeleteNodeInSlice(n, &edge.To.Succ) } } // here we do the actual removing of edges exact[n.S][n.T] = true exact[n.T][n.S] = true n.Adj = nil n.Visited = false return }
func preparenode() coupling.Node { var n coupling.Node e1 := coupling.Edge{&coupling.Node{S: 0, T: 0}, 0.1, true} e2 := coupling.Edge{&coupling.Node{S: 0, T: 1}, 0.5, true} e3 := coupling.Edge{&coupling.Node{S: 1, T: 0}, 0, false} e4 := coupling.Edge{&coupling.Node{S: 1, T: 1}, 0.4, true} n.Adj = [][]*coupling.Edge{ []*coupling.Edge{&e1, &e2}, []*coupling.Edge{&e3, &e4}} return n }
func findReverseReachable(node *coupling.Node, reachables []*coupling.Node) []*coupling.Node { node.Visited = true for _, succ := range node.Succ { if !coupling.IsNodeInSlice(succ, reachables) { reachables = append(reachables, succ) } if len(succ.Succ) == 0 || succ.Visited { continue } reachables = findReverseReachable(succ, reachables) } node.Visited = false return reachables }
func setUpCoupling() coupling.Coupling { c := coupling.New() n1 := coupling.Node{S: 0, T: 0} n2 := coupling.Node{S: 0, T: 1} n3 := coupling.Node{S: 1, T: 0} n4 := coupling.Node{S: 1, T: 1} e1 := coupling.Edge{&n1, 0.5, true} e2 := coupling.Edge{&n2, 0.2, true} e3 := coupling.Edge{&n3, 0, false} e4 := coupling.Edge{&n4, 0.3, true} n1.Succ = []*coupling.Node{&n1, &n2, &n4} n2.Succ = []*coupling.Node{&n2, &n4, &n1} n4.Succ = []*coupling.Node{&n2, &n1, &n4} n2.Adj = [][]*coupling.Edge{[]*coupling.Edge{&e1, &e2}, []*coupling.Edge{&e3, &e4}} c.Nodes = []*coupling.Node{&n1, &n2, &n3, &n4} return c }
func setUpLinearEquations(n *coupling.Node, exact [][]bool, d [][]float64, a *[][]float64, b *[]float64, i int, index *[]*coupling.Node, lambda float64) { n.Visited = true for _, row := range n.Adj { for _, edge := range row { // if the node is non-basic, we do not have to look at it if !edge.Basic { continue } // if the node is exact, we add its probablity times its distance to the i'th row in the b vector if exact[edge.To.S][edge.To.T] { (*b)[i] += d[edge.To.S][edge.To.T] * edge.Prob * lambda continue } // if the node has already been visited, we do not have to add it as a new linear equation // and subtract its probability from its corresponding place in the a matrix if edge.To.Visited { rowindex := findRowIndex(index, edge.To) (*a)[i][rowindex] -= edge.Prob * lambda continue } // we have to add a new linear equation, so we update a, b, and index addLinearEquation(a, b, index, edge.To) (*a)[i][len(*a)-1] -= edge.Prob * lambda // recursively sets up the linear equation setUpLinearEquations(edge.To, exact, d, a, b, len(*a)-1, index, lambda) } } return }