Showing posts with label Dynamic Programming. Show all posts
Showing posts with label Dynamic Programming. Show all posts

Thursday, June 30, 2011

Knapsack Problem (Unbounded & 0/1)

The knapsack problem or rucksack problem is a problem in combinatorial optimization: Given a set of items, each with a weight and a value, determine the number of each item to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible. It derives its name from the problem faced by someone who is constrained by a fixed-size knapsack and must fill it with the most useful items.

In the following, we have n kinds of items, 1 through n. Each kind of item i has a value vi and a weight wi. We usually assume that all values and weights are nonnegative. To simplify the representation, we can also assume that the items are listed in increasing order of weight. The maximum weight that we can carry in the bag is W.
The most common formulation of the problem is the 0-1 knapsack problem, which restricts the number xi of copies of each kind of item to zero or one. Mathematically the 0-1-knapsack problem can be formulated as:

maximize sum(vi,xi) for i=0 to n

such that sum(wi*xi)<=W & x(0,1) The unbounded knapsack problem (UKP) places no upper bound on the number of copies of each kind of item. Of particular interest is the special case of the problem with these properties: it is a decision problem, it is a 0-1 problem, for each kind of item, the weight equals the value: wi = vi. Notice that in this special case, the problem is equivalent to this: given a set of nonnegative integers, does any subset of it add up to exactly W? Or, if negative weights are allowed and W is chosen to be zero, the problem is: given a set of integers, does any nonempty subset add up to exactly 0? This special case is called the subset sum problem. In the field of cryptography the term knapsack problem is often used to refer specifically to the subset sum problem.\ Dynamic Programming Solution: Unbounded knapsack problem If all weights () are nonnegative integers, the knapsack problem can be solved in pseudo-polynomial time using dynamic programming. The following describes a dynamic programming solution for the unbounded knapsack problem. To simplify things, assume all weights are strictly positive (wi > 0). We wish to maximize total value subject to the constraint that total weight is less than or equal to W. Then for each w ≤ W, define m[w] to be the maximum value that can be attained with total weight less than or equal to w. m[W] then is the solution to the problem.
Observe that m[w] has the following properties:

m[0]=0 (the sum of zero items, i.e., the summation of the empty set)
m[i]=max(m[w-1],vi+m[w-wi]) where wi<=w where vi is the value of the i-th kind of item. Here the maximum of the empty set is taken to be zero. Tabulating the results from m[0] up through m[W] gives the solution. Since the calculation of each m[w] involves examining n items, and there are W values of m[w] to calculate, the running time of the dynamic programming solution is O(nW). Dividing by their greatest common divisor is an obvious way to improve the running time. Working Code: import java.io.*; class knapsack10 { public static void main(String args[]) throws IOException { int capacity,n; BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); System.out.println ("\n Enter the number of items u want to enter:"); n= Integer.parseInt(br.readLine()); float p[]=new float[n+1]; float x[]=new float[n+1]; int i,j,k,w; int WEIGHT[]=new int[n+1],PROFIT[]=new int[n+1]; WEIGHT[0]=0; PROFIT[0]=0; for(i=1;i<=n;i++) { System.out.println ("\n Enter the weight and profit of "+i+" : item "); WEIGHT[i]= Integer.parseInt(br.readLine()); PROFIT[i]= Integer.parseInt(br.readLine()); p[i]=0; x[i]=0; } System.out.println ("\n Enter the capacity of the knapsack : "); capacity = Integer.parseInt(br.readLine()); float c[][]=new float [n+1][capacity+1]; for(i=0;i<=n;i++) for(j=0;j<=capacity;j++) c[i][j] = 0; for(i=1;i<=n;i++) for(w=1;w<=capacity;w++) if(WEIGHT[i]<=w){ if ((PROFIT[i]+c[i-1][w-WEIGHT[i]])>c[i-1][w])
{
c[i][w] = PROFIT[i] + c[i-1][w-WEIGHT[i]];
p[i] = 1;
}
else
{
c[i][w]=c[i-1][w];
p[i] = 0;
}}
else
{
c[i][w]=c[i-1][w];
p[i] = 0;
}

float temp=0;
int t=0;
for(j=1;j<=capacity;j++)
{
temp = c[n-1][j]-c[n-1][j-1];
for(i=1;i if(temp==PROFIT[i])
t=i;
x[t] = 1;


}
for(j=0;j<=n;j++)
System.out.println (j+" "+x[j] );
System.out.println ("The profit obtained is "+c[n][capacity]);
}
}

The O(nW) complexity does not contradict the fact that the knapsack problem is NP-complete, since W, unlike n, is not polynomial in the length of the input to the problem. The length of the W input to the problem is proportional to the number of bits in W, logW, not to W itself.

