00 mi piace00 non mi piace

10 visualizzazioni5 pagineThis is the homework of algorithms

Sep 08, 2015

© © All Rights Reserved

PDF, TXT o leggi online da Scribd

This is the homework of algorithms

© All Rights Reserved

10 visualizzazioni

00 mi piace00 non mi piace

This is the homework of algorithms

© All Rights Reserved

Sei sulla pagina 1di 5

HW1

1: Modify depth-first search so that it assigns to each vertex v V an integer label cc(v), such that

cc(u) = cc(v) if u and v are in same connected component. The running time of your algorithm should

be O(V + E).

(a) Algorithm:

General Idea: Add a label to mark the vertex when using DFS.

Pseudo code:

DFS(G)

for each vertex u V [G]

do u.color WHITE

//Initialize all vertex to white to label their status as undiscovered

u. NIL

//Initialize all vertexs parent to NIL

time 0

//Initialize time to zero

label 0

//Initialize label to zero

for each vertex u V [G]

do if u.color = W HIT E

then label label + 1

//Set vertexs label as a marker of a connected component

DFS-SEARCH(u, label)

//Start to search

DFS-SEARCH(u, label)

u.color GRAY

//Set vertex as gray when they firstly discovered

u.cc label

//Set vertexs label

time time + 1

//Increase time 1 unit

u.d time

//Set vertexs discover time

for each v Adj[u]

//Start to search every vertex which is adjacent to u

do if v.color = W HIT E

then v. u

//If vertex is white(undiscovered), set its parent as u

DFS-SEARCH(v, label)

Recursively search every vertex

u.color BLACK

//Set u as black when every adjacent vertex is done

time time + 1

//Increase time-line

u.f time

//Set us finish time

Correctness:

When DFS-SEARCH is called to generate a new tree in the DFS forest, label is increased by 1, which

means every vertex visited by DFS-SEARCH inside the same tree will be labeled with same label value.

Thus u.cc = v.cc if and only if u and v are searched in the same DFS-SEACH call coming from DFS.

Then we need to prove that the vertices touched by the DFS-SEARCH call from DFS are the vertices in

one connected component of G.

In the pseudo-code, we consider u as the first vertex searched by DFS-SEARCH in a component. Since all

vertices were marked as WHITE initially, we can say all vertices are descendants of u by white-path

theorem, which means these vertices will be visited before DFS-SEARCH return to DFS. That gives us a

fact that if two vertices are touched in the same call in DFS-SEARCH from DFS, they are in the same

connected component since they will be touched only by paths found in adjacent lists.

And, every vertex will be labeled, since we know ultimately every vertex in the G will be searched by DFS.

1

Yi Zhai (447759337)

HW1

Running time:

From the pseudo-code, a vertex will be visited only if its color is white. After we visit the vertex, it will be

marked to non-white color which means it will never be visited again. That gives us a fact that all vertices

will be visited only once. Thus, we can say O(V ) time on vertices.

Again from pseudo-code, when we start to search one vertex, say u, by its adjacent lists, we only deep into

the search if the adjacent element, say v, is not visited. This make sure we visit every edge only once.

Thus, gives us O(E).

Then in total, the running time is O(V + E).

2: A pair of wrestlers may or may not be a rivalry. Suppose we have n wrestlers and r pairs are

rivalries. Given an O(n + r) algorithm that determines whether it is possible to produce a

designation such that each rivalry is formed by two kinds of wrestlers.

(a) Algorithm:

General Idea: We generate a graph with n vertices. Each vertex present a wrestler and an edge present the

relationship between two wrestlers. We examine the graph by BFS and then check the edges to determine

the relationship.

Pseudo-code:

BFS-RIVALRY-SEARCH(G)

generate graph using adjacent lists

//Generate a graph with n vertices and r edges

for each u V {s}

u.d

//Set the distance of all vertices except s to infinity

s.d 0

//Set the the distance of start point as 0

Q

//Initialize an empty list

EN-QUEUE(Q, s)

//Put start point s into Q

While Q 6=

u DE-QUEUE(Q)

//Take the first element out of Q

for each v Adj[u]

do if v.d =

then v.d v.d + 1

//Add one unit of distance

EN-QUEUE(Q, v)

//Add adjacent vertex to the queue

for each v V

do if v.d is even

v = good guys

//If distance of a vertex is even, designate it as good guy

else

v = bad guys

// if distance of a vertex is odd, designate it as bad guy

for each (u, v) E

do if (u, v) is between an odd vertex and an even vertex.

Designation produced

else Designation not produced

Correctness:

Firstly, we make sure every vertex is visited by our algorithm. Then we designate every vertex with an even

distance as a good guy and those with odd distance as a bad guy. By checking the edges after the search the

Yi Zhai (447759337)

HW1

whole graph, we can come up with the idea that the graph meet our requirement.

Running time:

The BST search will cost O(V + E) time, which is O(n + r). And the designation session will cost us

O(n) since we need to traverse every vertex. Finally the check session will cost us O(r) since we also need

to check every edge. Thus, the running time is O(n + r) overall.

3: Prove G has an Euler tour if and only if in-degree(v) = out-degree(u) for each v V . And design

an algorithm to find out the Euler tour if one exists.

(a) Proof:

Suppose for all vertices v, in-degree(v) = out-degree(v), we can traverse G from a vertex, say u, and

assemble a cycle that contains u.

