[GO] I implemented breadth-first search in python (queue, drawing self-made)

Scenes where breadth-first search (BFS) is required (preface)

I encountered a problem of finding the shortest distance between two points in a tree-structured graph with Atcoder. At that time, I created the algorithm by myself, but I couldn't solve the problem, so I decided to create BFS properly. When actually using it, I will use a convenient library, This time, I will program and organize the basic idea. Reimplementation using the library will be done at a later date.

Implementation

Since the introduction is good, implement it below.

Graph structure class definition

#Creating a graph structure
class cglaph():
  def __init__(self):
    #Node initialization
    self.nodes={}

  def addnode(self,num):#① Add a node
    for i in self.nodes.keys():
      if i==num:
        return(False)
    else:
      self.nodes[num]=list()
      return(True)

  def addedge(self,ag1,ag2):#② Add an edge
    node1=min(ag1,ag2)
    node2=max(ag1,ag2)
    addok=False

    for i in self.nodes.keys():
      if i==node1:
        for j in self.nodes.keys():
          if j==node2:
            addok=True

    if addok:
      self.nodes[node1].append(node2)
      self.nodes[node2].append(node1)

  def printnodes(self):    #③ Display the node
    print("■Glaph:")
    print("vertice:neighbors")
    for k,v in self.nodes.items():
      print(k,":",v)


  def getnodes(self):#④ Returns a list of nodes
    keylist=list()

    for i in self.nodes.keys():
      keylist.append(i)
    return keylist

  def getedge(self, node):#⑤ Returns the edge (connected node) of the specified node.
    return self.nodes[node]

Concept of this tree structure class

Node information is stored in dictionary type. The node number is stored in key, and the nodes connected to that node are stored in a list in value. Insert the following method. ① Add node ② Add edge ③ Display of nodes (and nodes connected to them) ④ Returns a list of nodes ⑤ Returns a list of nodes connected to the specified node

Queue structure class definition

#Definition of queue structure
class cqu():
  def __init__(self):
    #Queue initialization
    self.qu=list()
    self.head=0
    self.tail=-1

  def quval(self):#① Queue size
    return self.tail-self.head+1

  def printqu(self):#② Display the contents of the queue
    print(str(self.qu[self.head:self.tail+1])+",head:"+str(self.head)+",tail:"+str(self.tail))
    print(self.qu)

  def enqu(self,num):#③ Enqueue
    self.qu.append(num)
    self.tail+=1
 
  def dequ(self):#④ Decue
    if self.quval()!=0:
      outv=self.qu[self.head]
      self.head+=1
      return outv

    else:
      return False

Concept of queue structure class

The queue has a list structure and has variables such as pointers that indicate the beginning and end. Have the following method. ① Return the size of the queue ② Display the contents of the queue ③ Enqueue ④ Decue

Creating a tree structure

G=cglaph()

G.addnode(1)#Add node
G.addnode(2)
G.addnode(3)
G.addnode(4)
G.addnode(5)
G.addedge(1,2)#Add edge
G.addedge(2,3)
G.addedge(3,4)
G.addedge(4,5)
G.addedge(2,4)
G.printnodes()#List of nodes

nodelist=G.getnodes()#Get node list
print ("NODE LIST:",nodelist)

G.getedge(1)#Node connected to node 1

The image is the graph below cap1.PNG

BFS implementation


StartNode=1

#Target graph G
G.printnodes()

#List to record distance
NodeList=G.getnodes()
#print(NodeList)
DistList=[0]*len(NodeList)

#Queue structure generation
Q=cqu()

#① Enqueue the search start node
Q.enqu(StartNode)
#Q.printqu()

while Q.quval():#② Loop until the size of the queue becomes 0
  #print("=====loop=====")
  #Q.printqu()
  #print("Qval"+str(Q.quval()))

  checknode=Q.dequ()#③ Decue
  #print("deQ:"+str(checknode))

  nextnodes=G.getedge(checknode)#④ Acquire the node connected to the node acquired by enqueue
  #print("next nodes:"+str(nextnodes))

  for i in nextnodes:#⑤ Give a distance to each connected node
    #print(i)
    if DistList[NodeList.index(i)]==0:#⑥ Judge whether it has been searched (distance has been given to the node)
      if i!=StartNode:#⑦ Search start node is out of scope
        #print("enq")
        Q.enqu(i)#⑧ Enqueue, give distance if not searched (make it searched)
        DistList[NodeList.index(i)]=DistList[NodeList.index(checknode)]+1#⑨ Search Increase the distance from the original node by +1
    
    #print(DistList)

print("Distance list",DistList)

If it is a simple implementation, there are many on other sites, so I have left a comment for debugging that I am creating.