Time Complexity O(NlogN) W<=logW
Space Complexity (N^2)

More Info.
www.es.ele.tue.nl/education/5MC10/Solutions/knapsack.pdf
www.cse.unl.edu/~goddard/Courses/CSCE310J/Lectures/Lecture8-DynamicProgramming.pdf

2nd Knapsack 0/1 Problem(In Progress)

Monday, June 27, 2011

Largest Sum Contiguous Subarray

Problem Statement:Write an efficient C program to find the sum of contiguous subarray within a one-dimensional array of numbers which has the largest sum.

Data Structure Used:Array

O(N^3) Algorithm

#include
#include
#include


Sunday, June 5, 2011

WAP to Print All Possible Combination of Given Number From The Given Set "Only".

Given a set of numbers eg:{2,3,6,7,8}.Any one who is playing the game can score points only from this set using the numbers in that set. given a number, print all the possible ways of scoring that many points. Repetition of combinations are not allowed.
eg:
1. 6 points can be scored as
6
3+3
2+2+2

2. 7 can be scored as
7
2+2+3
but 2+3+2 and 3+2+2 is not allowed as they are repetitions of 2+2+3 & so on

3. 8 can be scored as
2+2+2+2
2+3+3
2+6
8

& so on

Algorithms is Pretty Clear if I understand the problem clear, i have already posted the same question with slight modification in which we are not restricted by array elements but we have to print all possible combinations without duplication such that
makes the given sum.

Algorithm

Here is What we do the same keep adding the array value into current-sum until it becomes equals to desired sum isn't it while checking array value is not equals to 0 (as zero don't counts in sum simple )& array values should be <= desired-sum so that we can get all combinations.& repeat the same process until we run out of array.


class PrintAllCombinations
{

public static void main(String[] args)
{
int s = 9;
//int[] a = new int[] {2,3,6,7,8};
int[] a = new int[] {2,3,6,7,8,0,10,66,45,3,56,89};
getCombinatsions(a, 0, s, 0, "");
}

static void getCombinatsions(int[] a, int j, int desiredSum, int currentSum, String st)
{
if(desiredSum == currentSum) {
System.out.println(st);
return;
}


if(currentSum > desiredSum)
{
return;
}



for(int i = j; i < a.length; i++)
{
if (a[i] <= desiredSum && a[i] != 0)
getCombinatsions(a, i, desiredSum, currentSum + a[i], st + "+" + a[i]);
else
break;
}
}


}


Time Complexity (N*2)
Space Complexity O(logn)
Run Here http://ideone.com/x2ICo

Suggestion/Comments are Welcome.??

Friday, June 3, 2011

WAP to find the index in an circular array such that the string that is formed starting from that index is first in lexicographic order.

For Ex : in the circular array ABCDEABCCDE
The answer is 6 because the circular string starting from the element A in the 6th position comes first in the dictionary formed from all the possible strings of the circular array

what is lexicographic order
Given two partially ordered sets A and B, the lexicographical order on the Cartesian product A × B is defined as
(a,b) ≤ (a′,b′) if and only if a < a′ or (a = a′ and b ≤ b′).

so basically we have to print 1st index from differentstring formed by same character leads different lexicographic order such that string comes 1st then other string in lexicographic order from all others .Some of you may stuck with language i written but example makes you more clear

so in case of Given string s= ABCDEABCCDEA
A comes at 0,5 & 11th position as you can see AA comes 1st then ABCCDE in lexicographic order or alphabetically order or dictionary order then ABCDE so output will be 11 not 0 or 5th index . you can easily visualize it you know about TRIE or Dictionary

This problem can be Solved in Two Ways

1st Simple Iterative Solution

#include
#include


int findIndex(const char* str){

int minindex= 0, i, j, k, temp, len = strlen(str);

for(i = 1; i < len; ++i){

if(str[i] < str[ret]){

minindex= i;

} else if(str[i] == str[ret]){

k = i;
temp= ret;

for(j = 0 ; j < len; j++){

k = (k + j) % len;
temp= (temp + j) % len;

if(str[k] < str[l]){
minindex = i;
break;//once we found minindex terminate to optimize the inner loop
}
}
}
}
return ret;
}
int main() {

char *s = "ABCDEABCCDEA";

printf("%d\n", findIndex(s));
}

Time Complexity O(N^2) when suppose ABCDEFGHACDEFGHA so only inner loop will run until last index of A. isn't it i suggest you to dry run it.
Space Complexity O(1)
Run Here http://ideone.com/rgMSE

2nd DP Solution

PS:Working On The Code ..