We start from a source vertex, say u. By the assumption, it implies that after we take an edge((u, v) that is

a in-degree edge of v(out-degree edge of u), there must be an out-degree edge of v we have not used. Pick

that edge and continue to traverse. Each time we pick an edge of v, we take it out from our unvisited list.

By doing this continuously on all other vertices that can be reached other than u, we will finally get back to

u since, for every vertex except u, there must be a out-degree edge. The last unvisited out-degree edge of

the last visiting vertex has no other vertex to go, except u. Then G leaves us an updated graph that only u

may has unvisited out-degree edges since we start from only one of us out-degree edges.

By this point, if theres still out-degree edges of u, we continue the cycle. If we successfully visited every

edge of G, we are done. If not, since G is connected, there must be unvisited out-degree edges of a vertex,

say v, on the cycle. we start a new cycle starting from v. The cycle will only take unvisited edges and we

can finally splice this cycle into previous cycle.

That means, we firstly get a cycle, namely {u, ......, v, a, ......u} and a new cycle, namely

{v, ......, b, ......v}, then we can splice them into a cycle {u, v, ......., b, ......v, a, ......, u}. We keep doing

this continuously and splicing new cycles until we visit every edge.

(b) Algorithm:

General Idea:We need to keep track of the out-degree edges of the vertex, which means we should delete

it from our unvisited list after we search it, this makes sure all edges are visited only once. And we also

need a list to store the cycles generated by the search process, namely SEARCH-R. Meanwhile, another list

is needed to store the spliced cycles, which is the final result, namely R. Additionally, In order to merge

disjoint cycles in a constant time so that our running time wouldnt exceed O(E), we need to know where

to put the newly found cycle before we merge it into our final result R. That requires us to store the

vertices positions in R so that we dont need to go through the R to find the mutual point of the two cycles.

Pseudo-code:

EULER-SPLICE(v)

R

for any vertex u V

if u

/R

R SEARCH-CYCLE(u)

else

Yi Zhai (447759337)

HW1

//Insert the newly found cycle into R so that it forms a big cycle

Return R

SEARCH-CYCLE(u)

SEARCH-R

//Setup an empty set to store the vertices that form a cycle.

While out-degree(u) >0

do let x be the first vertex in Adj[u]

remove x from Adj[u], decrease out-degree[u]

add x to the end of SEARCH-R

//Remove vertex and the out-degree edge from unvisited list

record position information of x

//Record the vertexs location

if out-degree(u) >0

ux

Return SEARCH-R

//Return of ordered list of vertices that form a cycle

Running Time: In SEARCH-CYCLE algorithm, since we decrease out-degree of a vertex after a iteration

and remove this vertex for further search when it has no out-degree edges, we make sure every edge is

visited only once. Thus, we make sure the running time of SEARCH-CYCLE algorithm is O(|E|).

For the SPLICE part, since we recorded the location information of the vertices in R, that ensures that we

know exactly where to merge the cycle into R. That implies it only take us constant time for merge action.

So, the algorithm running tims is O(|E|) overall.

4: Design an algorithm to find the widest paths from s to every node v in G

General Idea:We adapt Dijktsras algorithm.

Pseudo-code:

for each v V

v.width

//Initialize all vertices width to negative infinity

v. NIL

s.width =

//Initialize starting points width as infinity

QV

While Q 6=

do u EXTRACT-LARGEST-WIDTH(Q)

Take out the vertex that has the largest width

for each v Adj[u]

if v.width <max(v.width, min(u.width, weight(u, v)))

//Compare the width between v and minimum value of (width of u and the weight of (u, v))

v.width max(v.width, min(u.width, weight(u, v)))

v. = u

update Q

Reorder Q in decrease order

Correctness:

We can prove our algorithm by induction.

Statement:From the pseudo code, we can see that we are actually perform our actions on two vertices.

One is the vertex which the widest path has been found. The other one is not found.

Claim:In our algorithm, any vertices, if they are playing u role in our pseudo code, have been found the

correct widest path.

4

Yi Zhai (447759337)

HW1

Base Case:If we only have a starting point, say s and its width has been set as infinity at the very

beginning, in our graph. Infinity definitely is the maximum. Thus, our claim holds.

Induction:Assume we now have a vertex, say a, is de-queued from Q since it has the largest width.

According to general idea, a.width must > other paths, which lead to a, width.

Apparently, other paths need to go through some vertices that has not been designated its largest width and

for these vertices, say b, b.width 6 a.width.

That gives us a fact that all other paths to a is constrained by b, which mean it will never greater than

a.width.

Thus, our Algorithm holds.

Running time:

If we built our Q as a binary heap, which means vertices and corresponding heap elements maintain

handles. So each EXTRACT-LARGEST-WIDTH action will take O(lgV ). We totally have V vertices, that

makes us V lgV .

For the f or loop part, we know we need to examine every edges in G and each edge is checked only once.

That means we totally have E iterations in f or loop. Inside each iteration, we need to reorder the Q again.

It takes, again, O(lgV ) to do that. So it takes O(ElgV ) time to finish the f or loop.

Thus, we combine two parts together, it will take O(V lgV + ElgV ) = O((V + E)lgV ) time overall.

## Molto più che documenti.

Scopri tutto ciò che Scribd ha da offrire, inclusi libri e audiolibri dei maggiori editori.

Annulla in qualsiasi momento.