subroutine knapsack_01_brute ( n, w, c, s ) !*****************************************************************************80 ! !! knapsack_01_brute() seeks a solution of the 0/1 Knapsack problem. ! ! Discussion: ! ! In the 0/1 knapsack problem, a knapsack of capacity C is given, ! as well as N items, with the I-th item of weight W(I). ! ! A selection is "acceptable" if the total weight is no greater than C. ! ! It is desired to find an optimal acceptable selection, that is, ! an acceptable selection such that there is no acceptable selection ! of greater weight. ! ! Licensing: ! ! This code is distributed under the MIT license. ! ! Modified: ! ! 21 August 2014 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, integer N, the number of weights. ! ! Input, integer W(N), the weights. ! ! Input, integer C, the maximum weight. ! ! Output, integer S(N), is a binary vector which defines an ! optimal selection. It is 1 for the weights to be selected, and ! 0 otherwise. ! implicit none integer n integer c integer iadd logical more integer ncard integer s(n) integer s_test(n) integer t integer t_test integer w(n) more = .false. ncard = 0 s_test(1:n) = 0 t_test = 0 s(1:n) = s_test(1:n) t = 0 do call subset_gray_next ( n, s_test, more, ncard, iadd ) t_test = dot_product ( s_test, w ) if ( t < t_test .and. t_test <= c ) then t = t_test s(1:n) = s_test(1:n) end if if ( .not. more ) then exit end if end do return end subroutine subset_gray_next ( n, a, more, ncard, iadd ) !*****************************************************************************80 ! !! subset_gray_next() generates all subsets of a set of order N, one at a time. ! ! Discussion: ! ! It generates the subsets one at a time, by adding or subtracting ! exactly one element on each step. ! ! This uses a Gray code ordering of the subsets. ! ! The user should set MORE = FALSE and the value of N before ! the first call. On return, the user may examine A which contains ! the definition of the new subset, and must check MORE, because ! as soon as it is FALSE on return, all the subsets have been ! generated and the user probably should cease calling. ! ! The first set returned is the empty set. ! ! Example: ! ! N = 4 ! ! 0 0 0 0 ! 1 0 0 0 ! 1 1 0 0 ! 0 1 0 0 ! 0 1 1 0 ! 1 1 1 0 ! 1 0 1 0 ! 0 0 1 0 ! 0 0 1 1 ! 1 0 1 1 ! 1 1 1 1 ! 0 1 1 1 ! 0 1 0 1 ! 1 1 0 1 ! 1 0 0 1 ! 0 0 0 1 ! ! Licensing: ! ! This code is distributed under the MIT license. ! ! Modified: ! ! 02 May 2003 ! ! Author: ! ! Original FORTRAN77 version by Albert Nijenhuis, Herbert Wilf. ! This version by John Burkardt. ! ! Reference: ! ! Albert Nijenhuis, Herbert Wilf, ! Combinatorial Algorithms for Computers and Calculators, ! Second Edition, ! Academic Press, 1978, ! ISBN: 0-12-519260-6, ! LC: QA164.N54. ! ! Parameters: ! ! Input, integer N, the order of the total set from which ! subsets will be drawn. ! ! Input/output, integer A(N). On each return, the Gray code ! for the newly generated subset. A(I) = 0 if element I is in the subset, ! 1 otherwise. ! ! Input/output, logical MORE. Set this variable FALSE before ! the first call. Normally, MORE will be returned TRUE but once ! all the subsets have been generated, MORE will be ! reset FALSE on return and you should stop calling the program. ! ! Input/output, integer NCARD, the cardinality of the set ! returned, which may be any value between 0 (the empty set) and N (the ! whole set). ! ! Output, integer IADD, the element which was added or removed ! to the previous subset to generate the current one. Exception: ! the empty set is returned on the first call, and IADD is set to 0. ! implicit none integer n integer a(n) integer iadd logical more integer ncard ! ! The first set returned is the empty set. ! if ( .not. more ) then a(1:n) = 0 iadd = 0 ncard = 0 more = .true. else iadd = 1 if ( mod ( ncard, 2 ) /= 0 ) then do iadd = iadd + 1 if ( a(iadd-1) /= 0 ) then exit end if end do end if a(iadd) = 1 - a(iadd) ncard = ncard + 2 * a(iadd) - 1 ! ! The last set returned is the singleton A(N). ! if ( ncard == a(n) ) then more = .false. end if end if return end