Top Banner
 <Graph Theory 10> December 11111011010 "Everything is a graph, and a graph is everything." -- Benjamin Burton, (year unknown)
23

orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

Aug 22, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

<Graph Theory 10>

December 11111011010

"Everything is a graph, and a graph is everything."

­­ Benjamin Burton, (year unknown)

Page 2: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Trees

● Connected and has N nodes, N­1 edges

● Connected and has no cycles

● If any edge is added, exactly one cycle is formed

● If any edge is removed, the graph is disconnected

● There exists one unique path between any two nodes

● Trees can be rooted or unrooted.

● Nodes have one parent and zero or more children.

● Leaves have zero children.

● Every node is a subtree

Page 3: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Funky tree problems

● Height (max­depth) of a tree:– depth[node] = depth[parent]+1

– height(node) = if no children: 0else: max(height(child) for each child )+1

● Breadth of a tree– Count how many nodes at each depth, output the highest count.

● Diameter of a tree– diameter(node) = depth[deepest child] 

  + depth[2nd deepest child]

– Pick node with largest diameter.

● Length of path between two nodes

Page 4: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Lowest Common Ancestor

Page 5: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Lowest Common Ancestor

● Store the parent of each node● Store the height of each node:

– height[node] = height[parent[node]] + 1

● We could store the grandparent of each node– gparent[node] = parent[parent[node]]

● And store their great­great­grandparents...– gggparent[node] = gparent[gparent[node]]

● etc.

Page 6: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Lowest Common Ancestor

● parent[node][i] : the 2ith ancestor of 'node'● parent[node][0] : its normal parent (20 = 1)● parent[node][1] : its grandparent (21 = 2)● parent[node][2] : its gg­grandparent (22 = 4)● parent[node][3] : 23 = 8 nodes up the tree● This is really cool because:

– parent[node][i] = parent[parent[node][i­1]][i­1]

● With 'k' sweeps of the whole tree, we can easily precompute the parent[][] table

Page 7: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Lowest Common Ancestor

● If parent[ node ] [ k ] = 0, then it doesn't have a 2k th parent (ie. its level is < 2k)

● In logarithmic time, we can now calculate the node 'm' steps up the tree for any node.

set parent[i][j] to 0 for all i,jinput parent[i][0] for all i

for (i = 1; i <= MAX_K; i++) for (j = 1; j <= n; j++) 

parent[j][i] = parent[ parent[j][i­1] ][i­1];

Page 8: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Lowest Common Ancestor

● Wait a minute Jarrah, what has this got to do with lowest common ancestor?

//get the node 'm' steps up from node 'node'// MAX_K is defined to be log

2(maximum nodes in tree)

for (k = MAX_K; k >= 0; k­­) {if (pow2(k) <= m) {

node = parent[node][k];m ­= pow2(k);

}}return node;

Page 9: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Lowest Common Ancestor

● Two nodes 'a' and 'b'. lca(a, b) = ??– 1) Get depth of a and b : O(1) after pre­comp.– 2) If depth[a] > depth[b]

  a = parent(a, depth[b]­depth[a])Likewise for b.

– 3) Now they're at the same level, yay! Their LCA must be the same distance from each. Using our epic expo­parential array, we effectively binary search for the LCA.

Page 10: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Lowest Common Ancestor

// get the lca of 'a' and 'b'// MAX_K is defined to be log

2(maximum nodes in tree)

for (k = MAX_K; k >= 0; k­­) {if (parent[a][k] != parent[b][k]) {

a = parent[a][k];b = parent[b][k];

}}assert(a == b);return a;

● In logarithmic time, you have found the lowest common ancestor.

● Yay! But how does this help us again?YOU JUST LOST THE GAME

Page 11: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Length of path in a tree

● 1) Root the tree

● 2) Pre­compute epic parents

● 3) The length of the path from a to b isdepth[a] – depth[lca(a,b)]

+  depth[b] – depth[lca(a, b)]

