// Removing edge, connecting node1 and node2 func (g *UndirectedMatrix) RemoveEdge(node1, node2 VertexId) { makeError := func(err interface{}) (res erx.Error) { res = erx.NewSequentLevel("Remove edge from graph.", err, 1) res.AddV("node 1", node1) res.AddV("node 2", node2) return } defer func() { // warning! such code generates wrong file/line info about error! // see http://groups.google.com/group/golang-nuts/browse_thread/thread/66bd57dcdac63aa // for details if err := recover(); err != nil { panic(makeError(err)) } }() conn := g.getConnectionId(node1, node2, false) if !g.nodes[conn] { panic(erx.NewError("Edge doesn't exist.")) } g.nodes[conn] = false g.edgesCnt-- return }
// Adding new edge to graph func (g *UndirectedMatrix) AddEdge(node1, node2 VertexId) { makeError := func(err interface{}) (res erx.Error) { res = erx.NewSequentLevel("Add edge to graph.", err, 1) res.AddV("node 1", node1) res.AddV("node 2", node2) return } defer func() { // warning! such code generates wrong file/line info about error! // see http://groups.google.com/group/golang-nuts/browse_thread/thread/66bd57dcdac63aa // for details if err := recover(); err != nil { panic(makeError(err)) } }() var conn int conn = g.getConnectionId(node1, node2, true) if g.nodes[conn] { err := erx.NewError("Duplicate edge.") err.AddV("connection id", conn) panic(makeError(err)) } g.nodes[conn] = true g.edgesCnt++ return }
// Adding single node to graph func (g *UndirectedMap) AddNode(node VertexId) { makeError := func(err interface{}) (res erx.Error) { res = erx.NewSequentLevel("Add node to graph.", err, 1) res.AddV("node id", node) return } if _, ok := g.edges[node]; ok { panic(makeError(erx.NewError("Node already exists."))) } g.edges[node] = make(map[VertexId]bool) return }
func (g *UndirectedMap) RemoveNode(node VertexId) { makeError := func(err interface{}) (res erx.Error) { res = erx.NewSequentLevel("Remove node from graph.", err, 1) res.AddV("node id", node) return } if _, ok := g.edges[node]; !ok { panic(makeError(erx.NewError("Node doesn't exist."))) } g.edges[node] = nil, false for _, connectedVertexes := range g.edges { connectedVertexes[node] = false, false } return }
// Adding arrow to graph. func (g *DirectedMap) AddArc(from, to VertexId) { makeError := func(err interface{}) (res erx.Error) { res = erx.NewSequentLevel("Add arc to graph.", err, 1) res.AddV("tail", from) res.AddV("head", to) return } g.touchNode(from) g.touchNode(to) if direction, ok := g.directArcs[from][to]; ok && direction { panic(makeError(erx.NewError("Duplicate arrow."))) } g.directArcs[from][to] = true g.reversedArcs[to][from] = true g.arcsCnt++ return }
func (g *DirectedMap) CheckArc(from, to VertexId) (isExist bool) { makeError := func(err interface{}) (res erx.Error) { res = erx.NewSequentLevel("Checking arc existance in graph.", err, 1) res.AddV("tail", from) res.AddV("head", to) return } connectedVertexes, ok := g.directArcs[from] if !ok { panic(makeError(erx.NewError("From node doesn't exist."))) } if _, ok = g.reversedArcs[to]; !ok { panic(makeError(erx.NewError("To node doesn't exist."))) } _, isExist = connectedVertexes[to] return }
// Adding arrow to graph. func (g *UndirectedMap) AddEdge(from, to VertexId) { makeError := func(err interface{}) (res erx.Error) { res = erx.NewSequentLevel("Add edge to graph.", err, 1) res.AddV("node 1", from) res.AddV("node 2", to) return } g.touchNode(from) g.touchNode(to) if direction, ok := g.edges[from][to]; ok && direction { panic(makeError(erx.NewError("Duplicate arrow."))) } g.edges[from][to] = true g.edges[to][from] = true g.edgesCnt++ return }
func (g *UndirectedMap) CheckEdge(from, to VertexId) (isExist bool) { makeError := func(err interface{}) (res erx.Error) { res = erx.NewSequentLevel("Check edge existance in graph.", err, 1) res.AddV("node 1", from) res.AddV("node 2", to) return } connectedVertexes, ok := g.edges[from] if !ok { panic(makeError(erx.NewError("Fist node doesn't exist."))) } if _, ok = g.edges[to]; !ok { panic(makeError(erx.NewError("Second node doesn't exist."))) } _, isExist = connectedVertexes[to] return }
// Removing arrow 'from' and 'to' nodes func (g *UndirectedMap) RemoveEdge(from, to VertexId) { makeError := func(err interface{}) (res erx.Error) { res = erx.NewSequentLevel("Remove edge from graph.", err, 1) res.AddV("node 1", from) res.AddV("node 2", to) return } connectedVertexes, ok := g.edges[from] if !ok { panic(makeError(erx.NewError("First node doesn't exists"))) } if _, ok = connectedVertexes[to]; ok { panic(makeError(erx.NewError("Second node doesn't exists"))) } g.edges[from][to] = false, false g.edges[to][from] = false, false g.edgesCnt-- return }
func (g *DirectedMap) RemoveNode(node VertexId) { makeError := func(err interface{}) (res erx.Error) { res = erx.NewSequentLevel("Remove node from graph.", err, 1) res.AddV("node id", node) return } _, okDirect := g.directArcs[node] _, okReversed := g.reversedArcs[node] if !okDirect && !okReversed { panic(makeError(erx.NewError("Node doesn't exist."))) } g.directArcs[node] = nil, false g.reversedArcs[node] = nil, false for _, connectedVertexes := range g.directArcs { connectedVertexes[node] = false, false } for _, connectedVertexes := range g.reversedArcs { connectedVertexes[node] = false, false } return }
// Removing arrow 'from' and 'to' nodes func (g *DirectedMap) RemoveArc(from, to VertexId) { makeError := func(err interface{}) (res erx.Error) { res = erx.NewSequentLevel("Remove arc from graph.", err, 1) res.AddV("tail", from) res.AddV("head", to) return } connectedVertexes, ok := g.directArcs[from] if !ok { panic(makeError(erx.NewError("Tail node doesn't exist."))) } if _, ok = connectedVertexes[to]; ok { panic(makeError(erx.NewError("Head node doesn't exist."))) } g.directArcs[from][to] = false, false g.reversedArcs[to][from] = false, false g.arcsCnt-- return }
func (g *UndirectedMatrix) getConnectionId(node1, node2 VertexId, create bool) int { makeError := func(err interface{}) (res erx.Error) { res = erx.NewSequentLevel("Calculating connection id.", err, 1) res.AddV("node 1", node1) res.AddV("node 2", node2) return } defer func() { // warning! such code generates wrong file/line info about error! // see http://groups.google.com/group/golang-nuts/browse_thread/thread/66bd57dcdac63aa // for details if err := recover(); err != nil { panic(makeError(err)) } }() var id1, id2 int node1Exist := false node2Exist := false id1, node1Exist = g.VertexIds[node1] id2, node2Exist = g.VertexIds[node2] // checking for errors { if node1 == node2 { panic(makeError(erx.NewError("Equal nodes."))) } if !create { if !node1Exist { panic(makeError(erx.NewError("First node doesn't exist in graph"))) } if !node2Exist { panic(makeError(erx.NewError("Second node doesn't exist in graph"))) } } else if !node1Exist || !node2Exist { if node1Exist && node2Exist { if g.size-len(g.VertexIds) < 2 { panic(makeError(erx.NewError("Not enough space to create two new nodes."))) } } else { if g.size-len(g.VertexIds) < 1 { panic(makeError(erx.NewError("Not enough space to create new node."))) } } } } if !node1Exist { id1 = int(len(g.VertexIds)) g.VertexIds[node1] = id1 } if !node2Exist { id2 = int(len(g.VertexIds)) g.VertexIds[node2] = id2 } // switching id1, id2 in order to id1 < id2 if id1 > id2 { id1, id2 = id2, id1 } // id from upper triangle matrix, stored in vector connId := id1*(g.size-1) + id2 - 1 - id1*(id1+1)/2 return connId }