Graphs

अब Quizwiz के साथ अपने होमवर्क और परीक्षाओं को एस करें!

Kuratowski's Theorem

a graph is planar iff does not contain a copy/subdivisions of K5(like pentagon with star inside) or K3, 3 (bipartite, every node goes to 3 other nodes, like hour glass thingie)

kruskal's algorithm

at each step, add edge (that doesn't form a cycle) with minimum weight, uses min defn of spanning tree (REGARDLESS IF NODES WERE ALREADY TOUCHED, also no starting node for Kruskal's, unlike Prim's)

using prim JPD to create a maze

choose beginning node randomly (in grid, 2D array of Nodes for the maze) frontier set F: nodes that are adjacent to nodes in spanning tree (adjacent to white nodes) **ArrayList with O(1) removal cuz in random order, copy last element into place u just removed from and delete last element **use enum to keep track of N, S, W, frontier, etc. 1. choose random frontier node 2. make it white, remove from F 3. put letter to indicate edge of white node to which it is adjacent (like a backpointer pointing to node's parent) 4. remove black line between two nodes 5. add adj nodes to frontier

optimized iterative BFS space/time efficiency

same as optimized iterative DFS! space: O(V) time: adj list is O(V+E), adj matrix is O(V^2)

source and sink of directed edge

source = where edge starts sink = where edge ends

adjacency list for sparse graphs space/enumerate all edges/is there an edge

space: O(n) enumerate all edges: O(n) is there an edge (u,v)? O(outdegree of node u) because you could have array list(with each element being linked list)!

adjacency list for dense graphs space/enumerate all edges/is there an edge

space: O(n^2) enumerate all edges: O(n^2) is there an edge (u,v)? O(outdegree of node u) because you could have array list(with each element being linked list)!

a maze is a

spanning tree of a graph, with one vertex being entrance, another being end

whether to choose adjacency list or matrix?

sparse (few edges) vs dense (max # edges = |V|^2) if graph is dense: AM if graph is sparse: AL (takes less space)

Amortized time

spreading cost over many items as in arraylist, when its backing array is full we make new backing array (double the size) and move that element, but it is amortized...O(n)/n = O(1) **also think fizzy water example! Think of arraylist as adding AND moving each element (O(1) operations) instead of adding all and THEN moving all (which may appear O(n))

JPD invariant

invariant: G1 = Cw together with a bunch of 1-node trees, and Cw is a tree

complete undirected graph of n nodes has how many edges

n(n-1) /2 (because u can change complete directed graph into undirected by removing 1 edge per pair)

coloring of an undirected graph

assignment of color to each node such that no two adjacent nodes have the same color

indegree of a vertex u in directed graph

# of edges for which u is the sink

outdegree of a vertex u in directed graph

# of edges for which u is the source

degree of a vertex u in undirected graph

#of edges for which u is an endpoint

dfs1 algorithm (no precondition that u is not visited)

/** Visit every node reachable along a path of unvisited nodes from node u. */ public static void dfs1(Node u) { if (u is visited) return; Visit u; for neighbor w of u: if (w is not visited) dfs1(w);**or could just write dfs1(w)}

dfs precondition (IMPORTANT DIFF when precondition is or isn't there!)

/** Visit every node reachable along a path of unvisited nodes from node u. Precondition: u is not visited. */ public static void dfs(Node u)

one step of JPD algorithm pseudocode

1. choose random node v in F and a random edge (v, u) with u in the spanning tree already (look for neighbors of v that are already in spanning tree! random one of these is u) 2. add v to the spanning tree and fix F to satisfy its invariant 3. edge (v, u) is now part of the spanning tree, add neighbors of v that aren't u or in F already 4. return the new node that was added to the spanning tree

DAG: directed acyclic graph

A graph which is directed and contains no cycles

adjacency list vs adjacency matrix space complexity

AL: O(|V| + |E|) AM: O(|V|^2)

adjacency list vs adjacency matrix visiting all edges efficiency

AL: O(|V| + |E|) AM: O(|V|^2) **adjacency matrix is expected time O(|V|) time for iterating over all edges of a given node, whereas adjacency list is O(|V|) worst case in that situation, expected time is O(outdegree of node n)

adjacency list vs adjacency matrix time to determine whether one edge exists efficiency(assuming adjacent list is nested linked list!)

AL: O(|V| + |E|) look at all vertices, then all edges Tighter: O(|V| + outdegree of v1) AM: O(1) it's an array, so if you're looking for (v1, v2), index to that place

application of graph coloring

Consider the graph in which the nodes are tasks to be performed. There is an edge between two nodes/tasks if they require the same shared resource, so they cannot be executed simultaneously. Produce a graph coloring. Then, two nodes/tasks have the same color if they can be carried out simultaneously. Think of the colors as time slots in which to schedule the tasks. Hence, the minimum number of colors needed to color the graph is the minimum number of time slots needed to carry out all tasks.

On a connected unweighted graph, Breadth First Search is guaranteed to find the shortest path to any given node from a defined start node.

True (not true for DFS)

iterative DFS

DFS with a loop

graph as a tree conditions

Each pair of nodes is connected by a unique simple path. 2. G is connected and e = n-1. 3. G is acyclic and e = n-1. 4. G is connected and acyclic. 5. G is connected and removing any edge makes it unconnected. (Must have min # edges n-1) 6. G is acyclic and adding any edge results in a cycle (this means graph must be connected)

Directed graph (aka digraph)

Edges are pairs (u, v), so order matters (ARROWS)...A pair (V, E) where V is set of vertices and E = set of edges (each edge is an ordered pair (u, v))

Graph

Generalized tree: vertices connected by edges Examples: subway maps, submarine cables(vertices: stations, edges: cables)

minimal size nonplanar graph

K5 or K3, 3

DFS alternative stack structure

Our alternative data structure is a stack t. The method starts by visiting u and then pushing on the stack an object that contains (a pointer to) b, which contains the neighbors of u, and the number 0. This denotes ArrayList elements b[0..]...so this is more efficient than pushing EVERY neighbor onto the stack

topological sort complexity

O(V+E)

connected graph

PATHHHHHHHHHHHHHHH NOT edge between any pair of nodes (otherwise it's disconnected); it's pretty obvious if something is connected, nothing is floating off by itself A one-node graph is connected n-node connected undirected graph has at least n-1 edges

DFS pseudocode

Precondition: u is unvisited void dfs(Node u) { mark u visited; for each neighbor w of u: if w is unmarked: dfs(w); } boolean []visited to keep track of what's been visited

iterative dfs ordering

The recursive dfs visits the neighbors from left to right: first w0 (and all nodes reachable along unvisited paths from it), then w1, and then w2. The iterative version pushes the neighbors onto stack s in the order w0, w1, w2. This means that w2 will processed —and visited if necessary— first, and it's easy to see that the neighbors are thus visited in reverse order. To get the same order, in the iterative version, push the neighbors onto s in reverse order.

OO implementation of graph

There would typically be classes Graph, Node, and Edge. Class Graph would have methods to retrieve (1) the Nodes as a Set or List and (2) the Edges as a Set or List. Class Node would have methods to retrieve (1) the Edges leaving the Node and (2) the Nodes at the other end of Edges leaving the Node. You can figure out what methods class Edge could have. public interface Graph<VL, EL> where edge labels are type EL and vertex labels are type VL Adjacency List representation: maintains LInkedList<Vertex> vertices Also class Vertex with VL label and LinkedList<Edge> outgoing... class Edge with EL label and VL to addEdge from v1 to v2...check if edge exists, if not, add v2 to vertex v1's outgoing return edgeLabel from v1 to v2...check if edge exists, then return EL from that Edge

DFS space efficiency

V nodes and E edges Mark each node: O(V) Call frame for each recursive call: O(V) (this is worst case, if graph degenerates to linked list) So worst case is O(V)

DFS time efficiency

V nodes and E edges Mark each node: O(V) recursive call on each unvisited node: O(V) *worst case if graph has degenerated to linked list Find each edge in adjacency list is O(E)(for each loop runs O(E) times total): so worst case is O(2V+E) ---> O(V + E) Adjacency matrix: find each edge = O(V^2) so worst case is O(V + V + V^2) --->O(V^2)!

Undirected graph

a pair (V, E) where V is a set (element of V = vertex/node) E is a set (element of E is edge/arc, an edge is usually itself a 2-element set of pairs, each pair is {u, v}, which is subset of V) Often require u not equal v (i.e. no self-loops) but can't assume this is the case Can traverse between two nodes in either direction

Path

a sequence of vertices (where if directed (set of vertices) in E, undirected: {set of vertices} in E) length of path = number of edges Path: A, C, D

forest

a set of trees in which no two trees have a node in common. We say that the forest is the disjoint union of the trees. equivalently, a forest is an undirected acyclic graph. The number of trees in the graph is the number of connected components in the graph.

spanning tree of connected undirected graph

a subgraph of the graph that is a tree **has SAME set of vertices V, maximal set of edges that contains no cycle **(V, E') where E' subset of E **another definition of spanning tree: SAME set of vertices and minimial set of edges that connect all vertices

Prim's (JPD) algorithm

add edge (that doesn't form cycle) with min weight, but keep added edge connected to previously selected nodes(ADD EDGE WITH EXACTLY ONE endpt in existing spanning tree!)! **if edge weights are all diff, Prim and Kruskal result in same min spanning tree

DFS for sparse graph should be implemented with

adjacency list not matrix

simple path

all nodes are different

undirected tree

an undirected graph is a tree if there is exactly one simple path between any pair of vertices...root doesn't matter trees are connected, no cycles, |E| = |V| - 1 **if graph is connected, no cycles is a tree...ANY TWO OF THESE PROPERTIES implies the third

array for adjacency list

array where each element contains a linked list of adjacent vertex labels (requires labels are integers so you can index! limited # of vertices unless you use arrayList?)

complete graph

as many edges as possible

how to tell if graph is DAG

find nodes with indegree zero and keep deleting them, if graph disappears it is a DAG (bc deleting nodes with indegree zero doesn't affect cycles) this is the essential topological sort algorithm! **If the indegree of each node in a directed graph is positive >0, the graph contains a cycle

acyclic graph

does not have a cycle

undetermined specification

doesn't tell you exactly what to do nondeterministic: multiple possible outputs when running repeatedly even with same input

linked list for adjacency list

each node has vertext label and linked list of adjacent vertex labels

labels

edges and vertices can be labeled with additional data ex. nodes labeled with characters, edges with integers

four color theorem

every map-like(planar) graph is 4-colorable

BFS pseudocode

expand from where you started...visit each unvisited layer of the graph (like 1 link away, 2 links, etc) recursive BFS is awkward!!!!!!!! BFS INVARIANT IS SAME AS DFS: /** Visit every node reachable along a path of unvisited nodes from node u. Precondition: u has not been visited. */ This precondition is very important!!!

coloring graph time complexity

find_color complexity: O(vs.length()) for each of the following steps: creating new array, for each vertex in vs, return smallest c... where vs is length of neighbor set... color complexity: O(E) cuz we're looking at all the neighbors (undirected graph)...but technically we would like at each edge twice for each direction it can be traversed(undirected), O(2E) is still O(E)

adjacency matrix

give integers labels and bounded # of vertices maintain 2D boolean array b element b[i][j] is true iff there is an edge from vertex i to vertex j row then column can have vertices are nonexistent ones in graph, this is a drawback/cost

complete directed graph has # edges

has n(n-1) edges

a graph is planar

if it can be drawn in the plane without any edges crossing

a directed graph can be topologically sorted iff

it has no cycles; must be a DAG, a directed acyclic graph!

topological sort pseudocode

k = 0; //invariant: k nodes have been given numbers in 1...k, such that if n1 <= n2, there is no edge from n2 to n1 while(there is a node of indegree 0) { let n be node of indegree zero k++ give it number k delete n and all outgoing edges } topological sort sorts DAG's(directed acyclic graphs)

Convert undirected to directed and maintain paths

leave nodes unchanged replace each undirected edge with two directed edges

path is a cycle if

length >= 1 and first/last nodes are the same...Paths (C, A, B, C) and (C, A, C, A, C) in the undirected graph are cycles. Path (F, C, A, B, C) in the undirected graph is not a cycle.

adjacency list

maintains a collection of vertices for each vertex, also maintain a collection of its adjacent vertices...can either be array of linked lists or linked lists of linked lists, etc...

greedy algorithm

makes locally optimal choice to find global optimum (Dijkstra's algorithm is greedy), doesn't always work!

optimized iterative DFS time efficiency

mark each node: O(V) push/pop each node once: O(V) find each edge(TOTAL, # of times for each loop runs): in adj list: O(E)...so total is O(V+ E) adj matrix: O(V^2)...so total is O(V^2)

optimized iterative DFS space efficiency

mark each node: O(V) stack entry for each node so you have: O(V) (better than nonoptimized, now we have discovery!) worst case: O(V)

iterative DFS space efficiency

mark per node: O(V) stack entry for each edge: O(E) (think like directed graph, u are pushing every node's neighbors onto stack, plus u can push same node onto stack multiple times) worst case: O(V + E)

bipartite graph

nodes can be partitioned into 2 sets such that no edge connects 2 nodes in the same set (application: matching problem, like matching everything in left set to right set) being bipartite is equivalent to having no cycles of odd length and being 2-colorable

endpoint

nodes of (u,v) *directed(pair) or {u, v} *undirected(set)

can you convert directed graph to undirected graph and maintain paths?

nope!

does graph coloring algorithm always use min # colors??

not necessarily, depends on order the node is processed

cycle is simple if

only repeated nodes are its first and last nodes

practice implementing this method spec with DFS: /** The walker is standing on a Node u (say) given by State s. Visit every node reachable along paths of unvisited nodes from node u. End with walker standing on Node u. Precondition: u is unvisited. */

public static void dfsWalk(State s) { Node u= s.standingOn(); Visit u; for each neighbor w of u { if (w is unvisited) { s.moveTo(w); dfsWalk(s); s.moveTo(u); } } }

DFS (depth first search)

recursively visit each unvisited neighbor (BACKTRACK WHEN NO CHILDREN/NEIGHBORS OF NODE...DO NOT START FROM TOP AGAIN) Visit smallest neighbor, max, odds first, many possibilities

finding a spanning tree: subtractive method

start with connected (likely u dir) graph while there is a cycle: pick an edge of a cycle, throw it out must delete e - (n-1) edges (remember that undir connected graph has n-1 edges at minimum) dense/complete graph: throw O(n^2) edges, this is INEFFICIENT **uses maximal set of edges with no cycle defn of spanning tree, this method is nondeterministic cuz doesn't say which edge to delte exactly

finding a spanning tree: additive method

start with no edges, while nodes are not connected: choose an edge that connects 2 unconnected components(i.e. nodes), add it (as long as it doesn't add cycle) *uses this definition of spanning tree: minimal set of edges connecting all vertices add n - 1 edges, repetend executed n-1 times, nondeterministic algorithm

min cost spanning tree

suppose edges are weighted (>0) we want minimum total cost...min total edge weights Kruskal: add edge with minimum weight, can have forest Prim(JPD): add edge with min weight but so that the added edges (and nodes at their end) form 1 tree **both these algorithms are additive/greedy

DFS starting from the root of a tree T and processing children left to right does a preorder traversal of T

true

topological order

turn directed graph into ordering of vertices (ordering without violating directions), line up vertices with all edges pointing left and right

adjacent

two vertices are adjacent if they're connected by an edge

representing maze as graph

vertices are intersections and edges are corridors

goals of graph traversal

visit each vertex reachable from some starting vertex and visit those nodes only once

optimized iterative BFS pseudocode

void bfs (Node u) { Queue q = new Queue(); mark u discovered: q.add(u); while(q is not empty): u = q.remove(); if(u not visited): {mark u visited; for each neighbor w of u: if(w is not discovered): mark w discovered; q.add(w); } } **ONLY ADD IF NOT DISCOVERED

iterative BFS pseudocode

void bfs (Node u) { Queue q = new Queue(); q.add(u); while(q is not empty): u = q.remove(); if(u not visited): [[[[[mark u visited; for each neighbor w of u: q.add(w); ]]]]] } USES QUEUES...while DFS uses stacks

how to color graph pseudocode

void color() { for each vertex v in graph: c = find color (neighbors of v) color v with c } **USED stores # times neighbors have used each color (represented as integers) int find color(vs) { //at worst need d+1 colors because color the current node AND all d neighbors diff colors in worst case int[] used = new int[vs.length() + 1] for each vertex v in vs: { //we don't care if color 75 is used, smaller colors must be available if color(v) <= vs.length(): used[color(v)] ++ } return smallest c such that used[c] == 0; }

optimized iterative DFS

void dfs (Node u) { Stack s = new Stack(); mark u discovered; s.push(u); while(s is not empty): u = s.pop(); if(u not visited): [[[[[mark u visited; for each neighbor w of u: if (w not discovered): mark w discovered; s. push(w); ]]]] } **think discovered = chilling on stack but not popped yet

iterative DFS pseudocode

void dfs (Node u) { Stack s = new Stack(); s.push(u); while(s is not empty): u = s.pop(); if(u not visited): [[[[mark u visited; for each neighbor w of u: s. push(w); ]]]] } ***pushing values in ascending order causes visit to occur in descending order

JHT topological sort pseudocode

while (the graph has a node) { Choose a node w (say) with indegree 0; Make w the next node in the ordering; Delete w and all edges leaving it from the graph } Note that if at some point the graph contains a node but no node has indegree 0, then there is a cycle

can graphs have unconnected nodes?

yep! nodes can be chilling by themselves

can directed graph be tree

yes

sparse

|E| << |V|^2 sparse if |E| is about O(n), where n = # nodes = |V| (I.e. number of edges is close to minimum of n-1 edges)

dense

|E| ~ |V|^2....number of nodes is proportional to or close to n*n (n = # nodes) (i.e. number of edges is close to maximum of n(n-1) /2 )


संबंधित स्टडी सेट्स

THE BUSINESSOWNERS POLICY -- MODULE D

View Set

HIST 224 - Midterm Quiz Material

View Set

[EXAM 1] Mastering Biology 3 - Osmoregulation

View Set

A&PII CH 18 Circulatory sytem: Blood

View Set

Dynamic questions/Fundies Book questions -BP/VS/Resp/ROS

View Set

Module 16 - Adulthood - Retrieval Practice & Review

View Set