Wednesday 29 July 2020

Subset Sum In Dynamic Programming

Subset Sum using Dynamic Programming

DP Tutorial 3

Prerequisite –Tutorial 1,Tutorial 2

Problem Statement-

Given a array of integer you have to tell if there is subset present in array which have the sum equal to given array.

Eg.arr[]=[2,3,7,8,10]

     Sum=11

Output -Yes

Sumset={3,8}

Parent Problem-

0-1   knapsack

how it is related to 0-1 knapsack?

I want to tell again that we try to drive solution of child problem from parent problem.In this problem we can choose a element or not and any where if this type of pattern trigger then surely that problem can be solved using 0-1 knapsack pattern.And as we forward in tutorial you can easily find.

Choice diagram of subset sum


Choice diagram of 0-1 knapsack


How to identify Dynamic Programming-

1.choice –

In this problem you can choose a element or not.Condition 1 is satisfied.

2.Optimal-

In this problem you can’t see the maximum or minimum don’t worry now assign 1 to yes and 0 to No then you want to yes mean you try to find maximum.Condition 2 is satisfied.

How to fill Table?

1.base condition

If i==0 and j==0 means you have to find sum equal to zero and you have empty array can you find ?

Yes there will be an empty subset.

If j==0 then for  i=1 to n means you have to find sum equal to zero and you have non empty array can you find  yes there will be an empty subset.

If i==0 then for j=1 to Sum means you have to find non zero sum but you have empty array can you find? No

2.Choice diagram

