Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Coursework2-7015511/380CT - Theoretical Aspects of Computer Science Coursework.ipynb
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
767 lines (767 sloc)
140 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# 380CT - Theoretical Aspects of Computer Science\n", | |
"## Coursework 2\n", | |
" \n", | |
"***" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"- **Name:** Shahzeb Dawood <br>\n", | |
"- **Student ID:** 7015511 <br>\n", | |
"- **Github Repository Link:** https://github.coventry.ac.uk/380CT-1718JANMAY/Coursework2-7015511 <br>\n", | |
"\n", | |
"***" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Notation\n", | |
"Let a given Graph be _G_, Number of nodes be _N_ and the probability of edge creation be _e_.\n", | |
"\n", | |
"***" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Definition of the problem" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Directed Hamiltonian Cycle Problem <br>\n", | |
"\n", | |
"Given a directed graph G = (N, e), a Hamiltonian cycle in G is a path in the graph, starting and ending at the same node, such that every node in N is traversed exactly once (Rudoy 2017). <br>\n", | |
"\n", | |
"Hence, the Directed Hamiltonian Cycle Problem are referred to as problems to determine whether a given a graph has a Hamiltonian cycle. <br>\n", | |
"\n", | |
"Also referred to as a special case of the \"Traveling Salesman Problem\" (Plesn´ik 1979). <br>\n", | |
"\n", | |
"### The Traveling Salesman Problem: <br>\n", | |
"\n", | |
"Is a very well-known NP Complete permutation problem with the aim of finding the path of the shortest length (or minimum cost) on a graph. The traveling salesman starts at one node, visits all other nodes successively only one time each, and finally returns to the starting node (RAO et al. 2014). <br>\n", | |
"<br>\n", | |
"This is identical to our DHCP. The relationship between the two is defined such that a Traveling salesman problem solving operation can determine a minimum weight Hamiltonian cycle.<br>\n", | |
"\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Complexity Class Membership\n", | |
"__Np complete__\n", | |
"\n", | |
"In the work of Garey and Johnson: __The Hamiltonian Circuit belongs to NP__ <br>\n", | |
"\n", | |
"And to quote Garey and Johnson \"The Hamiltonian circuit belongs to NP, because a nondeterministic algorithm need only guess an ordering of the vertices and check in polynomial time that all required edges belong to the edge set of the given graph\" (Garey and Johnson 1982). <br>\n", | |
"\n", | |
"And since: _Hamiltonian Circuit == Hamiltonian Cycle_ <br>\n", | |
"\n", | |
"Hence proved: __The Hamiltonian Cycle Problem belongs to NP__<br>\n", | |
"\n", | |
"\n", | |
"Additionally, _\"The ordered list of vertices in a directed Hamiltonian path can serve as a certificate of its place in NP_ (Arora and Barak 2016).\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Decision <br>\n", | |
"\n", | |
"For a given directed graph, decide whether it contains a path that traverses by visiting every vertex just once and terminates at the origin vertices. <br>\n", | |
"\n", | |
"Traverse random generated graphs using different algorithm to decide whether a given graph is a Hamiltonian cycle graph or not. <br>\n", | |
"\n", | |
"__NP-complete__, because DHCP belongs to NP <br>\n", | |
"\n", | |
"DHCP belongs to NP: Once a random graph is generated, we can quickly \"verify\" its Hamiltonian in cycle presence quickly. <br>\n", | |
"\n", | |
"\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Computation - Search/Traverse Graph\n", | |
"\n", | |
"Given that the problem is decidable, then find a graph that meets the criterion of the Hamiltonian cycle. <br>\n", | |
"\n", | |
"__NP-Complete__\n", | |
"Once we have a given graph, the determination of its Hamiltonian Cycle presence is only a matter of verificiation. Hence the Computation of the problem is no different to its decideabillity and it belongs to NP complete. <br>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Optimisation\n", | |
"Find a graph that contains Hamiltonian cycle while minimizing non-hamiltonian cycle determinations or alternatively decreasing the runtime of determinating algorithm. <br>\n", | |
"\n", | |
"__NP-Hard__\n", | |
"\n", | |
"Optimization versions of NP-complete problems are automatically NP-Hard. <br>\n", | |
"\n", | |
"***" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Testing Methodology\n", | |
"\n", | |
"Comparison of all 3 algorithms based on their O notation and Bog O notation graph. With suggestions on what kind of situation they will be best translated into. <br>\n", | |
"\n", | |
"Since the actual code isn’t adapted after attempts but due to shortage of time the big O notation for the pseudocode is compared instead of the actual accuracy and runtime performance of the algorithm based on increasing graph nodes and probability of connection. <br>\n", | |
"\n", | |
"\n", | |
"***" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Random Instance Generation <br>\n", | |
"\n", | |
"The random graph is generated using a built in Python library function (Library 'Networkx'). The function takes in parameters for the number of nodes 'n', their probability of connection 'e' and the nature of the graph edges (directed/undirected). <br>\n", | |
"\n", | |
"The probability of edge creation 'e' works like a coin toss. The user defined probability enables the algorithm to set the odds between each node having a connection between them. The higher the probability of edge connection, the more connected the graph tends to be. <br>\n", | |
"\n", | |
"For testing of the algorithm, it is to be ensured that every graph being given to them is a Hamiltonian Cycle graph. This is achieved by the following: <br>\n", | |
"\n", | |
"Once a random graph is generated, the following steps are taken to check whether the graph generated is a Hamiltonian cycle graph: <br>\n", | |
"\n", | |
"1. Determine and store all cycles in the graph\n", | |
"2. Find the longest cycle in graph\n", | |
"3. Check that said cycle has traversed through all nodes just once \n", | |
"4. Check that the cycle terminates at the start node\n", | |
"\n", | |
"Given that the mentioned conditions are fulfilled, the “Hamiltonian_Generator\" function returns the graph with confidence that it is a Hamiltonian Cycle Graph. <br>\n", | |
"\n", | |
"***\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Code" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Relevant Librarie(s):" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import networkx as nx" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Random Graph Generation:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/png": "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iZ6enhwyZAj37dtXYGLXrVu3uHLlSg4cOJD+/v6sV68eR40axf79+9Pd3b3YEBZqtZrx8fH87LPP2KhRIwYEBPCdd97hwYMHjYqpExcXR19fX8bExJjkuk3N7du3GRQUVOScjJo1a5q0n8tcSENQSbl37x6HDh3KwMBAbt261dJydPTp04ebNm3SfT579iwHDBhgsFFYuXIlFQqF2eLt5Obm0tvbm6GhoWUqR61WMzAwsECYifLi5s2bnD17Nps3b04vLy+GhIQwKCiInp6efPnll7lo0SJevny50HGPh7BISEjgsWPH+OGHH7JOnTqsW7cux40bx9jY2DJ10B8+fJg+Pj48dOhQWS7T5KSmprJFixacOnWq3v1Tp06lra3tEzHS6XGkIajkHDhwgPXr1+dLL71kFeO033rrLc6ZM0fvPn1G4aOPPtIZBZVKRXd3d7766qvmlMyzZ89SoVAwOjq61GXEx8czKCioXEd3qVQq/v777/zqq6/YqVMnuri4sGXLlgwPD2f16tXZoEEDTp06tdj4VUqlkv/3f/+nmytib2/PqKgoJiQkmFR7TEyM3o5YS5GZmcmwsDC+9dZbeq8zKSmJNjY2Jp8QaS6kIZAwMzOTn332GX19fblo0SKLjnueMWMGP/rooxLzPW4UatWqxbZt29Le3r5c48sXRXR0NBUKRamf6CdPnswPPvjAxKo0o6e+//57RkVF0dfXlw0bNuTbb7/Nbdu2FZiBrlarGRsby7fffpt+fn5s06YN58yZw9u3bzM7O5t79uzh8OHD6evryxYtWnDatGnctWtXuYaw2Lp1K/38/CwePC83N5d9+vRhVFRUkf+NkJAQ1q1b18zKTIc0BBIdZ86cYdu2bdmxY8dC46LNxapVqzhgwACjjklMTOTLL7+sizBaq1Ytfvzxx8UOYywPQkND6ePjU6pY982bNzd6ARx9pKWlcceOHXz33XfZuHFjent7s3///ly6dKnBcZJyc3O5detWhoeH087Ojra2tgwKCuIXX3yhd1F6fSEsTDViJq8/y1JDn9VqNYcOHcpu3boVeU157sg//vjDzOpMhzQEkgIolUrOmzeP3t7enDJlitmfrvfv38+wsDCjj3vppZfo7e3NxMRERkVF6RaVqVWrFsePH2+WUArp6el0cXFhz549SWo6Xw0ZoXP16tVSGxClUskTJ05w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\n", | |
"text/plain": [ | |
"<matplotlib.figure.Figure at 0x20ff8e5d8d0>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"#Function for random generation of a directed graph with specified number of nodes\n", | |
"#and probability of connection between nodes\n", | |
"def RandomGraphGenerator(Nodes, ProbabilityCnct):\n", | |
" \n", | |
" G = nx.erdos_renyi_graph(Nodes, ProbabilityCnct, directed=True)\n", | |
" \n", | |
" return(G)\n", | |
"\n", | |
"#Plotting the randomly generated Graph\n", | |
"if __name__ == \"__main__\":\n", | |
" Random_Graph = RandomGraphGenerator(10, 0.5)\n", | |
" nx.draw_networkx(Random_Graph, node_color=\"yellow\", edge_color=\"k\")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"The above graph shows a randomly generated with 10 nodes and an edge connection probability of 50% <br>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Definite Hamiltonian Graph Generation:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<matplotlib.figure.Figure at 0x20ff8cc1940>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"#Function for definite Hamiltonian cycle graph generation with \n", | |
"#specified number of nodes and probability of connection between nodes\n", | |
"def Hamiltonian_Generator(Nodes, ProbabilityCnct):\n", | |
"\n", | |
" Hamiltonian = False\n", | |
" \n", | |
" #Runs until either a Hamiltonian Cycle is found\n", | |
" while Hamiltonian != True:\n", | |
" \n", | |
" #Uses same method of random graph generation\n", | |
" G = nx.erdos_renyi_graph(Nodes, ProbabilityCnct, directed=True)\n", | |
" \n", | |
" #Variable declarations\n", | |
" count = 0\n", | |
" Length = []\n", | |
" Cycle_Size = 0\n", | |
" All_Cycles = (list(nx.simple_cycles(G)))\n", | |
" \n", | |
" # finds longest cycle in the graph\n", | |
" while count < len(All_Cycles):\n", | |
" if len(All_Cycles[count]) > Cycle_Size:\n", | |
" Length = All_Cycles[count]\n", | |
" Cycle_Size = len(Length)\n", | |
" count = count + 1\n", | |
"\n", | |
" # checks found cycle contains all nodes once\n", | |
" if sorted(G.nodes()) == sorted(Length):\n", | |
" # checks last edge in cycle connects to first\n", | |
" if G.has_edge(Length[len(Length)-1],Length[0]):\n", | |
" Hamiltonian = True\n", | |
" \n", | |
" return(G)\n", | |
"#Plotting the Hamiltonian Graph\n", | |
"if __name__ == \"__main__\":\n", | |
" Hamiltonian_Graph = Hamiltonian_Generator(10, 0.5)\n", | |
" nx.draw_networkx(Hamiltonian_Graph, node_color=\"orange\", edge_color=\"k\")" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"The above code was implemented to ensure that the graph being implemented was a Hamiltonian. As initially it was intended to write code for the algorithms and in testing methodologies all graphs given to the algorithms, although random, had to be Hamiltonians for testing and comparison on their ability and performance. <br>\n", | |
"\\pagebreak" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Solution Methods" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Exhaustive Search (Exact Method)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"The Exhaustive search is a definitive exact method to decide the DHCP problem. It is an algorithm that in collaboration with the Depth First Search (DFS) traverses through a graph's nodes and its resulting edges to make sure that the criteria for a graph to be a DHC is met. It, logically returns TRUE if the conditions are met. Else returns FALSE <br>\n", | |
"\n", | |
"<br>\n", | |
"\n", | |
"### Pseudocode:\n", | |
"\n", | |
"#### Exhaustive Pseudocode Explanation:\n", | |
"The proposed exhaustive search pseudocode can be broken into 3 components:<br>\n", | |
"* Recursive DFS function to traverse through everynode<br>\n", | |
"\n", | |
"#### Exhaustive Pseudocode Implementation:\n", | |
"1. 2DimensionalList =[[]]\n", | |
"2. **FUNCTION** RecursiveDFS (EDGE)<br>\n", | |
"3. CurrentNode = Traverse EDGE<br>\n", | |
"4. EdgesOut = CurrentNode.edges()<br>\n", | |
"5. **FOR** every edge in EdgesOUT<br>\n", | |
"6. $\\quad$**IF** edge **NOT** Visited<br>\n", | |
"7. $\\qquad$RecursiveDFS(edge)<br>\n", | |
"<br>\n", | |
"8. **FOR** Nodes **IN** Graph<br>\n", | |
"9. $\\quad$ 2DimensionalList.Append(RecursiveDFS(Nodes))<br>\n", | |
"<br>\n", | |
"10. **FUNCTION** Verifier()<br>\n", | |
"11. **FOR** EVERY Edge in 2DimensionalList<br>\n", | |
"12. $\\quad$TraverseEdge<br>\n", | |
"13. $\\qquad$IF Node NOT IN EdgesOut<br>\n", | |
"14. $\\qquad$Break<br>\n", | |
"15. $\\quad$**RETURN** TRUE<br>\n", | |
"\n", | |
"\n", | |
"### Big O Notation: \n", | |
"__O(|N| + |E|)__ <br>\n", | |
"\n", | |
"The Exhaustive search makes use of a depth first search, which has a Big O notation of __O(|N| + |E|)__ (O(number of nodes+number of edges) so ultimately, linear)but since there is a loop within a recursive algorithm and that is the most complex and worst Big O notation holder it dictates the algorithms Big O Notation, hence the whole algorithm takes the complexity __O(n^2)__\n", | |
"\n", | |
"__O(n!)__\n", | |
"Generally, exhaustive is argued to have time complexity of O(n!), since every edge is iterated over which has a notation of O(n) for each state on the path (n*(n-1)!), ultimately giving it a Big O notation of O(n!) which is the worst case scenario.\n", | |
"\n", | |
"But given that in our Exhaustive search for DHCP problem there are defined clauses that exit or break the loop if a given condition is not met hence not all nodes in the graph are traversed to, making our time complexity a little simpler and better as opposed to the general exhaustive search for a different problem.\n", | |
"\n", | |
"***" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Greedy Heuristic" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Unlike the definitive solution and exact method \"Exhaustive Search\", the greedy method nd most heuristics are created to add randomness to the problem solution. In the real world, a traveling salesman isn’t going to be \n", | |
"\n", | |
"Given our random graph generation itself was a solution of the DHCP problem the generation of graphs would take fairly long time as it is.\n", | |
"\n", | |
"### Random Graph Pseudocode Explanation:\n", | |
"I present the proposed system of greedy heuristic that I would have implemented.\n", | |
"\n", | |
"The random graph generation method would work following the steps:\n", | |
"\n", | |
"- Random Graph Generation\n", | |
"- Addition of non-existent edges (with expensive weights(cost)) between nodes. \n", | |
"\n", | |
"So, given a randomly generated graph, make sure that every node is connected to every other node of the graph. Those nodes that aren’t connected are connected by placing an expensive edge between them.\n", | |
"\n", | |
"\n", | |
"### Pseudocode:<br>\n", | |
"\n", | |
"### Greedy Pseudocode Explanation:\n", | |
"\n", | |
"* Pick a random node and assign it as start node\n", | |
"* Make start node the current node\n", | |
"* Determine all the edges leaving from current node and their weights (Do this step for every time a node is traversed to)\n", | |
"* Traverse to node with cheapest path\n", | |
"* If only paths available are expensive, then there is no choice, traverse an expensive path or only possible edge\n", | |
"* If 2 paths are equally weighted, then give preference to node that hasn’t been visited before\n", | |
"* Do until NextNode == StartNode\n", | |
"* else return that Graph isn’t a Hamiltonian\n", | |
"\n", | |
"\n", | |
"#### Greedy Heuristic Implementation: <br>\n", | |
"\n", | |
"1. StartNode = Random(G.Nodes)<br>\n", | |
"2. NextNode = StartNode<br>\n", | |
"3. Cycle = []<br>\n", | |
"4. Visited = []<br>\n", | |
"<br>\n", | |
"5. **FUNCTION** GreedyTraversal(G)<br>\n", | |
"6. **FOR** i < LENGTH(G.nodes)<br>\n", | |
"7. Sorted = EMPTY<br>\n", | |
"8. CurrentNode = NextNode<br>\n", | |
"9. NodeEges = CurrentNode[Node:Edges]<br>\n", | |
"10. Sorted = NodeEdges.sort(ascending)<br>\n", | |
"11. NextNode = Sorted[0][Node]<br>\n", | |
"12. $\\quad$ **IF** NextNode == StartNode<br>\n", | |
"13. $\\qquad$ **RETURN** Cycle , TRUE<br>\n", | |
"14. $\\quad$**FOR** i in RANGE (LENGTH(Sorted))<br>\n", | |
"15. $\\qquad$ **IF** NextNode **IN** Visited<br>\n", | |
"16. $\\qquad$ NextNode = Sorted[i][Node]<br>\n", | |
"17. $\\qquad$ **ELSE**<br>\n", | |
"18. $\\qquad$ Hamiltonian = **FALSE**<br>\n", | |
"19. $\\quad$**RETURN** Cycle , **FALSE**<br>\n", | |
"\n", | |
"\n", | |
"#### Big O Notation: <br>\n", | |
"__O(n^2)__\n", | |
"Due to the presence of a nested FOR loop in the otherwise linear greedy algorithm, the worst complexity dictates the algorithms complexity of O(n^2).\n", | |
"\n", | |
"This means that as the number of nodes in the graph increases, the performance reduces in direct proportion to the square on the number of nodes. (Abu Naser, 1999)\n", | |
"\n", | |
"***" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Meta Heuristic" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Genetic Algorithm Explanation: <br>\n", | |
"Genetic algorithm (GA) (Genetic algorithms in search, optimization, and machine learning, 1989) is a search technique that takes inspiration from natural selection and genetics. It updates a population of solutions to acquire a global optimum. The new solutions generated by the GA, also referred to as 'offspring', from the parental solutions by applying the crossover and mutation operation. Said operations should be applied in such a way that offspring inherit important factors of parents. (Iima and Yakawa, n.d.)\n", | |
"\n", | |
"### Pseudocode:\n", | |
"\n", | |
"#### Genetic Algorithm Pseudocode Explanation: <br>\n", | |
"\n", | |
"1.\tCreate the first population, and set g←1. (g = generation).\n", | |
"2.\tChoose 2 solutions say S1 and S2 randomly from the population created in step 1 with as 'parents'.\n", | |
"3.\tCreate two further solutions S3 and S4 using an external algorithm (Maybe greedy as implemented above OR crossover Operation). (for every generation)\n", | |
"4.\tDerive a solution S5 from S1 using another external operation (mutation - to match 'genetic' nature). Do the same to generate solution S6 from S2. (for every generation)\n", | |
"5.\tFrom the set of generated populations: {S1, S2,⋯,S6} select 2 best possible solutions. Remove S1 and S2 (parents) from the population, and the 2 best possible solutions as parents for the next generation.\n", | |
"6.\tTERMINATION - Given If g=G, end the algorithm. (Where G =final generation; and it value is initially defined). \n", | |
"7.\tGiven that g ≠ G, increment g (g←g+1) and continue from step 2\n", | |
"\n", | |
"##### Mutation operation and Crossover Operation:\n", | |
"Taken as external operations to the genetic algorithm, these two functions are responsible to deliver solutions based on natural instincts. Like in nature, mutation operations to mutate genes and in the case of crossover operation making sure that the best factors of the parents are inherited in the resulting solution. (Joel Zwickl, 2006)\n", | |
"\n", | |
"#### Genetic Algorithm Implementation: <br>\n", | |
"\n", | |
"1. BestSolution = [] <br>\n", | |
"2. Population ={}\n", | |
"3. Parent1 = RandomSolution(population)\n", | |
"4. Parent2 = RandomSolution(population)\n", | |
"5. **WHILE** Termination = **FALSE DO** <br>\n", | |
"6. $\\quad$ S3 , S4 = CrossoverOp() <br>\n", | |
"7. $\\quad$ S5 = MutationOperation(Parent1) <br>\n", | |
"8. $\\quad$ S6 = MutationOperation(Parent2) <br>\n", | |
"9. $\\quad$ population.ADD(Parent1,Parent2,S3,S4,S5,S6) <br>\n", | |
"10. $\\quad$ Parent1 = population.BestSolution <br>\n", | |
"11. $\\quad$ Parent2 = population.BestSolution <br>\n", | |
"12. **END WHILE** <br>\n", | |
"13. **RETURN** BestSolution <br>\n", | |
"\n", | |
"#### Big O Notation: <br>\n", | |
"The complexity is __O(n)__ as the algorithm is Linear except for the external functions it incorporates but as population increases the time taken complexity increases insignificantly. having said that, the external functions do compromise the computation of the overall algorithm. <br>\n", | |
"\n", | |
"### Pseudocode:\n", | |
"\n", | |
"#### Grasp Pseudocode Explanation: <br>\n", | |
"Defined as a multi-start algorithm, this heuristic combines two different computations to encourage randomness (Glover and Kochenberger, 2003) in compututation. Meta Heuristic techniques take inspiration from things such as nature and everyday life. Ant colony optimization (ACO) and Genetic Algorithm (GA), both such meta-heuristic examples. <br>\n", | |
"\n", | |
"- The termination condition is user specified to carry out a reasonable number of iterations (eg. 50-100)\n", | |
"- The GRASP algorithm below incorporates the previously implemented greedy algorithm within itself along with a Local Search\n", | |
"- Much like neural networks and gradient decent and loss functions, the linear search aims to produce the best possible solution by changing the edges of the graph to see if the overall performance improves.\n", | |
"\n", | |
"#### GRASP pseudocode Implementation: <br>\n", | |
"1. BestSolution = EMPTY <br>\n", | |
"2. **WHILE** Termination = **FALSE DO** <br>\n", | |
"3. $\\quad$ GreedySolution = GreedyTraversal(G) <br>\n", | |
"4. $\\quad$ GraspSolution = LocalSearch(GreedySolution) <br>\n", | |
"5. $\\quad$ **IF** GreedySolution IS BETTER THAN GraspSolution **THEN** <br>\n", | |
"6. $\\qquad$ BestSolution = GraspSolution <br>\n", | |
"7. $\\quad$ **ENDIF** <br>\n", | |
"8. **END WHILE** <br>\n", | |
"9. **RETURN** BestSolution <br>\n", | |
"\n", | |
"#### Big O Notation: <br>\n", | |
"From steps 1-2, the complexity is __O(n)__ although visibly the algorithm remains linear, it still incorporates 2 foreign functions (Greedy Traversal and Linear Search) which do compromise the computation of the overall algorithm, visible algorithm is all pretty linear, but the implication of the other functions do affect the parent algorithm. <br>\n", | |
"***\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Special Cases" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"> Let G be a connected graph with n < 2 vertices, and E edges.\n", | |
"\n", | |
"## Singleton Graph\n", | |
"Description: A graph containing just one node and no edges.\n", | |
"\n", | |
"_\"By convention, the singleton graph is Hamiltonian\"_ (Weisstein, 1995).\n", | |
"\n", | |
"* Meets all the criteria of a Directed Hamiltonian Cycle. \n", | |
"* Although there is significant debate of whether a single node graph can in fact be considered a directed graph\n", | |
"* Again, can contribute to the optimisation of determination algorithms\n", | |
"\n", | |
"## Empty Graph\n", | |
"Description: Graph contain empty nodes but no edges.\n", | |
"\n", | |
"Given that through the personal communication Mr B. McKay, _\"By convention, the singleton graph is considered to be Hamiltonian (B. McKay, pers. comm., Mar. 22, 2007\"_ (Weisstein, 1995) Hence it can be said that a empty graph, is a special case of a singleton graph where every node in the graph acts as a graph itself as re-quoted from the singleton Graph special case.\n", | |
"\n", | |
"> Let G be a connected graph with n = E = 2.\n", | |
"\n", | |
"## 2 nodes 2 edges\n", | |
"Description: For a given graph with just 2 nodes, and 2 edges connecting both nodes, is logically a Hamiltonian cycle. easily computable in polynomial time as all we need to do to verify it is to check if: **Number of nodes = number of edges = 2**\n", | |
"\n", | |
"> Let G be a connected graph with Number of nodes 'n' < Number of edges 'E'\n", | |
"\n", | |
"## Number of edges < number of nodes\n", | |
"Description: The number of nodes in a graph are less than the number of edges in the graph. This means that at least one node in the graph is disconnected.\n", | |
"\n", | |
"It is mathematically impossible for a graph to have a Hamiltonian cycle if a node(s) isn’t participating in the graph. That ultimately suggests that all nodes are not traversed hence breaking the criteria for a given graph to be a Hamiltonian Cycle graph. \n", | |
"\n", | |
"> Let G be a connected graph where Number of E = n(n-1).\n", | |
"\n", | |
"## Complete Graph (100% connected graph)\n", | |
"Description: Every node connected to every other node in the graph.\n", | |
"\n", | |
"* Given a random graph, with specified number of nodes and edge connection probability of 1 (100%) the resulting graph will always be a Hamiltonian Cycle graph.\n", | |
"* This can be mathematically checked if the number of edges are = n(n-1). Where n = number of nodes.\n", | |
"* This proves that a graph is 100% connected and this linear one like code can check if a given graph is a complete graph.\n", | |
"* This can help optimise code as well as if a DHCP determining algorithm is given a complete graph, rather than traversing through every node, it would check if it completely connected and not proceed into traversal.\n", | |
"\n", | |
"\n", | |
"## Traveling Salesman Problem\n", | |
"Since DHCP and TSP are rather similar, it was considered that the special cases of TSP might translate into special cases for DHCP as well. But the special cases for TSP were much to customised. (Tsitsiklis, 1992)\n", | |
"\n", | |
"However, I later felt that TSP itself is an application of DHCP and so, although it isn’t a special case, I wanted it to be on here as a special mention.\n", | |
"\n", | |
"\n", | |
"***\n", | |
"\\pagebreak" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Conclusion\n", | |
"\n", | |
"## Restating principle findings:\n", | |
"\n", | |
"The resulting Big O Notations for the written pseudocode: Exhaustive, Greedy and Meta Heuristic are as follows: O(n^2), O(n^2) and O(n) respectively.\n", | |
"\n", | |
"Seeing the Big O notations of the algorithms it is evident that based on this complexity the Greedy performed just as well as the Exhaustive algorithm.\n", | |
"\n", | |
"With increasing amount of data, the time taken will increase proportionally to the square of data increased for both greedy and exhaustive, however the Meta Heuristic Graph will take almost the same time because of its linear complexity." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Visual Aid to better understand the resultant Big O \n", | |
"\n", | |
"### Code to mimic the nature of O(n) and O(n^2)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<matplotlib.legend.Legend at 0x22787bb5160>" | |
] | |
}, | |
"execution_count": 5, | |
"metadata": {}, | |
"output_type": "execute_result" | |
}, | |
{ | |
"data": { | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAD8CAYAAAB+UHOxAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAIABJREFUeJzt3Xd8VGX2+PHPSYHQQZpAgICAlAABAtIFwbYIiIIorgK64rqwsuvasLHuYi+o7H5d+VkAlaKggq6L0hQsIEGKFIUICKFGejfl/P64NzMJmYSQdieZ83698src5z5z52RgnnPnufeeK6qKMcaY0BPmdQDGGGO8YQnAGGNClCUAY4wJUZYAjDEmRFkCMMaYEGUJwBhjQpQlAGOMCVGWAIwxJkRZAjDGmBAV4XUAualRo4bGxMR4HYYxxpQoq1at+lVVa56rX1AngJiYGBISErwOwxhjShQR+SUv/WwKyBhjQpQlAGOMCVGWAIwxJkQF9TGAQFJSUkhKSuL06dNeh2JM0ImKiiI6OprIyEivQzElQIlLAElJSVSqVImYmBhExOtwjAkaqsqBAwdISkqiUaNGXodjSoASNwV0+vRpqlevboO/MWcREapXr27fjk2elbgEANjgb0wO7LNRSmx8BpLmFfnLlMgEYIwxpVbSPFjzICwdCGsfhfS0InspSwD5kJSUxMCBA2natCkXXXQRY8eO5bfffvOtX716NX/4wx8AmDJlCmFhYaxbt863PjY2lu3bt2fZ5p133kmFChVYvHhxlvYXX3yRli1b0qZNG/r06cMvvzjXdyQnJ3PVVVedd+xTpkyhZs2axMXF+X42btyYa/8xY8ac9+vk1fbt25k+fbpvOSEhgbvvvrvIXi+vvvjiC6655pqA67777jt69epF06ZNad++Pf369eOHH34okjhGjBjB7Nmzi2TbJggd3Qzf3uJfPrAcKLr7tlsCOE+qynXXXce1117Lli1b2Lx5M8ePH+fhhx/29XnyySf585//7FuOjo7miSeeyHGbEyZM4NChQ6xYsYLRo0dnSRbt2rUjISGBdevWMXjwYO6//34AatasSZ06dfj666/P+28YOnQoa9as8f20bNnyvLdRWM5OAPHx8bzyyiuexXMu+/bt44YbbuDJJ59ky5YtfP/994wbN46ff/45W9/U1FQPIjQlVspxWDYIUo46yxUaQtcZEFZ05+pYAjhPixcvJioqipEjRwIQHh7OxIkTefPNNzl58iTHjh1j3bp1tG3b1veca665hg0bNvDTTz9l297UqVNZv34906dPJzY2lnnz5nHHHXewc+dOAHr37k358uUB6Ny5M0lJSb7nXnvttbz77ruF8nd9+OGH9O3bF1Vlz549NGvWjL179wKwe/durrrqKpo2bepLQAB33XUX8fHxtGrVivHjx/vaY2Ji+PXXXwFnj75Xr14AfPnll75vHe3atePYsWM8+OCDLFu2jLi4OCZOnOjb805PTycmJobDhw/7ttukSRP27dtHcnIy119/PR07dqRjx44Bk+D27dvp0aMH7du3p3379nzzzTeAs2ffq1cvBg8eTPPmzbn55ptRdfaw5s+fT/PmzenevTsffPBBwPfpX//6F8OHD6dr166+tu7du3PttdcCzh77PffcQ+/evXnggQc4ceIEt912Gx07dqRdu3bMnTsXgLS0NO677z46duxImzZteO211wBnB2PMmDG0bNmSfv36sX//fgAWLVrEoEGDfK+5YMECrrvuunP+u5oSQhWWj4Qj7rfx8Cjo8QFE1Sjq19Vcf4A3gf3A+gDr7sX5flLDXRbgFSARWAe0z9R3OLDF/Rl+rtdVVTp06KBn27hxo3/hXYruJwcvv/yy/uUvf8nWHhcXp2vXrtXFixfrdddd52t/6623dPTo0Tp16lS99dZbVVW1VatWum3bthxfIyejR4/Wf/7zn77lpKQkjY2NPa9tvPXWW1qjRg1t27at7+fkyZOqqnrzzTfrpEmTtF+/fjp9+nRf/0aNGunhw4f11KlT2qBBA92xY4eqqh44cEBVVVNTU/XSSy/VtWvXqqpqw4YNNTk5WVVVV65cqZdeeqmqql5zzTX61VdfqarqsWPHNCUlRZcsWaL9+vXzxZd5+e6779Y333xTVVWXL1+uffr0UVXVm266SZctW6aqqr/88os2b94829954sQJPXXqlKqqbt68WTP+Ly1ZskQrV66sO3fu1LS0NO3cubMuW7ZMT506pdHR0bp582ZNT0/XIUOGZIkrw6BBg/Sjjz7K8f0dPny49uvXT1NTU1VVddy4cfr222+rquqhQ4e0adOmevz4cX3ttdd8/5anT5/WDh066NatW3XOnDnat29fTU1N1V27dmmV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\n", | |
"text/plain": [ | |
"<matplotlib.figure.Figure at 0x227865d3588>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"import matplotlib.pyplot as plt\n", | |
"\n", | |
"#Initialise lists\n", | |
"X_Coordinates = []\n", | |
"Exh_Grdy = []\n", | |
"Grsp = []\n", | |
" \n", | |
"#Generate X cordinates from 0 to 40 with increments of 2 \n", | |
"for i in range (0,40,2):\n", | |
" X_Coordinates.append(i)\n", | |
"\n", | |
"#Generate square of X_coordinates for O(n)square and minute increase for O(n)\n", | |
"for i in X_Coordinates:\n", | |
" squared = i*i\n", | |
" Exh_Grdy.append(squared)\n", | |
" Grsp.append(i*1.0002)\n", | |
"\n", | |
"plt.plot(X_Coordinates,Exh_Grdy, color='orange', linewidth=3, \n", | |
" label = 'O(N^2) - Exhaustive and Greedy')\n", | |
"plt.plot(X_Coordinates,Grsp, color='green', linewidth=3, \n", | |
" label = 'O(N) - GA & GRASP - (Meta)')\n", | |
"plt.legend(loc='best')" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"As seen in the graph above, Since: O(n) < O(n^2) <br>\n", | |
"\n", | |
"Meta Heuristic Genetic Algorithm (GA) and GRASP methods win. <br>\n", | |
"\n", | |
"The aim for having additional methodologies as opposed to an exact method is to introduce randomness in computation (Avigad, 2013). In real world situations having to go through a node twice might actually be more inexpensive than the restriction of not passing through a given node twice.\n", | |
"\n", | |
"The exhaustive search is an exact method, the rest are approximations and heuristics and biases with their own computational abilities both crucial to the field of mathematics.\n", | |
"\n", | |
"The GRASP method makes use of the greedy implementation and along with a local search produces a solution better than that of greedy. Since it is an optimaisation version, its Big O shouldnt be worse than Greedy's.\n", | |
"\n", | |
"Out of the implemented \n", | |
"Although the three algorithms differ in nature and aren’t all exact methods (except exhaustive), they can't be compared on their determination abilities as they don’t work in the same way and environment and it is an unfair comparison. But in terms of their individual computation:\n", | |
"\n", | |
"- The time taken increased directly proportionally to the square of increase of number of nodes and edge creation probability.\n", | |
"- Both in the case of exhaustive and greedy this complexity was observed was observed\n", | |
"- The DHCP problem is best solved for small values of n by both Exhaustive and Greedy algorithm (Given worse values of Big O)\n", | |
"- The Big O of the GRASP method being surprisingly O(n)\n", | |
"***\n", | |
"\n", | |
"\\pagebreak" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Reflection\n", | |
"\n", | |
"Despite the belief that an early start and organised approach gets the job done, in my case since I started too early and started to consider the problem and researching, I started to relax seeing that my course mates hadn’t even started yet. That was an extremely wrong thing to do. Instead of using the head start to my advantage, I let comparison and focus on dissertation consume me until it was very late. However, given my passion for mathematics and Computer Science I took upon the challenge of doing all that i could get done in a short space of time. <br> \n", | |
"\n", | |
"I planned, if I couldn’t get it all done, I still could get something done which was better than nothing. and assigned tasks and intended to do them all before we broke off for Easter. That was nearly impossible as the relevant lecture slides for assignment were scheduled in last few weeks before spring break. Once we stepped into Easter, Dissertation Presentations and writeups took over and from time to time we would meet to get code done for meta heuristics and greedy mostly. <br>\n", | |
"\n", | |
"Although management in terms of task assigning was initially good, time wise. But I lacked and lost when it came to time management and organisation. I kept up my demeanour’s and instead of panicking, tried to deliver as much as I could. <br>\n", | |
"\n", | |
"#### Problems faced: <br>\n", | |
"- Understanding the problem (DHCP) <br>\n", | |
"- Time management <br>\n", | |
"- Coding and understanding <br>\n", | |
"\n", | |
"#### Skills and lessons Learnt <br>\n", | |
"- Transferable Skills that are next to none in terms of learning curve. As a third-year student I hadn’t, up to this stage been introduced to Jubyter Nootebook. <br>\n", | |
"- Jupyter notebook. It is a very effective tool that collaborates code as well as writing and my introduction to it helped me incorporate it in my Dissertation. <br>\n", | |
"- Problem Solving, mathematical language and literature inculcates a deep mental understanding and breakdown of a given problem. \n", | |
"- Time management, problem facing and ability to function under pressure <br>\n", | |
"- Significance of organisation and discipline <br>\n", | |
"- Starting early <br>\n", | |
"\n", | |
"#### What would i do differently? <br>\n", | |
"- Start early <br>\n", | |
"- Plan <br>\n", | |
"- Communicate with lecturer <br>\n", | |
"- Make a start <br>\n", | |
"\n", | |
"The skills learnt from this module and specifically this assignment are going to prove unmatchable as a Computer Science in the making, in three years of bachelors I hadnt had any experience with a powerful python tool like Jupyter notebook. The Big O notation for my learning curve in this module was definitely O(n!) as time went by, my learning progressed immensely and was introduced to new horizons.\n", | |
"\n", | |
"***\n", | |
"\\pagebreak" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Refrences\n", | |
"\n", | |
"- Abu Naser, S. (1999). Big O Notation for Measuring Expert Systems complexity. [online] Available at: https://philpapers.org/rec/NASBON [Accessed 22 Apr. 2018].\n", | |
"\n", | |
"- Arora, S. and Barak, B. (2016) Computational Complexity. New York (NY): Cambridge University Press\n", | |
"\n", | |
"- Avigad, J. (2013). Uniform distribution and algorithmic randomness. The Journal of Symbolic Logic, 78(01), pp.334-344.\n", | |
"\n", | |
"- Garey, M. and Johnson, D. (1982) Vychislitel'nye Mashiny I Trudnoreshaemye Zadachi. Moskva: Izd-vo \"Mir\"\n", | |
"\n", | |
"- Garey, S. and Johnson, D. (1979) Computers and Intractability: A Guide to the Theory of NP-Completeness. Freeman.\n", | |
"\n", | |
"- Genetic algorithms in search, optimization, and machine learning. (1989). Choice Reviews Online, 27(02), pp.27-0936-27-0936.\n", | |
"\n", | |
"- Glover, F. and Kochenberger, G. (2003). Handbook of metaheuristics. Boston: Kluwer, pp.219-222.\n", | |
"\n", | |
"- Hoos, H. and Stutzler, T. (2005) Stochastic Local Search: Foundations and Applications. Morgan Kaufmann.\n", | |
"\n", | |
"- Iima, H. and Yakawa, T. (n.d.). A new design of genetic algorithm for bin packing. The 2003 Congress on Evolutionary Computation, 2003. CEC '03..\n", | |
"\n", | |
"- Joel Zwickl, D. (2006). Genetic algorithm approaches for the phylogenetic analysis of large biological sequence datasets. Ph. D. The University of Texas at Austin.\n", | |
"\n", | |
"- Koutsoupias, E., & Papadimitriou, C. H. (1992). On the greedy algorithm for satisfiability. Information Processing Letters, 43(1), 53-55.\n", | |
"\n", | |
"- Plesn´ik, J. (1979) \"The Np-Completeness Of The Hamiltonian Cycle Problem In Planar Diagraphs With Degree Bound Two\". Information Processing Letters 8 (4), 199-201\n", | |
"\n", | |
"- RAO, W., JIN, C. and LU, L. (2014) \"An Improved Greedy Algorithm With Information Of Edges’ Location For Solving The Euclidean Traveling Salesman Problem\". Chinese Journal Of Computers 36 (4), 836-850\n", | |
"\n", | |
"- Thompson, G. and Singhal, S. (1985) \"A Successful Algorithm For The Undirected Hamiltonian Path Problem\". Discrete Applied Mathematics 10 (2), 179-195\n", | |
"\n", | |
"- Tsitsiklis, J. (1992). Special Cases of Traveling Salesman and Repairman Problems. Post Graduate. Massachusetts Institute of Technology Cambridge.\n", | |
"\n", | |
"- Weisstein, Eric W. (1995) \"Hamiltonian Cycle.\" From MathWorld--A Wolfram Web Resource: http://mathworld.wolfram.com/HamiltonianCycle.html\n", | |
"\n", | |
"- Rudoy, M. (2017). Hamiltonian Cycle and Related Problems: Vertex-Breaking, Grid Graphs, and Rubik’s Cubes. Post Graduate. MASSACHUSETTS INSTITUTE OF TECHNOLOGY.\n" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.6.4" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |