Oversized backpack problem

Source: Internet
Author: User
Tags bitmask

Before starting the problem, first introduce the use of C + + header file <algorithm> next_permutation () and pre_permutation generate 0, 1, 2, 3, ... N-1 the whole arrangement. These two functions

The way to produce the whole row is through the principle of dictionary order. Next_permutation () The next (the only definite, and current permutation) of the dictionary order is generated by an incremental approach, which cannot be mixed with any possible

arrangement). Prev_permutation () produces the last permutation of the dictionary order that is currently arranged, in descending order. The resulting dictionary order is smaller than the current arrangement.

The following uses next_permutation to generate 0, 1, ... N-1 all of the full-array methods:

Next_permutation example#include <iostream>     //Std::cout#include <algorithm>    //Std::next_ Permutation, Std::sortint main () {  int myints[] = {-*-n};  Std::sort (myints,myints+3); There must be this step, otherwise it may produce incomplete  std::cout << "the 3! Possible permutations with 3 elements:\n ";  Do {    std::cout << myints[0] << "<< myints[1] << ' << myints[2] << ' \ n ';  } while (Std::next_permutation (myints,myints+3));  Std::cout << "after loop:" << myints[0] << ' << myints[1] << ' << myints[2] <& Lt ' \ n ';  return 0;}
The results of the operation are as follows:

Of course, a recursive approach can also be used to produce the following methods:

#include <iostream>using namespace std;void swap (char *fir, char *sec) {    char temp = *fir;    *fir = *sec;    *sec = temp;} /* Arr is the string, Curr are the current index to start permutation from and size are sizeof the arr */void permutation (ch AR * arr, int curr, int size) {    if (Curr = = size-1)//base case    {for        (int a=0; a<size; a++)            cout << ; Arr[a] << "\ t";        cout << Endl;    }    else    {        for (int i=curr; i<size; i++)        {            swap (&arr[curr], &arr[i]);//Exchange            Permutation (arr, curr+1, size); Keep Curr, arrange            swap (&arr[curr], &arr[i]);//In Swap back        }    }}int Main () {    char str[] = " ABCD ";    Permutation (str, 0, sizeof (str)-1);    return 0;}

Operation Result:



In addition, from 0, .... N takes out all the combinations of the k digits. Use the bitmask array to mask all the index, mask out all n-k elements, remove the K elements from it. Of course, we need to find all the Beats (K 1).

#include <algorithm> #include <iostream> #include <string>using namespace std;//choose K numbers from 0 , 1, ..., nvoid comb (int N, int K) {    string bitmask (k, 1);//K leading 1 ' s    bitmask.resize (N, 0);//N-k Trailin G 0 ' s    //print all integers and permute bitmask    do{        for (int i = 0; i < N; ++i) {//[0, N-1] integers
   
    if (Bitmask[i]) cout << "" << i;        }        cout << Endl;    } while (Prev_permutation (Bitmask.begin (), Bitmask.end ()));} int main () {    comb (5, 3);}
   


The results of the operation are as follows:



Finally, let's say that the array size is n, that is, there are n numbers, and we need to select all possible combinations. What to do. This is the enumeration method. For example, we have n = 4, that is, we have four elements, and the number of all possible combinations is 2^4 = 16, that is, each element corresponds to or does not choose either of these two possibilities. What to do???

This is one of the most acute problems faced by the oversized knapsack problem. In fact, we are using the following approach (the core code):

for (int i = 0; i < 1 >> N; j + +) {for    (int j = 0; i < n; ++j) {        if (i >> J & 1) {            //doing Your Stuff        }}}    

Below we analyze the above code:

n = 4, then 1 >> 4 = 16, or 16 possibilities. For visual representation, change to the following:

for (int i = 0; i <; J + +) {for    (int j = 0; i < n; ++j) {        if (i >> J & 1) {            //doing your stuf F        }}}    


The introduction is over, to the point, the following talk about the biggest knapsack problem!!

The problem is described as follows:

There are n items of weight and value (WI, vi) respectively. Select items from these items that do not have a total weight of W. The maximum value of the total value in the selection scheme.

Restrictions:

1<= N <= 40,

1<= WI, vi <= 10^ (15)

1 <= W <= 10^ (15).

Input:

n = 4

W = {2, 1, 3, 2}

v = {3, 2, 4, 2}

W = 5

Output:

7 (pick items 0, 1th and 3rd).


Problem Analysis:

This problem is a knapsack problem. But this time the weight and the value can be very large values, but compared to n is a relatively small number. The time complexity of solving knapsack problems using DP (Dynamic programming) is

O (NW), not very realistic. We should use n relatively small features to solve. So we're not using a dynamic programming approach.

There are 2^n ways of selecting items. So you cannot enumerate directly. But by dividing it into two halves after enumerating!!!!! This will satisfy the requirements.

7

After splitting the weight and value of the two halves, each part has a maximum of 20 (because n is the maximum of 40). We count the sum of the weights and the sum of the values of the first half as W1, v1. Look for the total weight in the second part.

W2 < W-w1, make the V2 the largest selection method is good.

In order to efficiently find Max{v2 | W2 < W-W1} in the collection from the enumeration (W2, V2),. First we need to exclude all W2[i] <= w2[j] and V2[i] >= v2[j]. This can be done simply by following W2, V2 's Dictionary ordering. All remaining elements then meet W2[i] < W2[j] <-------> V2[i] < v2[j]. So we just need to look for W2[i] < W-W1 the largest I can. This can be done with a two-point search.

If the number of remaining elements is m, the time required for a search is O (LOGM). Because of M <= 2^ (N/2), the total complexity of the algorithm is O (n * 2^ (N/2)).

The procedure is as follows:

#include <iostream> #include <utility>//For pair<> #include <algorithm>//For std::sortusing Namespace Std;typedef long Long int64;const int max_n = + 5;const Int64 INF = 0x3fffffffffffffff;int N;int64 W[max_n], V[max_n];int64 W;pair<int64, int64> ps[1 << (MAX_N/2)];    (weight, value) void Solve () {//enum first half int n2 = N/2;        for (int i = 0; i < 1 << n2; ++i) {//N2 all combinations of items Int64 SW = 0, SV = 0;                for (int j = 0; J < n2; ++j) {if (i >> J & 1) {SW + = W[j];            SV + = V[j];    }} Ps[i] = Make_pair (SW, SV);    }//Remove excess elements sort (PS, PS + (1 << n2));    int m = 0; for (int i = 1; I <= 1 << (N-N2); ++i) {if (Ps[m-1].second < Ps[i].second) {ps[m++] = PS        [i];    }}//Enumerate back half Int64 res = 0;        for (int i = 0; i < 1 << (N-N2); ++i) {//N2 all combinations of items Int64 SW = 0, SV = 0; for (intj = 0; J < N2;                ++J) {if (i >> J & 1) {SW + = w[n2 + j];            SV + = v[n2 + j];             }} if (sw <= W) {Int64 TV = (Lower_bound (PS, PS + M, Make_pair (W-SW, INF))-1)->second;        res = max (res, SV + TV); }} printf ("%i64d\n", res);}    int main () {freopen ("Input.txt", "R", stdin);    Freopen ("Output.txt", "w", stdout);        while (~SCANF ("%d%i64d", &n, &w)) {for (int i = 0; i < n; i++) {scanf ("%i64d", &w[i]);        } for (int i = 0; i < n; i++) {scanf ("%i64d", &v[i]);    } solve (); } return 0;}

Input:

4 52 1 3 23 2 4 2

Output:

7


Oversized backpack problem

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.