# include # include # include # include # include "subset_sum_brute.h" /******************************************************************************/ int i4_power ( int i, int j ) /******************************************************************************/ /* Purpose: i4_power() returns the value of I^J. Licensing: This code is distributed under the MIT license. Modified: 23 October 2007 Author: John Burkardt Input: int I, J, the base and the power. J should be nonnegative. Output: int I4_POWER, the value of I^J. */ { int k; int value; if ( j < 0 ) { if ( i == 1 ) { value = 1; } else if ( i == 0 ) { fprintf ( stderr, "\n" ); fprintf ( stderr, "I4_POWER - Fatal error!\n" ); fprintf ( stderr, " I^J requested, with I = 0 and J negative.\n" ); exit ( 1 ); } else { value = 0; } } else if ( j == 0 ) { if ( i == 0 ) { fprintf ( stderr, "\n" ); fprintf ( stderr, "I4_POWER - Fatal error!\n" ); fprintf ( stderr, " I^J requested, with I = 0 and J = 0.\n" ); exit ( 1 ); } else { value = 1; } } else if ( j == 1 ) { value = i; } else { value = 1; for ( k = 1; k <= j; k++ ) { value = value * i; } } return value; } /******************************************************************************/ int *i4_to_digits_binary ( int i, int n ) /******************************************************************************/ /* Purpose: i4_to_digits_binary() produces the binary digits of an I4. Example: I N C Binary -- --- --- ------------ 0 1 0 0 0 2 0, 0 00 1 3 1, 0, 0 100 2 3 0, 1, 0 010 3 3 1, 1, 0 011 4 3 0, 0, 1 100 8 3 0, 0, 0 (1)000 8 5 0, 0, 0, 1, 0 01000 -8 5 0, 0, 0, 1, 0 (-) 01000 0 3 0, 0, 0 1 3 1, 0, 0 2 3 0, 1, 0 3 3 1, 1, 0 4 3 0, 0, 1 5 3 1, 0, 1 6 3 0, 1, 1 7 3 1, 1, 1 Licensing: This code is distributed under the MIT license. Modified: 19 December 2011 Author: John Burkardt Input: int I, the integer to be analyzed. int N, the number of digits to determine. Output: int I4_TO_DIGITS_BINARY[N], the first N binary digits of I. Entry 0 is the units digit. */ { int *c; int j; c = ( int * ) malloc ( n * sizeof ( int ) ); i = abs ( i ); for ( j = 0; j < n; j++ ) { c[j] = i % 2; i = ( i - c[j] ) / 2; } return c; } /******************************************************************************/ int i4vec_dot_product ( int n, int x[], int y[] ) /******************************************************************************/ /* Purpose: i4vec_dot_product() computes the dot product of two I4VEC's. Discussion: An I4VEC is a vector of I4's. Licensing: This code is distributed under the MIT license. Modified: 19 December 2011 Author: John Burkardt Input: int N, the size of the array. int X[N], Y[N], the arrays. Output: int I4VEC_DOT_PRODUCT, the dot product of X and Y. */ { int i; int value; value = 0; for ( i = 0; i < n; i++ ) { value = value + x[i] * y[i]; } return value; } /******************************************************************************/ int *subset_sum_brute ( int n, int weight[], int target ) /******************************************************************************/ /* Purpose: subset_sum_brute() seeks a subset of a set that has a given sum. Discussion: This function tries to compute a target value as the sum of a selected subset of a given set of weights. This function works by brute force, that is, it tries every possible subset to see if it sums to the desired value. Given N weights, every possible selection can be described by one of the N-digit binary numbers from 0 to 2^N-1. It is possible that there may be multiple solutions of the problem. This function will only return the first solution found. Example: n = 6 target = 22 w = (/ 1, 2, 4, 8, 16, 32 /) choice = (/ 0, 1, 1, 0, 1, 0 /) w(choice) = 2 + 4 + 16 = 22 Licensing: This code is distributed under the MIT license. Modified: 01 July 2013 Author: John Burkardt Input: int N, the number of weights. int WEIGHT[N], the weights. int TARGET, the target value. Output: int subset_sum_brute[N], contains a 1 for each weight that is chosen. If no solution was found, all entries are returned as -1. */ { int *choice; int i; int i_max; int w_sum; i_max = i4_power ( 2, n ); for ( i = 0; i < i_max; i++ ) { /* Convert I to a string of binary digits. */ choice = i4_to_digits_binary ( i, n ); /* Combine the weights whose binary digit is 1. */ w_sum = i4vec_dot_product ( n, choice, weight ); /* Return if we matched our target sum. */ if ( w_sum == target ) { return choice; } free ( choice ); } choice = ( int * ) malloc ( n * sizeof ( int ) ); for ( i = 0; i < n; i++ ) { choice[i] = -1; } return choice; } /******************************************************************************/ void timestamp ( ) /******************************************************************************/ /* Purpose: timestamp() prints the current YMDHMS date as a time stamp. Example: 31 May 2001 09:45:54 AM Licensing: This code is distributed under the MIT license. Modified: 24 September 2003 Author: John Burkardt */ { # define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct tm *tm; time_t now; now = time ( NULL ); tm = localtime ( &now ); strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm ); fprintf ( stdout, "%s\n", time_buffer ); return; # undef TIME_SIZE }