[
  {
    "path": "A_star_search/README.md",
    "content": "# Visualisation of A* Search using networkx library\n\n### A* Search ###\n\nA* search( pronounced as \"A star\") is a search algorithm which explores a graph by expanding the that node which minimizes steps from the source(like in BFS) as well as approximate steps to the goal(like in greedy bfs). Hence, this algorithm is thorough and fast as it combines the strengths of both BFS and Greedy BFS.\nA* algorithm is proven to give the optimal solution to a problem.\n\nWhat is the evaluation function here?\n\nEvaluation function-f is the criterion based on which the next node is chosen. \nf is the sum of 2 parameters:\n1. cost of path from source to the given node\n2. approximate cost of reaching the goal from the given node (heuristic function)\nSo, at each step, the node is chosen such that sum of the above 2 parameters, that is, f is minimal. \n\n### Algorithm\n\nStarting from source city, we choose the next city such that it is in the shortest path from the source (based on the cost of the route from source) as well as the closest to the Goal city(based on the heuristics function) amongst all it's neighbours. We terminate, once we've reached the goal city.\n\n\n\nLet us understand this better through an example.\n\n![Romania map](https://user-images.githubusercontent.com/22571531/27821959-ac69755a-60c1-11e7-8286-951cd1c0437f.png)\n\nSource: Artificial Intelligence A Modern Approach\n        by Stuart J. Russell and Peter Norvig \n\nGiven here is the map of Romania with cities and distance between them. We need to find the shortest route from Arad to Bucharest. \n\nThe heurestics that we are using here is the straight-line distance from the city to the goal(Here, Bucharest). Note that, this straight line distance is obtained only by knowing the map coordinates of the 2 cities. \n\n\n#### Input\n\nInput is taken from the file \n```\ninput.txt\n```\n\nEach line in the input is of the form \n```\ncity1 city2 dist\n```\nIt denotes each element of the adjacency list. That is, dist is the distance between city1 and city2. An undireced graph is drawn depicting the map of Romania.\nStarting city: Arad\nGoal city: Bucharest\n\nHeuristics is loaded from the file\n```\nheuristics.txt\n```\nEach line is of the form\n```\ncity h\n```\n'h' stands for the heuristics value(here, the straight line distnace) from the city 'city' to goal city(here, Bucharest)\n\n#### Working: \n\n\nHere, Arad is the starting city. The first node to be expanded from Arad will be Sibiu, because it has a smaller value of f (140+253=393) than either Zerind (75+374=449_)or Timisoara(118 + 329 =447). The next node to be expanded will be Rimnicu_Vilcia, because it has a smaller f compared to other possible nodes. Similary, Pitesti is expanded next and finally Bucharest is reached.\n\nHere, is the resultant graph.                                              \nGreen coloured node denotes the starting city(Here, Arad).                                             \nRed coloured node denotes the goal city(Here, Bucharest).                                                           \nEdges marked with black is the route from Arad to Bucharest generated by the A* search algorithm.\n![final-route](https://user-images.githubusercontent.com/22571531/27867257-c85c0e94-61b6-11e7-8b08-c2b1972e67b3.png)\n\n#### Complexity ####\n\nTime: O(b^d)                                                                \nb - Branching factor, the average number of successors per state        \nd - depth of the shortest path                        "
  },
  {
    "path": "A_star_search/a_star_search.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\nimport Queue as Q\n \n \n\ndef getPriorityQueue(G, v):\n\tq = Q.PriorityQueue()\n\tfor node in G[v]:\n\t\tq.put(Ordered_Node(float(heuristics[node])+float(G[node][v]['length']),node))\n\treturn q,len(G[v])\n\n\n\ndef aStarSearchUtil(G, v, visited, final_path, dest, goal): \n\tif goal == 1:\n\t\treturn goal\n\tvisited[v] = True\n\tfinal_path.append(v)\n\tif v == dest:\n\t\tgoal = 1\n\telse:\n\t\tpq_list = []\n\t\tpq,size = getPriorityQueue(G, v)\n\t\tfor i in range(size):\n\t\t\tpq_list.append(pq.get().description)\n\t\tfor i in pq_list:\n\t\t\tif goal != 1:\n\t\t\t\t#print \"current city:\", i\n\t\t\t\tif visited[i] == False :\n\t\t\t\t\tgoal = aStarSearchUtil(G, i, visited, final_path, dest, goal)\n\treturn goal\n\n\n \ndef aStarSearch(G, source, dest, heuristics, pos): \n\tvisited = {}\n\tfor node in G.nodes():\n\t\tvisited[node] = False\n\tfinal_path = []\n\tgoal = aStarSearchUtil(G, source, visited, final_path, dest, 0)\n\tprev = -1\n\tfor var in final_path:\n\t\tif prev != -1:\n\t\t\tcurr = var\n\t\t\tnx.draw_networkx_edges(G, pos, edgelist = [(prev,curr)], width = 2.5, alpha = 0.8, edge_color = 'black')\n\t\t\tprev = curr\n\t\telse:\n\t\t\tprev = var\n\treturn\n\n\n\nclass Ordered_Node(object):\n\tdef __init__(self, priority, description):\n\t\tself.priority = priority\n\t\tself.description = description\n\t\treturn\n\tdef __cmp__(self, other):\n\t\treturn cmp(self.priority, other.priority)\n\ndef getHeuristics(G):\n\theuristics = {}\n\tf = open('heuristics.txt')\n\tfor i in G.nodes():\n\t\tnode_heuristic_val = f.readline().split()\n\t\theuristics[node_heuristic_val[0]] = node_heuristic_val[1]\n\treturn heuristics\n\n\n\n#takes input from the file and creates a weighted graph\ndef CreateGraph():\n\tG = nx.Graph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\tfor i in range(n):\n\t\tgraph_edge_list = f.readline().split()\n\t\tG.add_edge(graph_edge_list[0], graph_edge_list[1], length = graph_edge_list[2]) \n\tsource, dest= f.read().splitlines()\n\treturn G, source, dest\n\n\n\ndef DrawPath(G, source, dest):\n\tpos = nx.spring_layout(G)\n\tval_map = {}\n\tval_map[source] = 'green'\n\tval_map[dest] = 'red'\n\tvalues = [val_map.get(node, 'blue') for node in G.nodes()]\n\tnx.draw(G, pos, with_labels = True, node_color = values, edge_color = 'b' ,width = 1, alpha = 0.7)  #with_labels=true is to show the node number in the output graph\n\tedge_labels = dict([((u, v,), d['length']) for u, v, d in G.edges(data = True)])\n\tnx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels, label_pos = 0.5, font_size = 11) #prints weight on all the edges\n\treturn pos\n\n\n\n#main function\nif __name__ == \"__main__\":\n\tG, source,dest = CreateGraph()\n\theuristics = getHeuristics(G)\n\tpos = DrawPath(G, source, dest)\n\taStarSearch(G, source, dest, heuristics, pos)\n\tplt.show()\n\n\n\n\n"
  },
  {
    "path": "A_star_search/heuristics.txt",
    "content": "Arad 366\nBucharest 0\nCraiova 160\nDobreta 242\nEforie 161\nFagaras 178\nGiurgiu 77\nHirsova 151\nIasi 226\nLugoj 244\nMehadia 241\nNeamt 234\nOradea 380\nPitesti 98\nRimnicu_Vilcea 193\nSibiu 253\nTimisoara 329\nUrziceni 80\nVaslui 199\nZerind 374"
  },
  {
    "path": "A_star_search/input.txt",
    "content": "23\nArad Sibiu 140\nArad Timisoara 118\nArad Zerind 75\nBucharest Fagaras 211\nBucharest Giurgiu 90\nBucharest Pitesti 101\nBucharest Urziceni 85\nCraiova Dobreta 120\nCraiova Pitesti 138\nCraiova Rimnicu_Vilcea 146\nDobreta Mehadia 75\nEforie Hirsova 86\nFagaras Sibiu 99\nHirsova Urziceni 98\nIasi Neamt 87\nIasi Vaslui 92\nLugoj Mehadia 70\nLugoj Timisoara 111\nOradea Zerind 71\nOradea Sibiu 151\nPitesti Rimnicu_Vilcea 97\nRimnicu_Vilcea Sibiu 80\nUrziceni Vaslui 142\nArad\nBucharest"
  },
  {
    "path": "Assignment Problem/README.md",
    "content": "# Visualisation of Assignment Problem using networkx library\n\n### INPUT ###\n\n\nInput is taken from the file \n#### input.txt ####\n\nSample input\n```\n 4\n 9 2 7 8\n 6 4 3 7 \n 5 8 1 8\n 7 6 9 4\n\n```\nFirst line contains n, the number of people which is the same as the number of jobs.\nFollowed by n*n weighted profit matrix.\n\n\n### Draw Graph ###\n\n\nA bipartite graph is to be drawn. Person and Job - are the 2 sets of nodes. Since, person is connected to every possible job and a job has connection from every person.\n\n![1](https://user-images.githubusercontent.com/22571531/27514223-5fa03ec4-59a1-11e7-9bdc-8d9c17afc030.png)\n\n\n### Assignment Problem ###\n\nAssignment Problem is a combinatorial optimization problem. It consists of finding a maximum weight matching (or minimum weight perfect matching) in a weighted bipartite graph.\n\nHere, we have n people and n jobs that need to be done. Given profit matrix, we need to assign exactly one person to each job and exactly one job to each person in such a way that the total profit of the assignment in maximized.\n(It is a linear assignment problem, since number of people and jobs are equal.)\n\nHungarian algorithm is one of the most effient methods that solves the linear assignment problem in polynomial time(with a time complexity of O(n^3)).\n\nThe code here,is an implementation of Hungarian algorithm. \nThe resultant graph for the sample input with maximum weight matching (denoted by red edges):\n\n![2](https://user-images.githubusercontent.com/22571531/27514224-645f8028-59a1-11e7-92b0-5f0d7f0b8b02.png)\n\n#### Complexity ####\n\nTime: O(n^3)                                                          \nn - number of people( = number of jobs)\n"
  },
  {
    "path": "Assignment Problem/assignment_prob_hungarian.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\nfrom networkx.algorithms import bipartite\nfrom string import ascii_lowercase\n\n\n\ndef init_labels(cost):\n\tn = len(cost)\n\tlx = [0] * n\n\tly = [0] * n\n \tfor x in range(n):\n \t\tfor y in range(n):\n \t\t\tlx[x] = max(lx[x], cost[x][y])\n \treturn lx,ly\n\n\n\ndef update_labels(T, slack, S, lx, ly, n):\n\tdelta = float(\"inf\");\n\tfor y in range(n):\n\t\tif T[y] == 0:\n\t\t\tdelta = min(delta, slack[y])\n \tfor x in range(n):\n\t\tif S[x] != 0:\n\t\t\tlx[x] -= delta\n \tfor y in range(n):\n\t\tif T[y] != 0:\n\t\t\tly[y] += delta\n \tfor y in range(n):\n \t\tif T[y] == 0:\n\t\t\tslack[y] -= delta\n\n\n\ndef add_to_tree(x, prevx, S, prev, lx, ly, slack, slackx, cost):\n\tn = len(cost)\n\tS[x] = True\n \tprev[x] = prevx\n \tfor y in range(n):\n \t\tif (lx[x] + ly[y] - cost[x][y]) < slack[y]:\n \t\t\tslack[y] = lx[x] + ly[y] - cost[x][y]\n \t\t\tslackx[y] = x\n \n\n\ndef augment(cost, max_match, xy, yx, lx, ly, slack, slackx):\n\tn = len(cost)\n\tif max_match == n:\n\t\treturn;\n \tq = [0] * n\n\twr = 0\n\trd = 0\n\troot = 0\n\tS = [False] * n\n\tT = [False] * n\n\tprev = [-1] * n \n\tfor x in range(n):\n\t\tif xy[x] == -1:\n\t\t\tq[wr] = x\n\t\t\twr = wr+1\n\t\t\troot = x\n \t\t\tprev[x] = -2\n \t\t\tS[x] = True\n \t\t\tbreak\n \tfor y in range(n): \n \t\tslack[y] = lx[root] + ly[y] - cost[root][y]\n \t\tslackx[y] = root\n  \twhile True:\n \t\twhile rd < wr:\n \t\t\tx = q[rd]\n \t\t\trd = rd+1\n \t\t\tfor y in range(n):\n \t\t\t\tif (cost[x][y] == lx[x] + ly[y] and T[y] == 0):\n\t\t\t\t\tif yx[y] == -1:\n\t\t\t\t\t\tbreak\n \t\t\t\t\tT[y] = True\n \t\t\t\t\tq[wr] = yx[y]\n \t\t\t\t\twr = wr+1\n \t\t\t\t\tadd_to_tree(yx[y], x, S, prev, lx, ly, slack, slackx, cost)\n \t\t\tif y < n:\n \t\t\t\tbreak\n\t\tif y < n:\n\t\t\tbreak\n\t\tupdate_labels(T, slack, S, lx, ly, n)\n\t\twr = 0 \n\t\trd = 0\n \t\tfor y in range(n):\n\t\t\tif T[y] == 0 and slack[y] == 0:\n\t\t\t\tif yx[y] == -1:\n\t\t\t\t\tx = slackx[y]\n \t\t\t\t\tbreak\n \t\t\t\telse:\n\t\t\t\t\tT[y] = true\n \t\t\t\t\tif S[yx[y]] == 0:\n \t\t\t\t\t\tq[wr] = yx[y]\n \t\t\t\t\t\twr = wr+1\n \t\t\t\t\t\tadd_to_tree(yx[y], slackx[y], S, prev, lx, ly, slack, slackx, cost)\n \t\tif y < n:\n\t\t\tbreak\n\tif y < n:\n\t\tmax_match = max_match+1\n\t\tcx = x\n\t\tcy = y\n\t\tty = 0\n\t\tflag = 0\n\t\tif cx != -2:\n\t\t\tty = xy[cx];\n \t\t\tyx[cy] = cx;\n \t\t\txy[cx] = cy;\n \t\t\tcx = prev[cx]\n\t\t\tcy = ty\n\t\twhile cx != -2:\n\t\t\tty = xy[cx]\n \t\t\tyx[cy] = cx\n\t\t\txy[cx] = cy\n\t\t\tcx = prev[cx]\n\t\t\tcy = ty\n \t\taugment(cost, max_match, xy, yx, lx, ly, slack, slackx)\n\n\n\ndef hungarian(B ,pos ,cost):\n\tn = len(cost)\n\tret = 0; \n\tmax_match = 0 \n\txy = [-1] * n\n\tyx = [-1] * n\n\tslack = [0] * n\n\tslackx = [0] * n\n\tlx, ly = init_labels(cost)\n\taugment(cost, max_match, xy, yx, lx, ly, slack, slackx)\n\tfor x in range(n):\n \t\tif (x, chr(xy[x]+97)) in B.edges():\n\t\t\tnx.draw_networkx_edges(B, pos, edgelist = [(x, chr(xy[x]+97))], width = 2.5, alpha = 0.6, edge_color = 'r')\n\n\n\n#takes input from the file and creates a weighted bipartite graph\ndef CreateGraph():\n\tB = nx.DiGraph();\n\tf = open('input.txt')\n\tn = int(f.readline())\n\tcost = []\n\t\n\tfor i in range(n):\n\t\tlist1 = map(int, (f.readline()).split())\n\t\tcost.append(list1)\n\tpeople = []\n\tfor i in range(n):\n\t\tpeople.append(i)\n\tjob = [] \n\tfor c in ascii_lowercase[:n]:\n\t\tjob.append(c)\n\tB.add_nodes_from(people, bipartite=0) # Add the node attribute \"bipartite\"\n\tB.add_nodes_from(job, bipartite=1)\n\tfor i in range(n) :\n\t\tfor c in ascii_lowercase[:n] :\n\t\t\tif cost[i][ord(c)-97] > 0 :\n\t\t\t\tB.add_edge(i, c, length = cost[i][ord(c)-97])  \n\treturn B,cost\n\n\n\ndef DrawGraph(B):\n\tl, r = nx.bipartite.sets(B)\n\tpos = {}\n\t# Update position for node from each group\n\tpos.update((node, (1, index)) for index, node in enumerate(l))\n\tpos.update((node, (2, index)) for index, node in enumerate(r))\n\tnx.draw(B, pos, with_labels = True)  #with_labels=true is to show the node number in the output graph\n\tedge_labels = dict([((u, v), d['length']) for u, v, d in B.edges(data = True)])\n\tnx.draw_networkx_edge_labels(B, pos, edge_labels = edge_labels, label_pos = 0.2, font_size = 11) #prints weight on all the edges\n\treturn pos\n\n\n\n#main function\nif __name__ == \"__main__\":\n\tB, cost = CreateGraph();\n\tpos = DrawGraph(B)\n\thungarian(B, pos, cost)\n\tplt.show()\n\t"
  },
  {
    "path": "Assignment Problem/input.txt",
    "content": "4\n9 2 7 8\n6 4 3 7 \n5 8 1 8\n7 6 9 4"
  },
  {
    "path": "BFS/README.md",
    "content": "# Visualisation of BFS traversal using networkx library\n\n### INPUT ###\n\n\nInput is taken from the file \n#### input.txt ####\n\nSample input\n```\n4\n0 5 10 5\n0 0 5 0\n0 10 0 0\n0 0 10 0\n0\n\n\n```\nFirst line contains the number of nodes,say n.(Nodes are numbered as 0,1,2,...(n-1) )\nFollowed by n*n weighted matrix. Disconnected egdes are represented by negative weight.\nLast line contains the source node.(i.e, the node from which the BFS should begin)\n\n\n### Draw Graph ###\n\n\nGraph is first drawn from the weighted matrix input from the user with weights shown. Edges are marked with black.\nvisualization of the input graph-\n![1](https://user-images.githubusercontent.com/22571531/27984139-48d91928-63eb-11e7-9634-fed45cec799a.png)\n\n\n### BFS traversal ###\n\nIterative BFS is performed, using a queue. Each time an edge is encountered, \nit is marked with red on the graph through the line -\n```\nnx.draw_networkx_edges(G,pos,edgelist=[(curr_node,i)],width=2.5,alpha=0.6,edge_color='r')\n\n```\nVisualization of the result-\n![2](https://user-images.githubusercontent.com/22571531/27984141-4d665e42-63eb-11e7-97e6-49f28ff1552e.png)\n\n### Complexity ###\n\nTime: 0(m+n)                                                                                                        \nwhere m - number of edges                                                                                \nn - number of nodes \n\n\n"
  },
  {
    "path": "BFS/bfs.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\n \n\n\n#BFS traversal \ndef BFS(G, source, pos): \n\tvisited = [False]*(len(G.nodes()))\n \tqueue = []\t\t#a queue for BFS traversal\n\tqueue.append(source)\n\tvisited[source] = True\n\twhile queue:\n\t\tcurr_node = queue.pop(0)\n\t\tfor i in G[curr_node]:  #iterates through all the possible vertices adjacent to the curr_node\n\t\t\tif visited[i] == False:\n\t\t\t\tqueue.append(i)\n\t\t\t\tvisited[i] = True\n\t\t\t\t# nx.draw_networkx_edges(G, pos, edgelist = [(curr_node,i)], width = 2.5, alpha = 0.6, edge_color = 'r')\n\treturn\n\n\n\n#takes input from the file and creates a weighted graph\ndef CreateGraph():\n\tG = nx.DiGraph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\twtMatrix = []\n\tfor i in range(n):\n\t\tlist1 = list(map(int, (f.readline()).split()))\n\t\twtMatrix.append(list1)\n\tsource = int(f.readline()) #source vertex from where BFS has to start\n\t#Adds egdes along with their weights to the graph \n\tfor i in range(n):\n\t\tfor j in range(len(wtMatrix[i])):\n\t\t\tif wtMatrix[i][j] > 0:\n\t\t\t\t\tG.add_edge(i, j, length = wtMatrix[i][j]) \n\treturn G, source\n\n\n\n#draws the graph and displays the weights on the edges\ndef DrawGraph(G):\n\tpos = nx.spring_layout(G)\n\tnx.draw(G, pos, with_labels = True)  #with_labels=true is to show the node number in the output graph\n\tedge_labels = dict([((u,v,), d['length']) for u, v, d in G.edges(data = True)])\n\tnx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels, label_pos = 0.3, font_size = 11) #prints weight on all the edges\n\treturn pos\n\n\n\n#main function\nif __name__== \"__main__\":\n\tG,source = CreateGraph()\n\tpos = DrawGraph(G)\n\tBFS(G, source, pos)\n\tplt.show()\n\n"
  },
  {
    "path": "BFS/input.txt",
    "content": "4\n0 5 10 5\n0 0 5 0\n0 10 0 0\n0 0 10 0\n0\n"
  },
  {
    "path": "BellmanFord/BellmanFord.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\nimport sys\n\ninf = float('inf')\n\n#function that performs Bellman-Ford algorithm on the graph G,with source vertex as source\ndef bellmanFord(G, source, pos):\n\tV = len(G.nodes()) # V denotes the number of vertices in G\n\tdist = [] # dist[i] will hold the shortest distance from source to i\n\tparent = [None]*V # parent[i] will hold the node from which i is reached to, in the shortest path from source\n\n\tfor i in range(V):\n\t\tdist.append(inf)\n\n\tparent[source] = -1; #source is itself the root, and hence has no parent\n\tdist[source] = 0;\n\n\tfor i in range(V-1):\n\t\tfor u, v, d in G.edges(data = True): # Relaxation is the most important step in Bellman-Ford. It is what increases the accuracy of the distance to any given vertex. Relaxation works by continuously shortening the calculated distance between vertices comparing that distance with other known distances.\n\t\t\tif dist[u] + d['length'] < dist[v]: #Relaxation Equation\n\t\t\t\tdist[v] = d['length'] + dist[u]\n\t\t\t\tparent[v] = u\n\n\t#marking the shortest path from source to each of the vertex with red, using parent[]\n\tfor v in range(V):\n\t\tif parent[v] != -1: #ignore the parent of root node\n\t\t\tif (parent[v], v) in G.edges():\n\t\t\t\tnx.draw_networkx_edges(G, pos, edgelist = [(parent[v], v)], width = 2.5, alpha = 0.6, edge_color = 'r')\n\treturn\n\n#takes input from the file and creates a weighted graph\ndef createGraph():\n\tG = nx.DiGraph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\twtMatrix = []\n\tfor i in range(n):\n\t\tlist1 = map(int, (f.readline()).split())\n\t\twtMatrix.append(list1)\n\tsource = int(f.readline()) #source vertex for BellmanFord algo\n\t#Adds egdes along with their weights to the graph\n\tfor i in range(n) :\n\t\tfor j in range(n) :\n\t\t\tif wtMatrix[i][j] > 0 :\n\t\t\t\t\tG.add_edge(i, j, length = wtMatrix[i][j])\n\treturn G, source\n\n\n#draws the graph and displays the weights on the edges\ndef DrawGraph(G):\n\tpos = nx.spring_layout(G)\n\tnx.draw(G, pos, with_labels = True)  #with_labels=true is to show the node number in the output graph\n\tedge_labels = dict([((u, v), d['length']) for u, v, d in G.edges(data = True)])\n\tnx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels, label_pos = 0.3, font_size = 11) #prints weight on all the edges\n\treturn pos\n\n#main function\nif __name__ == \"__main__\":\n\tG, source = createGraph()\n\tpos = DrawGraph(G)\n\tbellmanFord(G, source, pos)\n\tplt.show()\n"
  },
  {
    "path": "BellmanFord/input.txt",
    "content": "5\n0 2 7 -1 -1\n-1 0 3 8 5\n-1 2 0 1 -1\n-1 -1 -1 0 4\n-1 -1 -1 5 0\n0\n"
  },
  {
    "path": "DFS/README.md",
    "content": "# Visualisation of DFS traversal using networkx library\n\n### INPUT ###\n\nGraph is first drawn from the weighted matrix input from the user. \nInput is taken from the file \n#### input.txt ####\n\nSample input\n```\n 4\n 0 5 0 5\n 5 0 5 0\n 0 5 0 5\n 5 0 5 0\n 0\n\n```\nFirst line contains the number of nodes,say n.(Nodes are numbered as 0,1,2,...(n-1) )\nFollowed by n*n weighted matrix. Disconnected egdes are represented by negative weight.\nLast line contains the source node.(i.e, the node from which the DFS should begin)\n\nVisualization of the input graph-\n![1](https://user-images.githubusercontent.com/22571531/27984144-547decd6-63eb-11e7-9ddc-487d976b0fec.png)\n\n### DFS traversal ###\n\nRecursive DFS is performed, resulting DFS forests are stored in a stack. \n\n### Visulization of DFS path ###\n\nThe stack is then used to mark the DFS traversed edges with a different colour(Here, Red. So, as to distinguish itself from the rest).\nVisualization of the result-\n![2](https://user-images.githubusercontent.com/22571531/27984145-593846ae-63eb-11e7-91bc-4c69ba5ba12a.png)\n\n### Complexity ###\n\nTime: 0(m+n)                                                                                                        \nwhere m - number of edges                                                                                \nn - number of nodes                                                                                          \n\n"
  },
  {
    "path": "DFS/dfs_visual.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\n \n\n\n#utility fucntion used by DFS which does recursive depth first search \ndef DFSUtil(G, v, visited, sl): \n\tvisited[v] = True\n\tsl.append(v) \n\tfor i in G[v]:\n\t\tif visited[i] == False:\n\t\t\tDFSUtil(G, i, visited, sl)\n\treturn sl\n \n\n\n#DFS traversal \ndef DFS(G, source): \n\tvisited = [False]*(len(G.nodes()))\n \tsl = []\t\t#a list that stores dfs forest starting with source node\n \tdfs_stk = [] #A nested list that stores all the DFS Forest's\n\tdfs_stk.append(DFSUtil(G, source, visited, sl))\n\tfor i in range(len(G.nodes())):\n\t\tif visited[i] == False:\n\t\t\tsl = []\n\t\t\tdfs_stk.append(DFSUtil(G, i, visited, sl))\n\treturn dfs_stk\n\t\t\t\n\n\n#takes input from the file and creates a weighted graph\ndef CreateGraph():\n\tG = nx.DiGraph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\twtMatrix = []\n\tfor i in range(n):\n\t\tlist1 = map(int,(f.readline()).split())\n\t\twtMatrix.append(list1)\n\tsource = int(f.readline()) #source vertex from where DFS has to start\n\t#Adds egdes along with their weights to the graph \n\tfor i in range(n):\n\t\tfor j in range(n):\n\t\t\tif wtMatrix[i][j] > 0:\n\t\t\t\t\tG.add_edge(i, j, length = wtMatrix[i][j]) \n\treturn G,source\n\n\n\n#marks all edges traversed through DFS with red\ndef DrawDFSPath(G, dfs_stk):\n\tpos = nx.spring_layout(G)\n\tnx.draw(G, pos, with_labels = True)  #with_labels=true is to show the node number in the output graph\n\tedge_labels = dict([((u,v,), d['length']) for u, v, d in G.edges(data = True)])\n\tnx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels, label_pos = 0.3, font_size = 11) #prints weight on all the edges\n\tfor i in dfs_stk:\n\t\t#if there is more than one node in the dfs-forest, then print the corresponding edges\n\t\tif len(i) > 1:\n\t\t\tfor j in i[ :(len(i)-1)]:\n\t\t\t\tif i[i.index(j)+1] in G[j]:\n\t\t\t\t\tnx.draw_networkx_edges(G, pos, edgelist = [(j,i[i.index(j)+1])], width = 2.5, alpha = 0.6, edge_color = 'r')\n\t\t\t\telse:\n\t\t\t\t\t#if in case the path was reversed because all the possible neighbours were visited, we need to find the adj node to it.\n\t\t\t\t\tfor k in i[1::-1]: \n\t\t\t\t\t\tif k in G[j]:\n\t\t\t\t\t\t\tnx.draw_networkx_edges(G, pos, edgelist = [(j,k)], width = 2.5, alpha = 0.6, edge_color = 'r')\n\t\t\t\t\t\t\tbreak\n\n\n\n#main function\nif __name__ == \"__main__\":\n\tG, source = CreateGraph()\n\tdfs_stk = DFS(G, source)\n\tDrawDFSPath(G, dfs_stk)\n\tplt.show()\n\n\n"
  },
  {
    "path": "DFS/input.txt",
    "content": "4\n0 5 0 5\n5 0 5 0\n0 5 0 5\n5 0 5 0\n0\n"
  },
  {
    "path": "Dijsktra's/README.md",
    "content": "# Visualisation of Dijsktra's algorithm using networkx library\n\n### INPUT ###\n\n\nInput is taken from the file \n#### input.txt ####\n\nSample input\n```\n  5\n  0 2 7 -1 -1\n  -1 0 3 8 5\n  -1 2 0 1 -1\n  -1 -1 -1 0 4\n  -1 -1 -1 5 0\n  0\n\n\n```\nFirst line contains the number of nodes,say n.(Nodes are numbered as 0,1,2,...(n-1) )\nFollowed by n*n weighted matrix. Disconnected egdes are represented by negative weight.\nLast line contains the source node.(i.e, the node from which the rest of the nodes should be reached)\n\n### Draw Graph ###\n\n\nGraph is first drawn from the weighted matrix input from the user with weights shown. Edges are marked with black.\n\n\n\n### Dijsktras algorithm ###\n\nDDijkstra's algorithm is an algorithm for finding the shortest paths between nodes in a graph. \n\nHere, given the source node, the algorithm finds the shortest path from the source node to each of the remaining nodes. \n\nTo understand this better, consider the above input.\nSource node is 0.\n\nThe graph, initially.\n\n![1](https://user-images.githubusercontent.com/22571531/27195526-ca5dd872-5224-11e7-9b34-e669c7082a6e.png)\n\nWe use the following 3 lists:\n\n#### dist ####\n dist[i] will hold the shortest distance from source to i.                                 \n#### parent ####                               \nparent[i] will hold the node from which node i is reached to, in the shortest path from source.                          \n#### sptSet ####                         \nsptSet[i] will hold true if vertex i is included in shortest path tree.                           \n\n#### Initial values: ####\n```\ndist   = [0, inf ,inf, inf, inf]\nparent = [-1, None, None, None]                        \nsptSet = [True, False, False, False, False]\n```\n\n#### After the first iteration: ####\n\nNode 1 and Node 2 can be reached directly from source node,i.e, 0 with a distance of 2 and 7 respectively. Hence they are updated accordingly.\n\n```\ndist   = [0, 2, 7, inf, inf]\nparent = [-1, 0, 0, None, None] \nsptSet = [True, False, False, False, False]\n```\n\nMinimum most distance of those where sptSet[i] == False, is node 1.\nHence, the node is now included in the shorted path tree, hence sptSet[1] is set to True.\n\n![2](https://user-images.githubusercontent.com/22571531/27195530-cd783296-5224-11e7-87f5-a404a94fed84.png)\n\n\n#### After the second iteration: ####\n\n```\ndist   = [0, 2, 5, 10, 7]\nparent = [-1, 0, 1, 1, 1]\nsptSet = [True, True, False, False, False]\n```\n\n![3](https://user-images.githubusercontent.com/22571531/27195531-d081e824-5224-11e7-8993-81f2dc43c30f.png)\n\n#### After the third iteration: ####\n\n```\ndist   = [0, 2, 5, 6, 7]\nparent = [-1, 0, 1, 2, 1]\nsptSet = [True, True, True, False, False]\n```\n\n![4](https://user-images.githubusercontent.com/22571531/27195536-d310f896-5224-11e7-8a75-eb5e883bc37b.png)\n\n#### After the fourth iteration: ####\n\n```\ndist   = [0, 2, 5, 6, 7]\nparent = [-1, 0, 1, 2, 1]\nsptSet = [True, True, True, True, False]\n```\n\nHere, the red edges denote the shortest path from source node to the rest of the nodes.\n\n![5](https://user-images.githubusercontent.com/22571531/27195545-d8cfdf68-5224-11e7-8ee9-1b2d38e1d6ad.png)\n\n#### Complexity ####\nTime : O(V^2)                                                           \nV - number of Vertices                                \n"
  },
  {
    "path": "Dijsktra's/dijsktras.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\nimport sys\n \n\n\n#utility function that returns the minimum distance node\ndef minDistance(dist, sptSet, V):\n   \tmin = sys.maxsize #assigning largest numeric value to min\n   \tfor v in range(V):\n   \t\tif sptSet[v] == False and dist[v] <= min:\n   \t\t\tmin = dist[v]\n   \t\t\tmin_index = v\n\treturn min_index\n\n\n\n#function that performs dijsktras algorithm on the graph G,with source vertex as source\ndef dijsktras(G, source, pos):\n\tV = len(G.nodes()) # V denotes the number of vertices in G\n\tdist = [] # dist[i] will hold the shortest distance from source to i\n\tparent = [None]*V # parent[i] will hold the node from which i is reached to, in the shortest path from source\n\tsptSet = [] # sptSet[i] will hold true if vertex i is included in shortest path tree\n\t#initially, for every node, dist[] is set to maximum value and sptSet[] is set to False\n\tfor i in range(V):\n\t\tdist.append(sys.maxsize)\n\t\tsptSet.append(False)\n\tdist[source] = 0\n\tparent[source]= -1 #source is itself the root, and hence has no parent\n\tfor count in range(V-1):\n\t\tu = minDistance(dist, sptSet, V) #pick the minimum distance vectex from the set of vertices\n\t\tsptSet[u] = True\n\t\t#update the vertices adjacent to the picked vertex\n\t\tfor v in range(V):\n\t\t\tif (u, v) in G.edges():\n\t\t\t\tif sptSet[v] == False and dist[u] != sys.maxsize and dist[u] + G[u][v]['length'] < dist[v]:\n\t\t\t\t\tdist[v] = dist[u] + G[u][v]['length']\n\t\t\t\t\tparent[v] = u\n\t#marking the shortest path from source to each of the vertex with red, using parent[]\n\tfor X in range(V):\n\t\tif parent[X] != -1: #ignore the parent of root node \n\t\t\tif (parent[X], X) in G.edges():\n\t\t\t\tnx.draw_networkx_edges(G, pos, edgelist = [(parent[X], X)], width = 2.5, alpha = 0.6, edge_color = 'r')\n\treturn\n\n\n\n#takes input from the file and creates a weighted graph\ndef CreateGraph():\n\tG = nx.DiGraph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\twtMatrix = []\n\tfor i in range(n):\n\t\tlist1 = map(int, (f.readline()).split())\n\t\twtMatrix.append(list1)\n\tsource = int(f.readline()) #source vertex for dijsktra's algo \n\t#Adds egdes along with their weights to the graph \n\tfor i in range(n) :\n\t\tfor j in range(n) :\n\t\t\tif wtMatrix[i][j] > 0 :\n\t\t\t\t\tG.add_edge(i, j, length = wtMatrix[i][j]) \n\treturn G, source\n\n\n\n#draws the graph and displays the weights on the edges\ndef DrawGraph(G):\n\tpos = nx.spring_layout(G)\n\tnx.draw(G, pos, with_labels = True)  #with_labels=true is to show the node number in the output graph\n\tedge_labels = dict([((u, v), d['length']) for u, v, d in G.edges(data = True)])\n\tnx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels, label_pos = 0.3, font_size = 11) #prints weight on all the edges\n\treturn pos\n\n\n\n#main function\nif __name__ == \"__main__\":\n\tG,source = CreateGraph()\n\tpos = DrawGraph(G)\n\tdijsktras(G, source, pos)\n\tplt.show()\n\n"
  },
  {
    "path": "Dijsktra's/input.txt",
    "content": "  5\n  0 2 7 -1 -1\n  -1 0 3 8 5\n  -1 2 0 1 -1\n  -1 -1 -1 0 4\n  -1 -1 -1 5 0\n  0\n\n"
  },
  {
    "path": "Egocentric Network/egocentric_network_1.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\n \n\ndef EgocentricNetwork(G,v):\n\tegocentric_network_edge_list = []\n\tegocentric_network_node_list = [v]\n\tfor i in G.neighbors(v):\n\t\tegocentric_network_node_list.append(i)\n\t\tegocentric_network_edge_list.append((v,i))\n\treturn egocentric_network_edge_list,egocentric_network_node_list\n\n\n\n#takes input from the file and creates a graph\ndef CreateGraph():\n\tG = nx.Graph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\tfor i in range(n):\n\t\tG.add_node(i+1)\n\tno_of_edges = int(f.readline())\n\tfor i in range(no_of_edges):\n\t\tgraph_edge_list = f.readline().split()\n\t\tG.add_edge(int(graph_edge_list[0]), int(graph_edge_list[1])) \n\tvert = int(f.readline())\n\treturn G, vert\n\n\n\n#draws the graph and displays the weights on the edges\ndef DrawGraph(G,egocentric_network_edge_list,egocentric_network_node_list, vert):\n\tpos = nx.spring_layout(G)\n\tnx.draw(G, pos, with_labels = True, node_color = 'blue', alpha = 0.8)  #with_labels=true is to show the node number in the output graph\n\tnx.draw_networkx_edges(G, pos, edgelist = egocentric_network_edge_list , width = 2.5, alpha = 0.8, edge_color = 'red')\n\tnx.draw_networkx_nodes(G,pos, nodelist = egocentric_network_node_list, node_color = 'red', alpha = 0.5)\n\tnx.draw_networkx_nodes(G,pos,nodelist=[vert],node_color='green',node_size=500,alpha=0.8)\n\treturn pos\n\n\ndef CentralityMeasures(G):\n\t# Betweenness centrality\n\tbet_cen = nx.betweenness_centrality(G)\n\t# Closeness centrality\n\tclo_cen = nx.closeness_centrality(G)\n\t# Eigenvector centrality\n\teig_cen = nx.eigenvector_centrality(G)\n\t# Degree centrality\n\tdeg_cen = nx.degree_centrality(G)\n\t#print bet_cen, clo_cen, eig_cen\n\tprint \"# Betweenness centrality:\" + str(bet_cen)\n\tprint \"# Closeness centrality:\" + str(clo_cen)\n\tprint \"# Eigenvector centrality:\" + str(eig_cen)\n\tprint \"# Degree centrality:\" + str(deg_cen)\n\n\n#main function\n\nif __name__== \"__main__\":\n\tG,vert = CreateGraph()\n\tegocentric_network_edge_list,egocentric_network_node_list = EgocentricNetwork(G,vert)\n\tDrawGraph(G,egocentric_network_edge_list,egocentric_network_node_list, vert)\n\tCentralityMeasures(G)\n\tplt.show()\n\n"
  },
  {
    "path": "Egocentric Network/egocentric_network_1_5.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\nimport itertools\n \n\ndef EgocentricNetwork(G,v):\n\t\n\tegocentric_network_edge_list = []\n\tegocentric_network_node_list = [v]\n\tfor i in G.neighbors(v):\n\t\tegocentric_network_node_list.append(i)\n\t\tegocentric_network_edge_list.append((v,i))\n\tegocentric_network_node_list.sort()\n\tegocentric_network_edge_list = list(tuple(sorted(p)) for p in egocentric_network_edge_list)\n\n\tfor i in list(itertools.combinations(egocentric_network_node_list, 2)): #generates all possible pairs of nodes\n\t\tif i in G.edges() and i not in egocentric_network_edge_list:\n\t\t\tegocentric_network_edge_list.append(i)\n\n\treturn egocentric_network_edge_list,egocentric_network_node_list\n\n\n\n#takes input from the file and creates a graph\ndef CreateGraph():\n\tG = nx.Graph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\tfor i in range(n):\n\t\tG.add_node(i+1)\n\tno_of_edges = int(f.readline())\n\tfor i in range(no_of_edges):\n\t\tgraph_edge_list = f.readline().split()\n\t\tG.add_edge(int(graph_edge_list[0]), int(graph_edge_list[1])) \n\tvert = int(f.readline())\n\treturn G, vert\n\n\n\n#draws the graph and displays the weights on the edges\ndef DrawGraph(G, egocentric_network_edge_list, egocentric_network_node_list, vert):\n\tpos = nx.spring_layout(G)\n\tnx.draw(G, pos, with_labels = True, node_color = 'blue', alpha = 0.8)  #with_labels=true is to show the node number in the output graph\n\tnx.draw_networkx_edges(G, pos, edgelist = egocentric_network_edge_list , width = 2.5, alpha = 0.8, edge_color = 'red')\n\tnx.draw_networkx_nodes(G,pos, nodelist = egocentric_network_node_list, node_color = 'red', alpha = 0.5)\n\tnx.draw_networkx_nodes(G,pos,nodelist=[vert],node_color='green',node_size=500,alpha=0.8)\n\treturn pos\n\n\ndef CentralityMeasures(G):\n\t# Betweenness centrality\n\tbet_cen = nx.betweenness_centrality(G)\n\t# Closeness centrality\n\tclo_cen = nx.closeness_centrality(G)\n\t# Eigenvector centrality\n\teig_cen = nx.eigenvector_centrality(G)\n\t# Degree centrality\n\tdeg_cen = nx.degree_centrality(G)\n\t#print bet_cen, clo_cen, eig_cen\n\tprint \"# Betweenness centrality:\" + str(bet_cen)\n\tprint \"# Closeness centrality:\" + str(clo_cen)\n\tprint \"# Eigenvector centrality:\" + str(eig_cen)\n\tprint \"# Degree centrality:\" + str(deg_cen)\n\n\n#main function\nif __name__== \"__main__\":\n\tG, vert = CreateGraph()\n\tegocentric_network_edge_list,egocentric_network_node_list = EgocentricNetwork(G, vert)\n\tDrawGraph(G,egocentric_network_edge_list, egocentric_network_node_list, vert)\n\tCentralityMeasures(G)\n\tplt.show()\n\n"
  },
  {
    "path": "Egocentric Network/egocentric_network_2.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\nimport itertools\n \n\ndef EgocentricNetwork(G,v):\n\t\n\tegocentric_network_edge_list = []\n\tegocentric_network_node_list = [v]\n\tfor i in G.neighbors(v):\n\t\tegocentric_network_node_list.append(i)\n\t\tegocentric_network_edge_list.append((v,i))\n\tegocentric_network_node_list.sort()\n\tegocentric_network_edge_list = list(tuple(sorted(p)) for p in egocentric_network_edge_list)\n\n\tfor i in list(itertools.combinations(egocentric_network_node_list, 2)): #generates all possible pairs of nodes\n\t\tif i in G.edges() and i not in egocentric_network_edge_list:\n\t\t\tegocentric_network_edge_list.append(i)\n\n\t\n\ttemp = []\n\ttemp.extend(egocentric_network_node_list)\n\n\tfor i in temp:#print i,\" \",G.neighbors(i)\n\t\tfor j in G.neighbors(i):\n\t\t\tif j not in egocentric_network_node_list:\n\t\t\t\tegocentric_network_node_list.append(j)\n\t\t\tif (j,i) in G.edges() and (j,i) not in egocentric_network_edge_list:\n\t\t\t\tegocentric_network_edge_list.append((j,i))\n\t\t\telif (i,j) in G.edges() and (i,j) not in egocentric_network_edge_list:\n\t\t\t\tegocentric_network_edge_list.append((i,j))\n\tprint egocentric_network_edge_list\n\tprint egocentric_network_node_list\n\treturn egocentric_network_edge_list,egocentric_network_node_list\n\n\n\n#takes input from the file and creates a graph\ndef CreateGraph():\n\tG = nx.Graph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\tfor i in range(n):\n\t\tG.add_node(i+1)\n\tno_of_edges = int(f.readline())\n\tfor i in range(no_of_edges):\n\t\tgraph_edge_list = f.readline().split()\n\t\tG.add_edge(int(graph_edge_list[0]), int(graph_edge_list[1])) \n\tvert = int(f.readline())\n\treturn G, vert\n\n\n\n#draws the graph and displays the weights on the edges\ndef DrawGraph(G,egocentric_network_edge_list,egocentric_network_node_list):\n\tpos = nx.spring_layout(G)\n\tnx.draw(G, pos, with_labels = True, node_color = 'blue', alpha = 0.2)  #with_labels=true is to show the node number in the output graph\n\tnx.draw_networkx_edges(G, pos, edgelist = egocentric_network_edge_list , width = 2.5, alpha = 0.8, edge_color = 'blue')\n\tnx.draw_networkx_nodes(G,pos, nodelist = egocentric_network_node_list, node_color = 'blue', alpha = 0.5)\n\treturn pos\n\n\ndef DrawGraph(G, egocentric_network_edge_list, egocentric_network_node_list, vert):\n\tpos = nx.spring_layout(G)\n\tnx.draw(G, pos, with_labels = True, node_color = 'blue', alpha = 0.8)  #with_labels=true is to show the node number in the output graph\n\tnx.draw_networkx_edges(G, pos, edgelist = egocentric_network_edge_list , width = 2.5, alpha = 0.8, edge_color = 'red')\n\tnx.draw_networkx_nodes(G,pos, nodelist = egocentric_network_node_list, node_color = 'red', alpha = 0.5)\n\tnx.draw_networkx_nodes(G,pos,nodelist=[vert],node_color='green',node_size=500,alpha=0.8)\n\treturn pos\n\n\ndef CentralityMeasures(G):\n\t# Betweenness centrality\n\tbet_cen = nx.betweenness_centrality(G)\n\t# Closeness centrality\n\tclo_cen = nx.closeness_centrality(G)\n\t# Eigenvector centrality\n\teig_cen = nx.eigenvector_centrality(G)\n\t# Degree centrality\n\tdeg_cen = nx.degree_centrality(G)\n\t#print bet_cen, clo_cen, eig_cen\n\tprint \"# Betweenness centrality:\" + str(bet_cen)\n\tprint \"# Closeness centrality:\" + str(clo_cen)\n\tprint \"# Eigenvector centrality:\" + str(eig_cen)\n\tprint \"# Degree centrality:\" + str(deg_cen)\n\n\n#main function\nif __name__== \"__main__\":\n\tG,vert = CreateGraph()\n\tegocentric_network_edge_list,egocentric_network_node_list = EgocentricNetwork(G,vert)\n\tDrawGraph(G,egocentric_network_edge_list,egocentric_network_node_list, vert)\n\tCentralityMeasures(G)\n\tplt.show()\n\n"
  },
  {
    "path": "Egocentric Network/input.txt",
    "content": "10\n11\n1 2\n1 4\n1 3\n3 9\n3 6\n6 8\n8 9\n6 9\n4 6\n4 5\n5 7\n9"
  },
  {
    "path": "Graph Coloring/README.md",
    "content": "# Visualisation of Graph Coloring Problem using networkx library\n\n### Graph Coloring ###\n\n Graph Coloring Problem is an NP complete problem where \"colors\" are assigned to elements of a graph(edge ,node or face) subject to certain constraints.\n\n This is an illustration of Vertex Coloring problem. The problem is that, given an undirected graph, assign colors to each node such that no two ajacent nodes have the same color. It also involves minimization of the number of colors used.\n\n Basic approach:\n\n Step 1: Assign first color to the first vertex\n Step 2: For each of the remaining vertices, color the vertex with the lowest numbered color which has not yet been used for any of its neighbouring vertices.\n\n The above approach is a Greedy approach. It doesn't guarantee to use minimum number of color's each time. One way to improve this is by ordering the vertices in the decreasing order of their valency. And apply node coloring in that order. By doing so, the node with maximum color conflicts will be resolved first, and hence works better. This is Welsh - Powell algorithm.\n\n\n#### Working ####\n\nFor the sample input below:\n\n```\n16\n0 7\n0 1\n1 3\n3 2\n3 8\n3 10\n7 8\n7 9\n7 10\n7 6\n8 9\n9 10\n6 5\n10 4\n5 4\n6 10\n```\nVisualization of the input graph:\n\n![1](https://user-images.githubusercontent.com/22571531/28072420-93b63840-6670-11e7-8178-45c47e8fddfe.png)\n\n\nVisualization of the result after node coloring.                                                  \nFollowing 4 colors have been used:                                                          \nBlue : 0, 3, 5                                                              \nPurple : 1, 2, 4, 6, 9                                                              \nGreen : 7                                                                  \nYellow : 8, 10                                                        \n\n![2](https://user-images.githubusercontent.com/22571531/28072424-9638f80a-6670-11e7-99ba-7b83ab92193c.png)\n\n#### Complexity ####\n\nTime: O(N^2 + E)                                                                                                          \nN - number of Nodes                                              \nE - number of Edges                                               \n\n\n\n \n\n\n\n"
  },
  {
    "path": "Graph Coloring/graph_coloring.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\n\n\n#implementation of welsh_powell algorithm\ndef welsh_powell(G):\n\t#sorting the nodes based on it's valency\n\tnode_list = sorted(G.nodes(), key =lambda x:G.neighbors(x))\n\tcol_val = {} #dictionary to store the colors assigned to each node\n\tcol_val[node_list[0]] = 0 #assign the first color to the first node\n\t# Assign colors to remaining N-1 nodes\n\tfor node in node_list[1:]:\n\t\tavailable = [True] * len(G.nodes()) #boolean list[i] contains false if the node color 'i' is not available\n\n\t\t#iterates through all the adjacent nodes and marks it's color as unavailable, if it's color has been set already\n\t\tfor adj_node in G.neighbors(node): \n\t\t\tif adj_node in col_val.keys():\n\t\t\t\tcol = col_val[adj_node]\n\t\t\t\tavailable[col] = False\n\t\tclr = 0\n\t\tfor clr in range(len(available)):\n\t\t\tif available[clr] == True:\n\t\t\t\tbreak\n\t\tcol_val[node] = clr\n\tprint col_val\n\treturn col_val\n\n        \n\n\n\n#takes input from the file and creates a undirected graph\ndef CreateGraph():\n\tG = nx.Graph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\tfor i in range(n):\n\t\tgraph_edge_list = f.readline().split()\n\t\tG.add_edge(graph_edge_list[0], graph_edge_list[1]) \n\treturn G\n\n\n#draws the graph and displays the weights on the edges\ndef DrawGraph(G,col_val):\n\tpos = nx.spring_layout(G)\n\tvalues = [col_val.get(node, 'blue') for node in G.nodes()]\n\tnx.draw(G, pos, with_labels = True, node_color = values, edge_color = 'black' ,width = 1, alpha = 0.7)  #with_labels=true is to show the node number in the output graph\n\n\n\n\n#main function\nif __name__ == \"__main__\":\n\tG = CreateGraph()\n\tcol_val = welsh_powell(G)\n\tDrawGraph(G,col_val)\n\tplt.show()"
  },
  {
    "path": "Graph Coloring/input.txt",
    "content": "16\n0 7\n0 1\n1 3\n3 2\n3 8\n3 10\n7 8\n7 9\n7 10\n7 6\n8 9\n9 10\n6 5\n10 4\n5 4\n6 10"
  },
  {
    "path": "Greedy BFS/README.md",
    "content": "\n\n# Visualisation of Greedy BFS using networkx library\n\n### Greedy Best First Search ###\n\nBest-first search is a search algorithm which explores a graph by expanding the most promising node chosen according to a specified rule. A greedy algorithm is one that chooses the best-looking option at each step. Hence, greedy best-first search algorithm combines the features of both mentioned above. It is known to be moving towards the direction of the target, in each step. (PS: There is no visiting back in path, as it is Greedy)\n\n#### Heuristic function\n\nGreedy BFS uses heuristics to the pick the \"best\" node.\n\nA heuristic is an approximate measure of how close you are to the target. In short, h can be any function at all. We will require only that h(n) = 0 if n is a goal.\n\n#### BFS v/s Greedy BFS\n\nBFS expands the most promising node first(by looking at it's proximity to the source node).Hence, the solution is thorough. It might have to return back in path if a dead end is reached.\nWhereas, Greedy BFS uses heuristics to prioritize nodes closer to target. Hence, the solution is faster(but not necessarily optimal). There is no returning back in the path.\n\nOften with large data sets, search algorithms could get computationally expensive with thorough approaches. Hence, we resort to approximation algorithms like Greedy BFS.\n\n### Greedy BFS Algorithm\n\nHeuristic functions are clearly problem-specific.\n\nLet us understand this better through an example. \n\n![Romania map](https://user-images.githubusercontent.com/22571531/27821959-ac69755a-60c1-11e7-8286-951cd1c0437f.png)\n\nSource: Artificial Intelligence A Modern Approach\n        by Stuart J. Russell and Peter Norvig \n\nGiven here is the map of Romania with cities and distance between them. We need to find the shortest route from Arad to Bucharest. \n\nThe heurestics that we are using here is the straight-line distance from the city to the goal(Here, Bucharest). Note that, this straight line distance is obtained only by knowing the map coordinates of the 2 cities. \n\n\n#### Input\n\nInput is taken from the file \n```\ninput.txt\n```\n\nEach line in the input is of the form \n```\ncity1 city2 dist\n```\nIt denotes each element of the adjacency list. That is, dist is the distance between city1 and city2. An undireced graph is drawn depicting the map of Romania.\nStarting city: Arad\nGoal city: Bucharest\n\nHeuristics is loaded from the file\n```\nheuristics.txt\n```\nEach line is of the form\n```\ncity h\n```\n'h' stands for the heuristics value(here, the straight line distnace) from the city 'city' to goal city(here, Bucharest)\n\n#### Working: \n\nStarting from source city, we choose the next city which is the closest to the Goal city amongst all it's neighbours(based on the heuristics function). We terminate, once we've reached the goal city.\n\nHere, Arad is the starting city. The first node to be expanded from Arad will be Sibiu, because it is closer to Bucharest than either Zerind or Timisoara. The next node to be expanded will be Fagaras, because it is closest. Fagaras in turn generates Bucharest, which is the goal.\n\nHere, is the resultant graph.                                              \nGreen coloured node denotes the starting city(Here, Arad).                                             \nRed coloured node denotes the goal city(Here, Bucharest).                                                           \nEdges marked with black is the route from Arad to Bucharest generated by the greedy bfs algorithm.\n\n![shortest route](https://user-images.githubusercontent.com/22571531/27821965-b12030d4-60c1-11e7-9e37-9388e4dd8751.png)\n\n#### Complexity ####\n\nTime: O(b^m)                                                                \nb - Branching factor, the average number of successors per state        \nm - maximum depth of the search \n"
  },
  {
    "path": "Greedy BFS/greedy_bfs.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\nimport Queue as Q\n \n \n\ndef getPriorityQueue(list):\n\tq = Q.PriorityQueue()\n\tfor node in list:\n\t\tq.put(Ordered_Node(heuristics[node],node))\n\treturn q,len(list)\n\n\n\ndef greedyBFSUtil(G, v, visited, final_path, dest, goal): \n\tif goal == 1:\n\t\treturn goal\n\tvisited[v] = True\n\tfinal_path.append(v)\n\tif v == dest:\n\t\tgoal = 1\n\telse:\n\t\tpq_list = []\n\t\tpq,size = getPriorityQueue(G[v])\n\t\tfor i in range(size):\n\t\t\tpq_list.append(pq.get().description)\n\t\tfor i in pq_list:\n\t\t\tif goal != 1:\n\t\t\t\t#print \"current city:\", i\n\t\t\t\tif visited[i] == False :\n\t\t\t\t\tgoal = greedyBFSUtil(G, i, visited, final_path, dest, goal)\n\treturn goal\n\n\n \ndef greedyBFS(G, source, dest, heuristics, pos): \n\tvisited = {}\n\tfor node in G.nodes():\n\t\tvisited[node] = False\n \tfinal_path = []\n\tgoal = greedyBFSUtil(G, source, visited, final_path, dest, 0)\n\tprev = -1\n\tfor var in final_path:\n\t\tif prev != -1:\n\t\t\tcurr = var\n\t\t\tnx.draw_networkx_edges(G, pos, edgelist = [(prev,curr)], width = 2.5, alpha = 0.8, edge_color = 'black')\n\t\t\tprev = curr\n\t\telse:\n\t\t\tprev = var\n\treturn\n\n\n\nclass Ordered_Node(object):\n\tdef __init__(self, priority, description):\n\t\tself.priority = priority\n\t\tself.description = description\n\t\treturn\n\tdef __cmp__(self, other):\n\t\treturn cmp(self.priority, other.priority)\n\ndef getHeuristics(G):\n\theuristics = {}\n\tf = open('heuristics.txt')\n\tfor i in G.nodes():\n\t\tnode_heuristic_val = f.readline().split()\n\t\theuristics[node_heuristic_val[0]] = node_heuristic_val[1]\n\treturn heuristics\n\n\n\n#takes input from the file and creates a weighted graph\ndef CreateGraph():\n\tG = nx.Graph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\tfor i in range(n):\n\t\tgraph_edge_list = f.readline().split()\n\t\tG.add_edge(graph_edge_list[0], graph_edge_list[1], length = graph_edge_list[2]) \n\tsource, dest= f.read().splitlines()\n\treturn G, source, dest\n\n\n\ndef DrawPath(G, source, dest):\n\tpos = nx.spring_layout(G)\n\tval_map = {}\n\tval_map[source] = 'green'\n\tval_map[dest] = 'red'\n\tvalues = [val_map.get(node, 'blue') for node in G.nodes()]\n\tnx.draw(G, pos, with_labels = True, node_color = values, edge_color = 'b' ,width = 1, alpha = 0.7)  #with_labels=true is to show the node number in the output graph\n\tedge_labels = dict([((u, v,), d['length']) for u, v, d in G.edges(data = True)])\n\tnx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels, label_pos = 0.5, font_size = 11) #prints weight on all the edges\n\treturn pos\n\n\n\n#main function\nif __name__ == \"__main__\":\n\tG, source,dest = CreateGraph()\n\theuristics = getHeuristics(G)\n\tpos = DrawPath(G, source, dest)\n\tgreedyBFS(G, source, dest, heuristics, pos)\n\tplt.show()\n\n\n\n\n"
  },
  {
    "path": "Greedy BFS/heuristics.txt",
    "content": "Arad 366\nBucharest 0\nCraiova 160\nDobreta 242\nEforie 161\nFagaras 178\nGiurgiu 77\nHirsova 151\nIasi 226\nLugoj 244\nMehadia 241\nNeamt 234\nOradea 380\nPitesti 98\nRimnicu_Vilcea 193\nSibiu 253\nTimisoara 329\nUrziceni 80\nVaslui 199\nZerind 374"
  },
  {
    "path": "Greedy BFS/input.txt",
    "content": "23\nArad Sibiu 140\nArad Timisoara 118\nArad Zerind 75\nBucharest Fagaras 211\nBucharest Giurgiu 90\nBucharest Pitesti 101\nBucharest Urziceni 85\nCraiova Dobreta 120\nCraiova Pitesti 138\nCraiova Rimnicu_Vilcea 146\nDobreta Mehadia 75\nEforie Hirsova 86\nFagaras Sibiu 99\nHirsova Urziceni 98\nIasi Neamt 87\nIasi Vaslui 92\nLugoj Mehadia 70\nLugoj Timisoara 111\nOradea Zerind 71\nOradea Sibiu 151\nPitesti Rimnicu_Vilcea 97\nRimnicu_Vilcea Sibiu 80\nUrziceni Vaslui 142\nArad\nBucharest"
  },
  {
    "path": "K Centers Problem/README.md",
    "content": "# Visualisation of K - Centers Problem using networkx library\n\n### K - Center ###\n\n K - Center problem (also known as Metric K - Center problem) is a NP - Hard Problem where given n cities, one needs to choose k (k<=n) centers, such that maximum distance of a city to the center is minimized. \n\n In layman terms,say we need to bulid k warehouses given a map of n connected cities. The best way to build a warehouse, is by keeping in mind that, it must be closest to the cities. In other words, the maximum distance of a city to the warehouse must be minimal.\n\n\n Greedy approach:\n\n Here, is an illustration of the simple greedy algorithm which has an approximation factor of 2. It works on the basic idea of choosing the city which is farthest from the current set of centers. \n\n Step 1: Pick an arbitrary center,c<sub>1</sub>.                                                                  \n Step 2: For every remaining cities C<sub>1</sub>,C<sub>2</sub>,.. C<sub>N-1</sub>, compute minimum distnace from the centers chosen already.                                                                                                    \n Step 3: Pick the new center with the highest distance from already chosen centers, that is max((dist(c<sub>1</sub>, C<sub>1</sub>), dist(c<sub>1</sub>,C<sub>2</sub>), ... dist(c<sub>1</sub>, C<sub>N-1</sub>)).                         \n Step 4: Continue this till all the k centers are found.                                            \n\n\n\n#### Working ####\n\nFor the sample input below:\n\n```\n4\n0 10 7 6\n10 0 8 5\n7 8 0 12\n6 5 12 0\n3\n```\nVisualization of the input graph:\n\n![1](https://user-images.githubusercontent.com/22571531/28249724-dcc08a16-6a78-11e7-8fbe-21905190307e.png)\n\nVisualization of the result :                                     \n\nHere, the red colored nodes denote the centers.                                                       \n![2](https://user-images.githubusercontent.com/22571531/28249726-e1255e42-6a78-11e7-9dd2-13b4751c2939.png)\n\n#### Complexity ####\n\nTime: O(n*k)                                                                                                          \nn - number of Cities                                              \nk - number of Centers\n \n\n\n\n"
  },
  {
    "path": "K Centers Problem/input.txt",
    "content": "4\n0 10 7 6\n10 0 8 5\n7 8 0 12\n6 5 12 0\n2"
  },
  {
    "path": "K Centers Problem/k_centers_problem.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\nimport operator\n\n\n\ndef k_centers(G, n):\n\tcenters = []\n\tcities = G.nodes()\n\t#add an arbitrary node, here, the first node,to the centers list\n\tcenters.append((G.nodes())[0])\n\tcities.remove(centers[0]) \n\tn = n-1 #since we have already added one center\n\t#choose n-1 centers\n\twhile n!= 0:\n\t\tcity_dict = {}\n\t\tfor cty in cities:\n\t\t\tmin_dist = float(\"inf\")\n\t\t\tfor c in centers:\n\t\t\t\tmin_dist = min(min_dist,G[cty][c]['length'])\n\t\t\tcity_dict[cty] = min_dist\n\t\t#print city_dict\n\t\tnew_center = max(city_dict, key = lambda i: city_dict[i])\n\t\t#print new_center\n\t\tcenters.append(new_center)\n\t\tcities.remove(new_center)\n\t\tn = n-1\n\t#print centers\n\treturn centers\n\n\n\n#takes input from the file and creates a weighted undirected graph\ndef CreateGraph():\n\tG = nx.Graph()\n\tf = open('input.txt')\n\tn = int(f.readline()) #n denotes the number of cities\n\twtMatrix = []\n\tfor i in range(n):\n\t\tlist1 = map(int, (f.readline()).split())\n\t\twtMatrix.append(list1)\n\t#Adds egdes along with their weights to the graph \n\tfor i in range(n) :\n\t\tfor j in range(n)[i:] :\n\t\t\t\tG.add_edge(i, j, length = wtMatrix[i][j]) \n\tnoc = int(f.readline()) #noc,here,denotes the number of centers\n\treturn G, noc\n\n\n\n#draws the graph and displays the weights on the edges\ndef DrawGraph(G, centers):\n\tpos = nx.spring_layout(G)\n \tcolor_map = ['blue'] * len(G.nodes())\n \t#all the center nodes are marked with 'red'\n \tfor c in centers:\n \t\tcolor_map[c] = 'red'\n\tnx.draw(G, pos, node_color = color_map, with_labels = True)  #with_labels=true is to show the node number in the output graph\n\tedge_labels = nx.get_edge_attributes(G, 'length')\n\tnx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels, font_size = 11) #prints weight on all the edges\n\t\n\n\n#main function\nif __name__ == \"__main__\":\n\tG,n = CreateGraph()\n\tcenters = k_centers(G, n)\n\tDrawGraph(G, centers)\n\tplt.show()\n\n"
  },
  {
    "path": "Kruskal's/README.md",
    "content": "# Visualisation of Kruskal's algorithm using networkx library\n\n### INPUT ###\n\n\nInput is taken from the file \n#### input.txt ####\n\nSample input\n```\n  5\n  0 2 7 -1 -1\n  2 0 3 8 5\n  7 3 0 1 -1\n  -1 8 1 0 4\n  -1 5 -1 4 0\n\n```\nFirst line contains the number of nodes,say n.(Nodes are numbered as 0,1,2,...(n-1) )\nFollowed by n*n weighted matrix. Disconnected edges are represented by negative weight.\n\n### Draw Graph ###\n\n\nGraph is first drawn from the weighted matrix input from the user with weights shown. Edges are marked with black.\n\n\n\n### Kruskal's algorithm ###\n\nKruskal's algorithm is a greedy algorithm that finds a minimum spanning tree for a weighted undirected garph. \n\nThe algorithm operates by adding the egdes one by one in the order of their increasing lengths, so as to form a tree. Egdes are rejected if it's addition to the tree, forms a cycle. This continues till we have V-1 egdes in the tree. (V stands for the number of vertices).\n\nTo understand this better, consider the above input.\n\nThe graph, initially.\n\n![1](https://user-images.githubusercontent.com/22571531/27430044-b959f994-5764-11e7-9b3e-aa0c10dc98e9.png)\n                           \n\n#### After the first iteration: ####\n\nThe smallest edge is of length 1, connecting Node 2 and Node 3. Since it is the first edge, it is added directly to the tree.\n\n\n![2](https://user-images.githubusercontent.com/22571531/27430048-bcf86eb4-5764-11e7-8f03-397f601338b2.png)\n\n\n#### After the second iteration: ####\n\nNext smallest edge is of length 2, connecting Node 0 and Node 1. Since it's addition doesn't result in a cycle, it is added to the tree.\n\n\n![3](https://user-images.githubusercontent.com/22571531/27430058-c0a1da78-5764-11e7-8a0a-a29ab5442d80.png)\n\n#### After the third iteration: ####\n\nNext smallest edge is of length 3, connecting Node 1 and Node 2. Since it's addition doesn't result in a cycle, it is added to the tree.\n\n![4](https://user-images.githubusercontent.com/22571531/27430069-c607466a-5764-11e7-9a2e-7d60e5d50254.png)\n\n#### After the fourth iteration: ####\n\nNext smallest edge is of length 4, connecting Node 3 and Node 4. Since it's addition doesn't result in a cycle, it is added to the tree.\n\nNow we have 4 edges, hence we stop the iteration.\nFinal graph, with red edges denoting the minimum spanning tree.\n\n![5](https://user-images.githubusercontent.com/22571531/27430080-ce205b20-5764-11e7-8bca-20f452d8b20d.png)\n\n#### Complexity ####\n\nTime: O(V^2)                                                                 \nV - Number of vertices                                          "
  },
  {
    "path": "Kruskal's/input.txt",
    "content": "  5\n  0 2 7 -1 -1\n  2 0 3 8 5\n  7 3 0 1 -1\n  -1 8 1 0 4\n  -1 5 -1 4 0"
  },
  {
    "path": "Kruskal's/kruskals_quick_union.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\nimport sys\n\n\n\n# A utility function that return the smallest unprocessed edge\ndef getMin(G, mstFlag):\n    min = sys.maxsize  # assigning largest numeric value to min\n    for i in [(u, v, edata['length']) for u, v, edata in G.edges( data = True) if 'length' in edata ]:\n    \tif mstFlag[i] == False and i[2] < min:\n    \t\tmin = i[2]\n    \t\tmin_edge = i\n    return min_edge\n\n\t\n\n# A utility function to find root or origin of the node i in MST\ndef findRoot(parent, i):\n    if parent[i] == i:\n        return i\n    return findRoot(parent, parent[i])\n\n\n\n# A function that does union of set x and y based on the order\ndef union(parent, order, x, y):\n    xRoot = findRoot(parent, x)\n    yRoot = findRoot(parent, y)\n \t# Attach smaller order tree under root of high order tree\n    if order[xRoot] < order[yRoot]:\n        parent[xRoot] = yRoot\n    elif order[xRoot] > order[yRoot]:\n        parent[yRoot] = xRoot\n    # If orders are same, then make any one as root and increment its order by one\n    else :\n        parent[yRoot] = xRoot\n        order[xRoot] += 1\n\n\n\n# function that performs Kruskals algorithm on the graph G\ndef kruskals(G, pos):\n\teLen = len(G.edges()) # eLen denotes the number of edges in G\n\tvLen = len(G.nodes()) # vLen denotes the number of vertices in G\n\tmst = [] # mst contains the MST edges\n\tmstFlag = {} # mstFlag[i] will hold true if the edge i has been processed for MST\n\tfor i in [ (u, v, edata['length']) for u, v, edata in G.edges(data = True) if 'length' in edata ]:\n\t\tmstFlag[i] = False \n\n\tparent = [None] * vLen # parent[i] will hold the vertex connected to i, in the MST\n\torder = [None] * vLen\t# order[i] will hold the order of appearance of the node in the MST\n\tfor v in range(vLen):\n\t\tparent[v] = v\n\t\torder[v] = 0\n\twhile len(mst) < vLen - 1 :\n\t\tcurr_edge = getMin(G, mstFlag) # pick the smallest egde from the set of edges\n\t\tmstFlag[curr_edge] = True # update the flag for the current edge\n\t\ty = findRoot(parent, curr_edge[1])\n\t\tx = findRoot(parent, curr_edge[0])\n\t\t# adds the edge to MST, if including it doesn't form a cycle\n\t\tif x != y:\n\t\t\tmst.append(curr_edge)\n\t\t\tunion(parent, order, x, y)\n        # Else discard the edge\n    # marks the MST edges with red\n\tfor X in mst:\n\t \tif (X[0], X[1]) in G.edges():\n\t \t\tnx.draw_networkx_edges(G, pos, edgelist = [(X[0], X[1])], width = 2.5, alpha = 0.6, edge_color = 'r')\n\treturn\n\n\n\n# takes input from the file and creates a weighted graph\ndef CreateGraph():\n\tG = nx.Graph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\twtMatrix = []\n\tfor i in range(n):\n\t\tlist1 = map(int, (f.readline()).split())\n\t\twtMatrix.append(list1)\n\t# Adds egdes along with their weights to the graph \n\tfor i in range(n) :\n\t\tfor j in range(n)[i:] :\n\t\t\tif wtMatrix[i][j] > 0 :\n\t\t\t\t\tG.add_edge(i, j, length = wtMatrix[i][j]) \n\treturn G\n\n\n\n# draws the graph and displays the weights on the edges\ndef DrawGraph(G):\n\tpos = nx.spring_layout(G)\n\tnx.draw(G, pos, with_labels = True)  # with_labels=true is to show the node number in the output graph\n\tedge_labels = nx.get_edge_attributes(G, 'length')\n\tnx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels, font_size = 11) #    prints weight on all the edges\n\treturn pos\n\n\n\n# main function\nif __name__ == \"__main__\":\n\tG = CreateGraph()\n\tpos = DrawGraph(G)\n\tkruskals(G, pos)\n\tplt.show()\n\n"
  },
  {
    "path": "Prim's/README.md",
    "content": "# Visualisation of Prim's algorithm using networkx library\n\n### INPUT ###\n\n\nInput is taken from the file \n#### input.txt ####\n\nSample input\n```\n  5\n  0 2 7 -1 -1\n  2 0 3 8 5\n  7 3 0 1 -1\n  -1 8 1 0 4\n  -1 5 -1 4 0\n\n```\nFirst line contains the number of nodes,say n.(Nodes are numbered as 0,1,2,...(n-1) )\nFollowed by n*n weighted matrix. Disconnected egdes are represented by negative weight.\n\n### Draw Graph ###\n\n\nGraph is first drawn from the weighted matrix input from the user with weights shown. Edges are marked with black.\n\n\n\n### Prim's algorithm ###\n\nPrim's algorithm is a greedy algorithm that finds a minimum spanning tree for\na weighted undirected garph. \n\nHere, starting from an arbitrary node, the algorithm operates by building this tree one vertex at a time. At each step, smallest egde connection (also known as cut) from the tree to another vertex is added to the resulting tree.\n\nTo understand this better, consider the above input.\nLet the arbitrary starting node be 0.\n\nThe graph, initially.\n\n![1](https://user-images.githubusercontent.com/22571531/27369441-88710056-5675-11e7-8b11-251a2992b38b.png)\n\nWe use the following 3 lists:\n\n#### dist ####\n dist[i] will hold the minimum weight edge value of node i to be included in MST(Minimum Spanning Tree).                               \n#### parent ####                               \nparent[i] will hold the vertex connected to i, in the MST edge.                          \n#### mstSet ####                         \nmstSet[i] will hold true if vertex i is included in the MST.                           \n\n#### Initial values: ####\n```\ndist   = [0, inf ,inf, inf, inf]\nparent = [-1, None, None, None]                        \nmstSet = [True, False, False, False, False]\n```\n\n#### After the first iteration: ####\n\nNode 1 and Node 2 form an edge with the starting node,i.e, 0 with a distance of 2 and 7 respectively. Hence they are updated accordingly.\n\n```\ndist   = [0, 2, 7, inf, inf]\nparent = [-1, 0, 0, None, None] \nmstSet = [True, False, False, False, False]\n```\n\nMinimum most edge value of the nodes which are not included in the MST yet, i.e, where mstSet[i] == False, is node 1.\nThe node is now included in the MST, and thus, mstSet[1] is set to True.\n\n![2](https://user-images.githubusercontent.com/22571531/27369443-8aded584-5675-11e7-9a35-a34dd3b4ba40.png)\n\n\n#### After the second iteration: ####\n\n```\ndist   = [0, 2, 3, 8, 5]\nparent = [-1, 0, 1, 1, 1]\nmstSet = [True, True, False, False, False]\n```\n\n![3](https://user-images.githubusercontent.com/22571531/27369444-8d5e5a6e-5675-11e7-9e82-d44277d59257.png)\n\n#### After the third iteration: ####\n\n```\ndist   = [0, 2, 3, 1, 5]\nparent = [-1, 0, 1, 2, 1]\nmstSet = [True, True, True, False, False]\n```\n\n![4](https://user-images.githubusercontent.com/22571531/27369448-917e86be-5675-11e7-8ecf-6d92d4e34782.png)\n\n#### After the fourth iteration: ####\n\n```\ndist   = [0, 2, 3, 1, 4]\nparent = [-1, 0, 1, 2, 3]\nmstSet = [True, True, True, True, False]\n```\n\nHere, the red edges denote the Minimum Spanning Tree\n\n![5](https://user-images.githubusercontent.com/22571531/27369450-947b6710-5675-11e7-81e3-0aff0dd4d224.png)\n\n#### Complexity ####                                  \n\nTime: O(V^2)                                                                 \nV - Number of vertices                                                    \n"
  },
  {
    "path": "Prim's/input.txt",
    "content": "  5\n  0 2 7 -1 -1\n  2 0 3 8 5\n  7 3 0 1 -1\n  -1 8 1 0 4\n  -1 5 -1 4 0"
  },
  {
    "path": "Prim's/prims.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\nimport sys\n\n\n#utility function that returns the minimum egde weight node\ndef minDistance(dist, mstSet, V):\n   \tmin = sys.maxsize #assigning largest numeric value to min\n   \tfor v in range(V):\n   \t\tif mstSet[v] == False and dist[v] < min:\n   \t\t\tmin = dist[v]\n   \t\t\tmin_index = v\n\treturn min_index\n\n\n\n#function that performs prims algorithm on the graph G\ndef prims(G, pos):\n\tV = len(G.nodes()) # V denotes the number of vertices in G\n\tdist = [] # dist[i] will hold the minimum weight edge value of node i to be included in MST\n\tparent = [None]*V # parent[i] will hold the vertex connected to i, in the MST edge\n\tmstSet = [] # mstSet[i] will hold true if vertex i is included in the MST\n\t#initially, for every node, dist[] is set to maximum value and mstSet[] is set to False\n\tfor i in range(V):\n\t\tdist.append(sys.maxsize)\n\t\tmstSet.append(False)\n\tdist[0] = 0\n\tparent[0]= -1 #starting vertex is itself the root, and hence has no parent\n\tfor count in range(V-1):\n\t\tu = minDistance(dist, mstSet, V) #pick the minimum distance vertex from the set of vertices\n\t\tmstSet[u] = True\n\t\t#update the vertices adjacent to the picked vertex\n\t\tfor v in range(V):\n\t\t\tif (u, v) in G.edges():\n\t\t\t\tif mstSet[v] == False and G[u][v]['length'] < dist[v]:\n\t\t\t\t\tdist[v] = G[u][v]['length']\n\t\t\t\t\tparent[v] = u\n\tfor X in range(V):\n\t\tif parent[X] != -1: #ignore the parent of the starting node\n\t\t\tif (parent[X], X) in G.edges():\n\t\t\t\tnx.draw_networkx_edges(G, pos, edgelist = [(parent[X], X)], width = 2.5, alpha = 0.6, edge_color = 'r')\n\treturn\n\n\n\n#takes input from the file and creates a weighted graph\ndef CreateGraph():\n\tG = nx.Graph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\twtMatrix = []\n\tfor i in range(n):\n\t\tlist1 = map(int, (f.readline()).split())\n\t\twtMatrix.append(list1)\n\t#Adds egdes along with their weights to the graph \n\tfor i in range(n) :\n\t\tfor j in range(n)[i:] :\n\t\t\tif wtMatrix[i][j] > 0 :\n\t\t\t\t\tG.add_edge(i, j, length = wtMatrix[i][j]) \n\treturn G\n\n\n\n#draws the graph and displays the weights on the edges\ndef DrawGraph(G):\n\tpos = nx.spring_layout(G)\n\tnx.draw(G, pos, with_labels = True)  #with_labels=true is to show the node number in the output graph\n\tedge_labels = nx.get_edge_attributes(G,'length')\n\tnx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels, font_size = 11) #prints weight on all the edges\n\treturn pos\n\n\n\n#main function\nif __name__ == \"__main__\":\n\tG = CreateGraph()\n\tpos = DrawGraph(G)\n\tprims(G, pos)\n\tplt.show()\n\n"
  },
  {
    "path": "README.md",
    "content": "# Visualization-of-popular-algorithms-in-Python\n\n### Description\n\nThe project aims to create visual outputs for popular graph algorithms like DFS,BFS and NP-HARD problems like Travelling Salesman Problem and Graph colouring problems using NetworkX graph library of Python. It is not just limited to getting a visual output, but the algorithms will be optimised to its best by using heuristics for non-polynomial time algorithms. The project aims to create a better understanding of the working of the algorithms, in-depth understanding of the application of heuristics to improve the computation time and usage of the later to our advantage in optimising the algorithm. It could be used by analysts as well as students and teachers, as a teaching aid. It could definitely serve all the applications of Np-hard problems like- School scheduling, Tourist Itineraries, etc.\n\n### Motivation\n\nDFS,BFS and NP-Hard algorithms have been there for years now and it has been coded out in every programming language as well. This project aims in visulization of them, to create a better understanding. Solving most of the above mentioned algorithm using brute force-technique might give the optimal solution, however, as the problem size increases, the search for an optimal solution will no longer be worth the effort. Hence, by involving heuristics, we aim to improve the time complexity while arriving at a good solution( need not be optimal always). (Heuristics is used, to predict how close the end of path is to a solution, so that the paths which are judged to be closer to a solution are extended first.)\n\nIt includes:\n### 1. DFS:\n[DFS](/DFS)\n### 2. BFS:\n[BFS](/BFS)\n### 3. Dijsktra's:\n[Dijsktra's](/Dijsktra's)\n### 4. Prim's:\n[Prim's](/Prim's)\n### 5. Kruskal's:\n[Kruskal's](/Kruskal's)\n### 6. Assignment Problem:\n[Assignment Problem](/Assignment%20Problem)\n### 7. Travelling Salesman Problem:\n[Travelling Salesman Problem](/Travelling%20Salesman%20Problem)\n### 8. Greedy Best First Search:\n[Greedy BFS](/Greedy%20BFS)\n### 9. A* Search:\n[A* Search](/A_star_search)\n### 10. Topological Sort:\n[Topological Sort](/Topological%20Sort)\n### 11. Graph Coloring Problem:\n[Graph-Coloring Problem](/Graph%20Coloring)\n### 12. K Centers Problem:\n[K Centers Problem](/K%20Centers%20Problem)\n### 13. Egocentric Network:\n[Egocentric Network](/Egocentric%20Network)\n### 14. Bellman-Ford algorithm:\n[Bellman Ford](/BellmanFord)\n"
  },
  {
    "path": "Topological Sort/README.md",
    "content": "# Visualisation of Topological sort algorithm using networkx library\n\n### Topological sort ###\n\n Topological sort of a directed graph is a linear ordering of its vertices such that for every directed edge uv from vertex u to vertex v, u comes before v in the ordering. For instance, the vertices of the graph may represent tasks to be performed, and the edges may represent constraints that one task must be performed before another; in this application, a topological ordering is just a valid sequence for the tasks.\n PS: Topological sorting is possible only if the graph is a directed acyclic graph.\n\n Two commom approaches for topological sort:\n 1. Kahn's algorithm\n 2. Depth - first search\n\n The code here is an implementation of Kahn's algorithm.\n\n #### Kahn's algorithm ####\n\n This is computationally simpler compared to DFS approach.\n\n Step 1: Find all the nodes in the graph with in-degree as 0 and add them into a queue\n Step 2: Remove the nodes from the queue one by one, append it to the sorted_list and simulatneously update the graph(remove the node from the graph, resulting which, in-degree of nodes which had edges directed from the reomved node decreases by one).\n Step 3: If there are anymore nodes left in the graph, go back to step 1 \n\n This method is optimal but modifies the graph. For the algorithm to not modify the original graph, you'll need to maintain a boolean array visited[] - to keep track to the visited nodes and indegree[] to store the in-degree of the graph nodes.\n\n#### Working ####\n\nConsider the sample input below:\n\n```\n6\n1 2\n1 3\n2 3\n2 4\n3 4\n3 5\n```\nVisualization of the input graph:\n\n![1](https://user-images.githubusercontent.com/22571531/27983933-e09f086c-63e6-11e7-9830-b63a48b829b6.png)\n\n\nNode 1 is the only node with in-degree as 0.\nRemove it from the graph, and append it to the sorted_list.\nsorted_list = [1]\n\nNow, Node 2 has an in-degree of 0. Remove it from the graph, and append it to the sorted list.\nsorted_list = [1,2]\n\nNext, Node 3 has an in-degree of 0. \nsorted_list = [1,2 3]\n\nNext, Node 4 and Node 5, both have an in-degree of 0.\nsorted_list = [1,2,3,4,5]\nNote that: [1,2,3,5,4] is also the right order.\n\nVisualization of the topologically sorted order.                              \nGreen node - denotes the starting node.                                      \nRed node - denotes the final node.\n\n![2](https://user-images.githubusercontent.com/22571531/27983935-e5d92286-63e6-11e7-92f3-e45c9bbb6039.png)                                                                             \n\n\n \n\n\n\n"
  },
  {
    "path": "Topological Sort/input.txt",
    "content": "6\n1 2\n1 3\n2 3\n2 4\n3 4\n3 5\n"
  },
  {
    "path": "Topological Sort/topological_sort.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\n \n\ndef topologicalSort(G,pos):\n\tzero_indeg_list = [] \n\tsorted_list = []\n\tvisited = [False]*len(G.nodes())\n\twhile len(G.nodes())!=0:\n\t\tfor node in G.nodes():\n\t\t\tif visited[node-1] == False:\n\t\t\t\tif G.in_degree(node) == 0:\n\t\t\t\t\tvisited[node-1] = True\n\t\t\t\t\tzero_indeg_list.append(node)\n\t\tfor node in zero_indeg_list:\n\t\t\tsorted_list.append(node)\n\t\t\tG.remove_node(node)\n\t\t\tzero_indeg_list.remove(node)\n\treturn sorted_list\n\n\t\t\n#takes input from the file and creates a directed graph\ndef CreateResultGraph(sorted_list):\n\tD = nx.DiGraph()\n\tfor i in range(len(sorted_list)-1): \n\t \tD.add_edge(sorted_list[i], sorted_list[i+1]) \n\tpos = nx.spring_layout(D)\n\tval_map = {}\n\tval_map[sorted_list[0]] = 'green'\n\tval_map[sorted_list[len(sorted_list)-1]] = 'red'\n\tvalues = [val_map.get(node, 'blue') for node in D.nodes()]\n\tnx.draw(D, pos, with_labels = True, node_color =values)\n\t\n\n#takes input from the file and creates a directed graph\ndef CreateGraph():\n\tG = nx.DiGraph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\tfor i in range(n):\n\t\tadj_list = map(int, (f.readline()).split()) \n\t\tG.add_edge(adj_list[0], adj_list[1]) \n\treturn G\n\n\n\n#draws the graph\ndef DrawGraph(G):\n\tpos = nx.spring_layout(G)\n\tnx.draw(G, pos, with_labels = True, node_color ='blue')  #with_labels=true is to show the node number in the output graph\n\treturn pos\n\n\n\n#main function\nif __name__== \"__main__\":\n\tG = CreateGraph()\n\tplt.figure(1)\n\tpos = DrawGraph(G)\n\tplt.figure(2)\n\tsorted_list = topologicalSort(G,pos)\n\tCreateResultGraph(sorted_list)\n\tplt.show()\n\n"
  },
  {
    "path": "Travelling Salesman Problem/README.md",
    "content": "# Visualisation of Travelling Salesman Problem using networkx library\n\n### Travelling Salesman Problem ###\n\nTravelling salesman problem is a NP hard problem. Given a set of cities and the distance between every pair of cities, the problem is to find the shortest possible route that visits each city exactly once and returns back to the original city. Hence, it also belongs to the class of optimization problems. \n\n#### Why NP-hard?\n\nFirst, let us understand the definition of NP- hard.\nNP (nondeterministic polynomial time) problem is the one whose solution could be verified in polynomial time but the problem is not guaranteed to be solved in polynomial time.\nNow, NP - hard problem are those which are atleast as hard as any NP problem.\nNP complete problem is the class of problems that are both NP and NP-hard.\n\nLet us now check both the conditions.\n\n ##### condition (i): NP\n  To check that given solution is the right solution for a TSP problem. We need to verify two things:\n  Firstly, each city must be visited exactly once. (could be done in polynomial time)\n  Secondly, there is no shorter route than the current solution. (This cannot be guaranteed in polynomial time)\n  Hence, TSP is not NP\n\n ##### condition (ii): NP hard\n Surely TSP is a NP hard problem. (For, even it's solution can't be guaranteed in polynomial time)\n\n Thus, TSP belongs to the class of NP-hard problem and not NP-complete.\n\n\nBrute force approach for TSP will need all possible paths to be calculated which is (n-1)! paths( where n is the number of cities). As n increases, it is computationally not feasible to compute that many paths.\n\nThere are certain approximation algorithms for TSP which guarantees to solve the problem in polynomial time at the cost of solution not being exact. Christofides algorithm, is one such heuristics approach which guarantees it's solution to be within a factor of 1.5 of the optimal solution. By far, Christofides algorithm (time complexity : O(n^3)) is known to have the best approximation ratio for a general TSP problem. \n\n#### Christofides algorithm:\n\n1. Create a minimum spanning tree MST of G. (using Kruskal's or Prim's algorithm)\n2. Let odd_vert be the set of vertices with odd degree in MST. The number of vertices with odd_degree is guaranteed to be even( Proof: Handshaking Lemma).\n3. Find a minimum-weight perfect matching pairs in the induced subgraph given by the vertices from odd_vert. Add those edges to MST.\n The resulting MST now has all the vertices with even degree- hence, is a Eulerian circuit.\n4. Make the circuit found in previous step into a Hamiltonian circuit by skipping repeated vertices.\n\nThe code here,is an implementation of Christofides algorithm. \n\n### INPUT ###\n\n\nInput is taken from the file \n#### input.txt ####\n\nSample input\n```\n5\n0 10 8 9 7\n10 0 10 5 6\n8 10 0 8 9\n9 5 8 0 6\n7 6 9 6 0\n\n```\nFirst line contains n, the number of cities.\nFollowed by n*n distance matrix where matrix[i][j] denotes the distance between city i and city j.\n\n\n### Draw Graph ###\n\n\nAn undireced graph is drawn with nodes representing the cities and egde labels denoting the distance between them.\n\n![screenshot from 2017-06-29 12-50-58](https://user-images.githubusercontent.com/22571531/27676532-f2af862a-5ccb-11e7-9ba3-8a9cb87adca9.png)\n\nStep 1:\n\nA minimum spanning tree MST is obtained from the given grapg G (using Kruskal's algorithm)\n\n![screenshot from 2017-06-29 12-53-47](https://user-images.githubusercontent.com/22571531/27676537-f787e962-5ccb-11e7-8da7-e48e223d33a8.png)\n\nStep 2:\n\nThere are 2 vertices with odd degree in MST graph, that is, node 2 and node 3.\nHence, odd_vert = [2,3]\n\nStep 3:\n\nSince there are only 2 vertices in odd_vert, we get one minimum weight matching pair, i,e, (2,3). Adding this edge to MST, we have the below graph.\n\n![screenshot from 2017-06-29 12-48-48](https://user-images.githubusercontent.com/22571531/27676543-fb8d0d76-5ccb-11e7-93b9-bc7d6767b24d.png)\n\n\nStep 4:\n\nFinding the shortest hamiltonian circuit from the above graph (by skipping already visisted vertices) , we have\n```\n0 -> 2 -> 3 -> 1 -> 4 -> 0\n```\n\nThe below diagram shows the shortest route for TSP. \nPS: The arrows here are just for visual purposes to denote the route. The cycle could be traversed in any direction.\n\n![second](https://user-images.githubusercontent.com/22571531/27676549-01632fc8-5ccc-11e7-964e-eece9960b4b8.png)\n\n#### Complexity ####\n\nTime: O(n^3)                                                          \nn - number of Nodes"
  },
  {
    "path": "Travelling Salesman Problem/input.txt",
    "content": "5\n0 10 8 9 7\n10 0 10 5 6\n8 10 0 8 9\n9 5 8 0 6\n7 6 9 6 0"
  },
  {
    "path": "Travelling Salesman Problem/tsp_christofides.py",
    "content": "import networkx as nx\nimport matplotlib.pyplot as plt\nimport sys\n\n# A utility function that return the smallest unprocessed edge\ndef getMin(G, mstFlag):\n    min = sys.maxsize  # assigning largest numeric value to min\n    for i in [(u, v, edata['length']) for u, v, edata in G.edges( data = True) if 'length' in edata ]:\n    \tif mstFlag[i] == False and i[2] < min:\n    \t\tmin = i[2]\n    \t\tmin_edge = i\n    return min_edge\n\n# A utility function to find root or origin of the node i in MST\ndef findRoot(parent, i):\n    if parent[i] == i:\n        return i\n    return findRoot(parent, parent[i])\n\n\n# A function that does union of set x and y based on the order\ndef union(parent, order, x, y):\n    xRoot = findRoot(parent, x)\n    yRoot = findRoot(parent, y)\n \t# Attach smaller order tree under root of high order tree\n    if order[xRoot] < order[yRoot]:\n        parent[xRoot] = yRoot\n    elif order[xRoot] > order[yRoot]:\n        parent[yRoot] = xRoot\n    # If orders are same, then make any one as root and increment its order by one\n    else :\n        parent[yRoot] = xRoot\n        order[xRoot] += 1\n\n#function that performs kruskals algorithm on the graph G\t\ndef genMinimumSpanningTree(G):\n\tMST = nx.Graph()\n\teLen = len(G.edges()) # eLen denotes the number of edges in G\n\tvLen = len(G.nodes()) # vLen denotes the number of vertices in G\n\tmst = [] # mst contains the MST edges\n\tmstFlag = {} # mstFlag[i] will hold true if the edge i has been processed for MST\n\tfor i in [ (u, v, edata['length']) for u, v, edata in G.edges(data = True) if 'length' in edata ]:\n\t\tmstFlag[i] = False \n\n\tparent = [None] * vLen # parent[i] will hold the vertex connected to i, in the MST\n\torder = [None] * vLen\t# order[i] will hold the order of appearance of the node in the MST\n\tfor v in range(vLen):\n\t\tparent[v] = v\n\t\torder[v] = 0\n\twhile len(mst) < vLen - 1 :\n\t\tcurr_edge = getMin(G, mstFlag) # pick the smallest egde from the set of edges\n\t\tmstFlag[curr_edge] = True # update the flag for the current edge\n\t\ty = findRoot(parent, curr_edge[1])\n\t\tx = findRoot(parent, curr_edge[0])\n\t\t# adds the edge to MST, if including it doesn't form a cycle\n\t\tif x != y:\n\t\t\tmst.append(curr_edge)\n\t\t\tunion(parent, order, x, y)\n        # Else discard the edge\n\tfor X in mst:\n\t\tif (X[0], X[1]) in G.edges(): \n\t\t\t\tMST.add_edge(X[0], X[1], length = G[X[0]][X[1]]['length']) \n\treturn MST\n\n\n#utility function that adds minimum weight matching edges to MST\ndef minimumWeightedMatching(MST, G, odd_vert):\n\twhile odd_vert:\n\t\tv = odd_vert.pop()\n\t\tlength = float(\"inf\")\n\t\tu = 1\n\t\tclosest = 0\n\t\tfor u in odd_vert:\n\t\t\tif G[v][u]['length'] < length :\n\t\t\t\tlength = G[v][u]['length']\n\t\t\t\tclosest = u\n\t\tMST.add_edge(v, closest, length = length)\n\t\todd_vert.remove(closest)\n  \n\n\n\ndef christofedes(G ,pos):\n\topGraph=nx.DiGraph()\n\t#optimal_dist = 0\n\tMST = genMinimumSpanningTree(G) # generates minimum spanning tree of graph G, using Prim's algo\n\todd_vert = [] #list containing vertices with odd degree\n\tfor i in MST.nodes():\n\t\tif MST.degree(i)%2 != 0: \n\t\t\todd_vert.append(i) #if the degree of the vertex is odd, then append it to odd_vert list\n\tminimumWeightedMatching(MST, G, odd_vert) #adds minimum weight matching edges to MST\n\t# now MST has the Eulerian circuit\n\tstart = MST.nodes()[0]\n\tvisited = [False] * len(MST.nodes())\n\t# finds the hamiltonian circuit\n\tcurr = start\n\tvisited[curr] = True\n\tfor nd in MST.neighbors(curr):\n\t\t\tif visited[nd] == False or nd == start:\n\t\t\t\tnext = nd\n\t\t\t\tbreak\n\twhile next != start:\n\t\tvisited[next]=True\n\t\topGraph.add_edge(curr,next,length = G[curr][next]['length'])\n\t\tnx.draw_networkx_edges(G, pos, arrows = True, edgelist = [(curr, next)], width = 2.5, alpha = 0.6, edge_color = 'r')\n\t\t# optimal_dist = optimal_dist + G[curr][next]['length']\n\t\t# finding the shortest Eulerian path from MST\n\t\tcurr = next\n\t\tfor nd in MST.neighbors(curr):\n\t\t\tif visited[nd] == False:\n\t\t\t\tnext = nd\n\t\t\t\tbreak\n\t\tif next == curr:\n\t\t\tfor nd in G.neighbors(curr):\n\t\t\t\tif visited[nd] == False:\n\t\t\t\t\tnext = nd\n\t\t\t\t\tbreak\n\t\tif next == curr:\n\t\t\tnext = start\n\topGraph.add_edge(curr,next,length = G[curr][next]['length'])\n\tnx.draw_networkx_edges(G, pos, edgelist = [(curr, next)], width = 2.5, alpha = 0.6, edge_color = 'r')\n\t# optimal_dist = optimal_dist + G[curr][next]['length']\n\t# print optimal_dist\n\treturn opGraph\n\n\n\n\n\t\n#takes input from the file and creates a weighted undirected graph\ndef CreateGraph():\n\tG = nx.Graph()\n\tf = open('input.txt')\n\tn = int(f.readline())\n\twtMatrix = []\n\tfor i in range(n):\n\t\tlist1 = map(int, (f.readline()).split())\n\t\twtMatrix.append(list1)\n\t#Adds egdes along with their weights to the graph \n\tfor i in range(n) :\n\t\tfor j in range(n)[i:] :\n\t\t\tif wtMatrix[i][j] > 0 :\n\t\t\t\t\tG.add_edge(i, j, length = wtMatrix[i][j]) \n\treturn G\n\ndef DrawGraph(G,color):\n\tpos = nx.spring_layout(G)\n\tnx.draw(G, pos, with_labels = True, edge_color = color)  #with_labels=true is to show the node number in the output graph\n\tedge_labels = nx.get_edge_attributes(G,'length')\n\tnx.draw_networkx_edge_labels(G, pos, edge_labels = edge_labels,  font_size = 11) #prints weight on all the edges\n\treturn pos\n\n\n#main function\nif __name__ == \"__main__\":\n\tG = CreateGraph()\n\tplt.figure(1)\n\tpos = DrawGraph(G,'black')\n\topGraph = christofedes(G, pos)\n\tplt.figure(2)\n\tpos1 = DrawGraph(opGraph,'r') \n\tplt.show()"
  },
  {
    "path": "setup.sh",
    "content": "#!/bin/bash\nif [ $(uname -s) == \"Linux\" ]; then\n  declare -a distributions=(\"Manjaro\" \"Ubuntu\" \"Arch\");\n  declare -a distpackagemgrs=(\"1\" \"0\" \"1\");\n  declare -a packagemgr=(\"apt-get\" \"pacman\");\n\n  dist_count=${#distributions[*]}\n  usable_mgr=\"-1\"\n\n  dist_name=$(lsb_release -a);\n\n  for (( i=0; i<=$(( $dist_count -1 )); i++ ))\n  do\n      if [ $(echo \"$dist_name\" | grep -c \"${distributions[$i]}\") -gt 0 ]; then\n          usable_mgr=${distpackagemgrs[$i]}\n          echo \"Found Distribution ${distributions[$i]}, will use ${packagemgr[usable_mgr]}\"\n      fi\n  done\n\n  if [ $usable_mgr == \"-1\" ]; then\n      echo \"Err: Linux distibution unknown, will use apt-get\"\n      usable_mgr=\"0\"\n  fi\n\n  case $usable_mgr in\n      \"0\")\n      echo \"-- apt-get install --\"\n      sudo apt-get install python2.7-dev python-pip -y\n\n      ;;\n      \"1\")\n      echo \"-- pacman installation --\"\n      sudo pacman -S python2 python-pip -y\n\n      ;;\n  esac\nfi\n\nif [ $(uname -s) == \"Darwin\" ]; then\n  sudo easy_install pip\n\nfi\n\nsudo pip2 install matplotlib\nsudo pip2 install networkx\n\n\n\n\n"
  }
]