Tuesday, February 26, 2013

Topological Sort of a Directed Acyclic Graph

Problem:

A topological sort of a directed graph is an ordering of the vertices such that for every directed edge u → v, the vertex u comes before the vertex v in the order. Given a directed graph in DIMACS format, print the integer labels of the vertices, separated with spaces,in a topologically sorted order. If the graph contains a directed cycle, topological sorting is not possible. In this case, print the word cyclic. Example. The directed graph G in Fig. 1 is acyclic. One possible topological sort is given below.
                                                         3 2 4 1 5




The DIMACS graph format:

We use the textual DIMACS file format for representing graphs. The same format is used for both directed and undirected graphs. The file begins with a line of the form
                                                        p edge n m

where n ≥ 0 is the number of vertices and m ≥ 0 is the number of edges. The vertices are labeled with integers from 1 to n. This is followed by m lines describing the edges. Each such line has the form
                                                                 e u v

where u and v are integers from 1 to n. This represents an edge joining vertices u and v. If the file represents a directed graph, the edge is directed from u to v.
Your programs should read these lines from a file whose name is given as a command line argument. You can assume that the input conforms to the format described above. It is not necessary to check syntax errors, but correct syntax must result in correct
output.



C Code:

Wednesday, February 20, 2013

An Example of Dynamic Programming: Coin Exchange

Problem:

In England the currency is made up of pound, £, and pence, p, and there are eight coins in general circulation:
1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p).
It is possible to make £2 in the following way:
1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p
How many different ways can £2 be made using any number of coins?

Solution Technique:
Dynamic Programming.


Solution Detail:
  • Lets say you have a set of N coins. Consider an array. The name of the array is coins. It holds  the values of all the coins.       
          coins[0] = 0;    means no coins or a coin which has zero value.
                    coins[1] = 3;    means the first coin has a value of 3.
                    ....
                    ...
                    .
                    coins[N] = 71;  means the Nth coin has a value of 71.
  • T is Target Value
  • VN is Value of the Nth coin. If coins[1] = 3, it means V1 = 3.
  • Let us consider another array. The name of the array is count. It is a two dimensional array. Each entry count[i][j] of this array means In how many ways you can make up j,  using the set of coins found from coins[0.....i]. Where 0 <= i <= N and 0 <= j <= T
  • So, if your target is T and you have N coins of different values then the solution is coins[N][T]
  • If T=0, then there is always one way to make up the target value with whatever coin you have. That means 
coins[0][0]=1;
coins[1][0]=1;
coins[2][0]=1;
.....
...
coins[T][0]=1;
  • And if T > 0 and you have no coins or only one kind of coin of zero value, then there is no way to make up the target value. That means
coins[0][1]=0;
coins[0][2]=0;
coins[0][3]=0;
.....
...
coins[0][T]=0;  
  • Now, how to calculate coins[i][j] where both i and j is greater than 0 ? To answer the question, divide the problem into three parts. 
           1. One set of solutions which doesn't contain the ith coin
           2. Another set of solution which contain the ith coin at least once
           3. Another(only one) solution that contains only the ith coin, nothing else
     
  • Notice that, the second set may already have the solution that is mentioned  in the third set. That means the second and third set is not disjoint. This problem has been taken care of at the below yellow marked text.
  • At First, check, in how many ways you can make up j  without using the ith element. This refer to the array entry coins[i-1][j].
  • After that check, in how many ways you can make up j-Vi using the ith coin along with the all other i-1 coins. This refer to the array entry coins[i][j-Vi]. This is because, if you can make up j-Vi then you can also make up j just by adding one more ith coin. In this set of solutions there will be at least one ith coin as you are adding it explicitly. It may be the case that j-Vi < 0. In that case consider  coins[i][j-Vi] = 0.
  • At last, If Vi divides j,it means there is one more solution to make up J. In that solution you use j/Vi number of ith coins and no coins of other values than Vi. Anyway, we do not consider this solution in our count if Vi divides j-Vi also.
  • So, from the above three points we can write:
Count[i][j] = Count[i-1][j] + Count[i][j-Vi] (if j-Vi >=0) 
+ 1 (if Vi divides j and Vi doesnt divide j-Vi)

  • If T is the final target value and you have N coins then the solution is: coins[N][T] 

Example Table:


Target Amount         ->    |0    1    2    3    4    5    6
 ----------------------------------------------------------------------------------
 V0 = coins[0] = 0       ->    |1    0    0    0    0    0    0  
 V1 = coins[1] = 1       ->    |1    1    1    1    1    1    1  
 V2 = coins[2] = 2       ->    |1    1    2    2    3    3    4  
 V3 = coins[3] = 5       ->    |1    1    2    2    3    4    5  
 V4 = coins[4] = 10     ->    |1    1    2    2    3    4    5  
 V5 = coins[5] = 20     ->    |1    1    2    2    3    4    5  
 V6 = coins[6] = 50     ->    |1    1    2    2    3    4    5  
 V7 = coins[7] = 100   ->    |1    1    2    2    3    4    5  
V8 = coins[8] = 200  ->    |1    1    2    2    3    4    5

C Code:

#include<stdio.h>


/* The Problem Starts
In England the currency is made up of pound, £, and pence, p, and there are eight coins in general circulation:
    1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p).
It is possible to make £2 in the following way:
    1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p
How many different ways can £2 be made using any number of coins?
 The problem Ends */


int main()
{

int i,j,destination;

int coins[9]={0,1,2,5,10,20,50,100,200};

printf("Please enter a destination amount:(>=0):");
scanf("%d",&destination);
  
int count[9][destination+1];

count[0][0]=1;
for(i=0;i<=8;i++)
    count[i][0]=1;
for(i=1;i<=destination;i++)
    count[0][i]=0;

int x=0;
    for(i=1;i<=8;i++)
    {
        for(j=1;j<=destination;j++)
        {
            count[i][j]=0;
            if((j-coins[i])>=0)
            {
             count[i][j] = count[i][j]+count[i][j-coins[i]]+count[i-1][j];
                  
            }
            if((j-coins[i]) < 0)
            {
                count[i][j] = count[i][j]+count[i-1][j];
            }
            if((j%coins[i])==0)
            {
                if( (j-coins[i])%coins[i]!=0)
                count[i][j]++;
            }      
        }
    }
printf("\n*********The final count is:%d\n",count[8][destination]);

      
    if(destination<=15)
    {
        printf("\nThe whole two dimensional table is:\n\n");
        for(i=0;i<=8;i++)
        {
            if(i==0)
            {
                printf("    Amt->    |");
                for(j=0;j<=destination;j++)
                printf("%d    ",j);
              
                printf("\n           ");
                for(j=0;j<=destination;j++)
                printf("_    ",j);
            printf("\n\n");
            }

        printf("coins[%d] %d    |",i,coins[i]);
            for(j=0;j<=destination;j++)
                {printf("%d    ",count[i][j]);}
        printf("\n");
        }
    }

printf("\n**NB:All calculations are done using int data type. Overflow is very easy.\n\nn");

return 0;
}