The algorithm is to dequeue and determine the starting node. Enqueue the node connected to the departure node. repeat.

Drawing graphs and search results

import matplotlib.pyplot as plt
import collections
import copy

#Drawing a graph according to the search distance
N=len(nodelist)
x=DistList#x coordinate is distance
y=[0]*N#For the Y coordinate, nodes with the same X coordinate are arranged at equal intervals (the equal intervals are calculated below).===
c=collections.Counter(DistList)#Find the number of overlapping elements.
tmp=c.most_common()

c2=collections.Counter(DistList)#Correction counter


tmpmean=copy.deepcopy(tmp)
for i in range(len(tmp)):
  tmpmean[i]=(c[i]-1)*0.5+1


for i,n in zip(DistList,range(N)):
  if c[i]!=1:#1 is y=0 line
    y[n]=-c2[i]+tmpmean[i]
    c2[i]-=1
#===So far x,I just want to find the y coordinate

print("x:",x)
print("y:",y)

#Graph creation
plt.figure(1)

#Node drawing
plt.scatter(x,y)

#Give the node name to the node position
ax=plt.axes()
for i in range(N):
  ax.annotate(str(nodelist[i])+":"+str(DistList[i]),(x[i],y[i]),size=20)

#Draw edges
for i in nodelist:
  edges=G.getedge(i)
  for j in edges:
    plt.plot((x[nodelist.index(i)],x[nodelist.index(j)]),(y[nodelist.index(i)],y[nodelist.index(j)]), color='red')


plt.xlim(-1, 5)
plt.ylim(-3, 3)

cap2.PNG

The annotation attached to each node is (node number: distance from the search start node).

Summary, future issues

-BFS itself can be easily implemented using a queue structure. ・ We will summarize the implementation using the library in anticipation of practice. -If multiple nodes with the same distance (same hierarchy) continue in succession, the graph will be twisted. Examine the graph drawing algorithm.

References

BFS (Breadth-first Search) Super Introduction! ~ Use the queue vividly ~

[Graph drawing algorithm and behind Networkx] (https://qiita.com/odanny/items/7c550010f5915ae4acdc)

Create your own graph structure class and its drawing with python

Note about the very useful Python dictionary type

Count the number of occurrences of each element in the list with Python Counter

Recommended Posts

I implemented breadth-first search in python (queue, drawing self-made)
Algorithm in Python (breadth-first search, bfs)
I wrote the queue in Python
I implemented Cousera's logistic regression in Python
I implemented Robinson's Bayesian Spam Filter in python
I implemented the inverse gamma function in python
Python Exercise 1-Breadth-first search
Implemented SimRank in Python
Binary search in Python
Graph drawing in python
Queue processing in Python
I implemented Python Logging
Linear search in Python
Binary search in Python (binary search)
Implemented Shiritori in Python
Implement Depth-First Search (DFS) and Breadth-First Search (BFS) in python
I implemented a Vim-like replacement command in Slackbot #Python
[Python] BFS (breadth-first search) ABC168D
I wrote python in Japanese
Drawing candle charts in python
Search for strings in Python
Breadth-first search / bidirectional search (Python version)
Binary search in Python / C ++
Algorithm in Python (binary search)
Stack and Queue in Python
Sudoku solver implemented in Python 3
I understand Python in Japanese!
[Python] Depth-first search and breadth-first search
What I learned in Python
[Python] BFS (breadth-first search) ABC007C
6 Ball puzzle implemented in python
I implemented Donald Knuth's unbiased sequential calculation algorithm in Python
Write a binary search in Python
Implemented image segmentation in python (Union-Find)
[Python] I implemented peripheral Gibbs sampling
Breadth-first search (BPF) Maybe understood (python)
Widrow-Hoff learning rules implemented in Python
Algorithm in Python (depth-first search, dfs)
I wrote Fizz Buzz in Python
Implemented label propagation method in Python
Write a depth-first search in Python
I learned about processes in Python
I can't install scikit-learn in Python
Implemented Perceptron learning rules in Python
I tried Line notification in Python
Implemented in 1 minute! LINE Notify in Python
Depth-first search using stack in Python
I wrote the stack in Python
I tried to solve AtCoder's depth-first search (DFS) in Python (result: TLE ...)
I put Python 2.7 in Sakura VPS 1GB.
I tried to implement PLSA in Python
Ant book in python: Priority queue self-implementation
A simple HTTP client implemented in Python
I tried to implement permutation in Python
I made a payroll program in Python!
Algorithm in Python (ABC 146 C Binary Search
Implementation module "deque" in queue and Python
Try drawing a simple animation in Python
Implemented in Python PRML Chapter 7 Nonlinear SVM
Search and play YouTube videos in Python
I tried to implement PLSA in Python 2