コード例 #1
0
ファイル: UndirectedMatrix.go プロジェクト: tusj/go-graph
// 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
}
コード例 #2
0
ファイル: UndirectedMatrix.go プロジェクト: tusj/go-graph
// 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
}
コード例 #3
0
ファイル: UndirectedMap.go プロジェクト: tusj/go-graph
// 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
}
コード例 #4
0
ファイル: UndirectedMap.go プロジェクト: tusj/go-graph
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
}
コード例 #5
0
ファイル: DirectedMap.go プロジェクト: tusj/go-graph
// 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
}
コード例 #6
0
ファイル: DirectedMap.go プロジェクト: tusj/go-graph
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
}
コード例 #7
0
ファイル: UndirectedMap.go プロジェクト: tusj/go-graph
// 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
}
コード例 #8
0
ファイル: UndirectedMap.go プロジェクト: tusj/go-graph
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
}
コード例 #9
0
ファイル: UndirectedMap.go プロジェクト: tusj/go-graph
// 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
}
コード例 #10
0
ファイル: DirectedMap.go プロジェクト: tusj/go-graph
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
}
コード例 #11
0
ファイル: DirectedMap.go プロジェクト: tusj/go-graph
// 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
}
コード例 #12
0
ファイル: UndirectedMatrix.go プロジェクト: tusj/go-graph
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
}