If you choose element for example 3 then you look for 11-3=8 if there is possible to any subset which is equal to 8

 dp[i][j]=dp[i-1][j-arr[i-1]  or dp[i-1][j]

If you does not choose

dp[i][j]=dp[i-1][j]

 

 0                          1                     2            3                4                  5       6               7      8       9         10       11

T

F

F

F

F

F

F

F

F

F

F

F

T

F

Dp[i-1][2-2]||F==T||F==T

Dp[i-1][3-2]||F==F

F

F

F

F

F

F

F

F

T

F

T

DP[i-1][3-3]||F=T

F

DP[i-1][5-3]||F=T

F

F

F

F

F

F

T

F

T

T

F

T

F

T

F

T

T

F

T

F

T

T

F

T

F

T

T

T

T

T

T

F

T

T

F

T

F

T

T

T

T

T

 

Left side from row 0 to row 5 =[2,3,7,8,10]

 

Difference in code (Bottom UP)

0-1 knapsack

Subset sum

                     if(i==0||j==0)

    dp[i][j]=0;

    else if(weight[i-1]<=j)

dp[i][j]=max(value[i-1]+dp[i-1][j-weight[i-1]],dp[i-1][j]);

    else

    dp[i][j]=dp[i-1][j];

                      if(i==0)

    dp[i][j]=true;

                      else if(j==0)

                   dp[i][j]=false;

    else if(arr[i-1]<=j)

dp[i][j]=(dp[i-1][j-arr[i-1]]||dp[i-1][j]);

    else

    dp[i][j]=dp[i-1][j];

 

Where to practice-

https://practice.geeksforgeeks.org/problems/subset-sum-problem/0

Code-

 #include <iostream>

using namespace std;


int main() {

 int t;

 cin>>t;

 while(t--)

 {

     int n;

     cin>>n;

     int arr[n],sum=0;

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

     {   cin>>arr[i];

         sum+=arr[i];

     }

     if(sum%2!=0)

    cout<<"NO\n";

     else

     {

     sum=sum/2;

   

     bool dp[n+1][sum+1];

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

        {dp[i][0] = true; 

        }

        for (int i = 1; i <= sum; i++) 

        dp[0][i] = false;

     for(int i=1;i<=n;i++)

     {

         for(int j=1;j<=sum;j++)

         {

             if(i==0)

             dp[i][j]=true;

             else if(j==0)

             dp[i][j]=false;

             else if(arr[i-1]<=j)

             dp[i][j]=(dp[i-1][j-arr[i-1]]||dp[i-1][j]);

             else

             dp[i][j]=dp[i-1][j];

         }

     }

     if(dp[n][sum]==true)

     cout<<"YES\n";

     else

     cout<<"NO\n";

     }

 }

}

Time complexity

O(n*Sum)

Space complexity

O(n*Sum)

0-1 knapsack Bottom Up Dynamic Programming

0-1    knapsack Using Bottom Up Dynamic Programming-

Dp Tutorial -2

prerequisite

https://spoj-editorial1.blogspot.com/2020/07/0-1-knapsack-in-dynamic-programming.html

problem Statement-

you are given a weight array and respective value array and maximum size of knapsack and you have to put these item in such a way so that you will get maximum total value in knapsack.

Type of solution-

Recursive=base condition+recursive call

Memorization=recursive call +table

Bottom up=table

 

Why we use Bottom Up dynamic programming?

In recursive solution there may cause a problem of stack overflow so avoid this problem we use bottom up technique.

How to solve-

In this dynamic programming tutorial we only focus to drive solution from previously tutorial.

now we have to convert

recursive +  memoization =>bottom Up

lets understand table-

eg.

Weight[]=[1,3,4,5]

Value=[1,4,5,7]

W=7


in left side from row 0 to 4-

row 0 means you have empty array

row 1-weight[]=[1], value[]=1

row 3-weight[]=[1,3,4] ,value[1,4,5]

This is why dynamic programming called technique of solving problem which can we divided into sub problem

 

How to fill table-

Step 1-Intialization

Step 2- convert Recursive call  to interation

Question Why we choose only n and W for table if you look recurve call from previous tutorial

Knapsack(int v[],int weight[],int n,int W) only n and W are changing so we choose n and W for Table.

 

Step 1-Initilization

We have to think about base condition

If(n==0||w==0)

  return 0;

so think about if you have array size of zero then for any weight size of knapsack value will be zero so we fill first row with zero.

Now think if you have zero weight size of knapsack then for any size of given array value will be zero so we fill first column with zero.

Step 2-Convert recursive call to iteration.

From previous tutorial

Taken then=> value[n-1]+knapsack(value[],weight[],n-1,W-weight[n-1])

Not Taken=>knapsack(value[],weight[],n-1,W)

For these two=

if (weight[i-1]<=j)

dp[i][j]=max(value[i-1]+dp[i-1][j-weight[i-1]],dp[i-1][j])

//means if you choose this item then you have to choose previous but weight is decrease from current weight or if you don’t choose then previous row but column will not change because weight is not decrease.

Size greater =>knapsack(value[],weight[],n-1,W)

For this

dp[i][j]=dp[i-1][j]

 

now fill Table

    0                     1                   2                      3                    4                     5                  6                    7

0

0

0

0

0

0

0

0

0

1

1

1

1

1

1

1

0

1

1

(4+0,1)

(4+1,1)

5

5

5

0

1

1

4

(5+0,5)

(5+1,5)

(5+1,5)

(5+4,5)

0

1

1

4

5

(7+0,6)

(7+1,6)

(7+1,9)

Answer will we dp[n][W] which is 9.

Where to Practice-

https://practice.geeksforgeeks.org/problems/0-1-knapsack-problem/0

Code-

#include <bits/stdc++.h>

using namespace std;

int main() {

int t;

cin>>t;

while(t--)

{

    int n,W;cin>>n>>W;

    int value[n+1],weight[n+1];

   int dp[n+1][W+1];

          memset(dp,-1,sizeof(dp));

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

     cin>>value[i];

    

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

      cin>>weight[i];

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

   {

    for(int j=0;j<=W;j++)

    {

    if(i==0||j==0)

    dp[i][j]=0;

    else if(weight[i-1]<=j)

    dp[i][j]=max(value[i-1]+dp[i-1][j-weight[i-1]],dp[i-1][j]);

    else

    dp[i][j]=dp[i-1][j];

    }

   }

   cout<<dp[n][W]<<"\n";

}

}

Time complexity-

O(n*W)

Space complexity

(n*W)

 

 

 

 

 


The Future of Web Development: Why Next.js is Going Viral

  Are you ready to level up your web development game? Look no further than Next.js, the latest sensation in the world of web development th...