3

Let G be DAG with n vertices and m edges given by adjacency matrix. I need to calculate it's closure in form of a matrix as well. We have a computer that each word is b bits. and I need to find an algorithm that calculate the transitive closure in (n^2+nm/b)

I'm not really sure I understand what bits means and how can I use it

Adding the algorithm for finding transitive closure of dag:

TransitiveForDAG (Graph G)
int T[1...n,1...n] ={0,...,0}
List L <- TopologicalSort(G)
For each v in reverse(L)
   T[v,v]<-1
    For each u in Adj[v]
       for j<-1,...,n do
         T[v,j]<-T[v,j] or T[u,j]
Guy Coder
  • 24,501
  • 8
  • 71
  • 136
Anna
  • 59
  • 1
  • 2
  • 8
  • 1
    I am not sure you finished your – Ivaylo Strandjev Jan 02 '13 at 20:42
  • @izomorphius my question? well I just copied it as it is... My problem I don't understand what the bits mean?? – Anna Jan 02 '13 at 20:51
  • ok so add this to your question. It only says `I am not sure I understand what` also please indicate waht you **do** know and what exactly is not clear to you. – Ivaylo Strandjev Jan 02 '13 at 20:54
  • @izomorphius oh sorry it was cut for some reason! Ill update it – Anna Jan 02 '13 at 20:55
  • 1
    thank you. Your question is actually a good one and I don't think it would have been downvoted if you have put it like that. A +1 from me. – Ivaylo Strandjev Jan 02 '13 at 21:01
  • 2
    Does `(n^2+nm/b)` refer to time (algorithm steps) or space (memory usage)? – Ted Hopp Jan 02 '13 at 21:05
  • @TedHopp algorithm steps.. basically I we learned that a transitive closure on DAG is n^2+nm but still I cant understand what this bits mean – Anna Jan 02 '13 at 21:13
  • Can you provide a link to the normal transitive closure algorithm on DAGs? I'm not familiar with the O(n^2 + nm) algorithm off the top of my head, and it would be great to have it as a reference. – templatetypedef Jan 02 '13 at 21:50
  • @templatetypedef I didn't find any link but Ive add it to my question now ( copied from my book) – Anna Jan 02 '13 at 22:21

2 Answers2

1

You say you don't know what bits mean, so let's start with that.

  • Bit is the smallest unit of digital information - a 0 or a 1
  • Word is the unit of data processed by a computer at once. Processors don't take and process individual bits, but small chunks of them. Most today's computer architectures use words of 32 or 64 bits.

Now, how to work with words of binary data? In most programming languages, you'll use a numeric data type to store the data. To manipulate them, most languages provide bitwise operators - bitwise or (|) is one needed here.

So, how to make your algorithm faster? Look at the T matrix. It can only have values of 0 or 1 - a single bit is enough to store that information. You're processing fields of the matrix one by one; every time you process the last line of your algorithm, you only use one bit from the v'th row and one from the u'th row.

As said before, the processor has to read a whole word to read and process each of those bits. That's ineffective; mostly you wouldn't care about such a detail, but here it's in a critical place - the last line is in the innermost cycle and will be executed very many times.

Now, how to be more effective? Change the way you store the data - use a type with the length of a word as the data type for your matrix. Store b values from your original matrix in every value of the new one - this is called packing. Because of the way your algorithm works, you'll want to store them by row - the first value in the i-th row will contain first b values from the i-th row of the original matrix.

Apart from that, you only have to change the innermost cycle of the algorithm - the cycle will iterate over the words instead of individual fields and inside you'll process the whole words at once using bitwise or

T[v,j]<-T[v,j] | T[u,j]

The cycle is what generates the time complexity of the algorithm. You've now managed to iterate b-times less, so the complexity becomes (n^2+nm/b)

voidengine
  • 2,504
  • 1
  • 17
  • 29
0

For a simple graph, each entry in the adjacency matrix is either 0 or 1 and can be represented by one bit. This allows a compact representation of the matrix by packing b entries into each computer word. The challenge then is to implement matrix multiplication (to compute the closure) using the correct bit manipulation operators.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • I think the challenge is exactly how you would implement the matrix multiplication using the packed words. Since it's the *runtime* that's trying to be optimized, you would probably want to somehow use operations on individual words to do multiple operations on the bits in parallel. – templatetypedef Jan 02 '13 at 21:49
  • Ted thank you for your answer but unfortunately I still can't undertand how to use it for implementing the matrix multiplication. – Anna Jan 02 '13 at 22:23
  • @Anna, I would guess that a simple example would be regular matrix multiplication. How is this done? Arow1 * Bcolumn1 = Cr1c1, correct? (with the elements summed of course). In a DAG, the elements can only be 1 or 0. Thus, the possible outcomes can only be 1 or 0 (1 only if both elements are 1). This is equivalent to a logical AND, correct? Now, to do this operation quickly for an entire row * column, you can see that it is equivalent to a bitwise AND of the row and column in question (before the summing). Can you see how the X multiplications have been turned into 1 AND that is X bits long? – im so confused Jan 02 '13 at 22:57
  • Ted and template are trying to tell you that implementing these regular matrix operations via compact bit representation is the only challenge represented in this algorithm. – im so confused Jan 02 '13 at 22:59