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 TestCorrectDeletedSuccNodes(t *testing.T) { c := setUpCoupling() succ := c.Nodes[0].Succ coupling.DeleteNodeInSlice(succ[0], &succ) assert.Equal(t, len(succ), 2, "length of the successor slice did not change") coupling.DeleteNodeInSlice(succ[0], &succ) assert.Equal(t, len(succ), 1, "length of the successor slice did not change") }
func updateEdge(edge *coupling.Edge, signal bool, min float64, n *coupling.Node) { if signal { log.Printf("increasing at cell (%v,%v)", edge.To.S, edge.To.T) // increase and set the node to basic edge.Prob += min if !edge.Basic { edge.Basic = true n.BasicCount++ } // add the main node as a successor to the node if it not already is if !coupling.IsNodeInSlice(n, edge.To.Succ) { edge.To.Succ = append(edge.To.Succ, n) } } else { log.Printf("decreasing at cell (%v,%v)", edge.To.S, edge.To.T) edge.Prob -= min // if the line edge.Prob -= min, makes edge.Prob to zero, it is not a basic cell edge.Basic = !utils.ApproxEqual(edge.Prob, 0) // if no longer basic remove the main node as a successor for the node if !edge.Basic { coupling.DeleteNodeInSlice(n, &edge.To.Succ) n.BasicCount-- } } edge.To.Visited = false }
func updateNode(node *coupling.Node, newValues []float64) { if (len(node.Adj) * len(node.Adj[0])) != len(newValues) { log.Printf("%v %v", (len(node.Adj) * len(node.Adj[0])), len(newValues)) panic("The amount of new values does not match the adjacency matrix!") } k := 0 for i := range (*node).Adj { for _, edge := range (*node).Adj[i] { prevBasic := edge.Basic prob := newValues[k] if utils.ApproxEqual(prob, 0.0) { edge.Basic = false coupling.DeleteNodeInSlice(node, &edge.To.Succ) if prevBasic { node.BasicCount-- } } else { edge.Basic = true if !prevBasic { node.BasicCount++ } if !coupling.IsNodeInSlice(node, edge.To.Succ) { edge.To.Succ = append(edge.To.Succ, node) } } edge.Prob = prob k++ } } }
func setZerosDistanceToZero(n *coupling.Node, nonzero []*coupling.Node, exact [][]bool, d [][]float64, c *coupling.Coupling) { reachables := coupling.Reachable(n) for _, node := range nonzero { coupling.DeleteNodeInSlice(node, &reachables) } for _, node := range reachables { d[node.S][node.T] = 0 exact[node.S][node.T] = true } }
func filterZeros(reachables []*coupling.Node, exact [][]bool, d [][]float64) []*coupling.Node { // copy the reachable set such that we remove elements, without removing them from the original reachablesCopy := make([]*coupling.Node, len(reachables), len(reachables)) copy(reachablesCopy, reachables) for _, node := range reachablesCopy { // if exact and distance above 0, skip it if exact[node.S][node.T] && d[node.S][node.T] > 0 { continue } // otherwise delete it coupling.DeleteNodeInSlice(node, &reachables) } return reachables }