● If the edges were weighted, then instead of using 'depth' in the final formula, we would use 'distance', where distance[a] is the distance from 'a' to the root node. This is pre­computable in linear time – distance[node] = weight(node, parent) + distance[parent]

Page 12: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Spanning trees

● Facebook has changed their privacy settings so that you can view all default public information (name, phone, address, photos, real­time footage from cameras near your current location, etc.) for any friend­of­a­friend­of­a­friend­.......­of­a­friend. Find a (maximal) set of friendships that can be broken while still allowing everyone to view information on everyone else.

Page 13: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Spanning trees

● Any DFS will do – each node is processed only once, so if we store the edge used to reach it, we have a 'parent' for every node. We need n­1 edges to remain intact for the n nodes to stay connected.

● But what if the edges are weighted? The NBN network wants to connect every house in Australia using minimum total wiring.

Page 14: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Minimal spanning trees

● Prim's Algorithm

for (i = 0; i < n; i++) {

next = ­1;

for (j = 0; j < n; j++)if (!intree[j] && (next < 0 || dist[j] < dist[next])) 

next = j;

intree[next] = true;

for (j = 0; j < n; j++)if (!intree[j] && weight(next, j) < dist[j]) {

dist[j] = weight(next, j);parent[j] = next;

}}

Page 15: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Minimal Spanning Trees

● Kruskal's Algorithm

sort edges by weight ascending

for (i = 0; i < num_edges; i++) {

if (!path_exists(edge[i].u, edge[i].v)) {add_to_tree(edge[i]);

}}

Page 16: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

State explosion

+

Page 17: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Graphs are everywhere

● In data structures, you have lots of trees.● In DP, you have nodes (states or subproblems) 

with edges (recurrence relations). These graphs are directed and acyclic. (DAGs)

● Sometimes, even when a graph is staring at you in a problem, it may be the case that these are not the nodes you're looking for.

Page 18: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Colour Circles

● You are given a graph with nodes and edges, each node labelled a colour, and each edge labelled a colour. You have two counters, and the two nodes that they start on. You can move a counter along an edge only if the other counter is on a node of the same colour as the edge. Your goal is to get either counter into a 'target' node in the smallest number of moves.

Page 19: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Colour Circles

● 'Smallest number of moves'? That sounds like a......... shortest path problem! But then who was graph?

● By exploding the nodes of the graph to accommodate for the extra information we need (what node the other counter is on), we can create new edges between these nodes and transform the graph into one that a simple BFS will work on.

Page 20: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Colour Circles

● Vertex = pair of numbers:(node of counter A, node of counter B)

● We can travel from vertex U (p,q) to V (x,y) if:­ p = x and colour(q­>y) = colour(p), or­ q = y and colour(p­>x) = colour(q)

● Each vertex in this transformed graph corresponds to a state, each edge to a move.

● The line is blurry between 'state explosion' and 'creating an abstract graph from thin air', but the idea is what's important.

Page 21: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

What idea?

● We know we have to explode our states when  we need a bunch of information to decide our moves, rather than just a simple location.– e.g. what weapons I have in a dungeon might 

determine what monsters I can kill, hence which rooms I can enter.

● So to fix this, instead of BFSing 'dist[node]', we BFS on 'dist[node][other information]' and the combined state (node+information) is the new node in our transformed graph.

Page 22: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

Other cool tricks

● Oh noes, out of time? Ask me later about...– Multi­sourcing shortest path, e.g. given the 

locations of all the tutors + students in a graph, find the distance from every student to their closest tutor, in normal Dijkstra time complexity.

– Topsort, to find an ordering of a DAG so that every node appears before all its children.

– Hare and Tortoise: if every state has one outgoing edge, find when you hit a cycle (e.g. Relocation)

– Eulerian Paths – find a path going through every single edge once and only once

Page 23: <Graph Theory 10>orac.amt.edu.au/notes/GraphTheory2-Dec2010.pdf · Lowest Common Ancestor parent[node][i] : the 2ith ancestor of 'node' parent[node][0] : its normal parent (20

   

</Graph Theory 10>

"Except some things aren't graphs."­­ Benjamin Burton, (year known)