Sum of average of all subsets

3.7

Given an array arr of N integer elements, the task is to find sum of average of all subsets of this array.

Input  : arr[] = [2, 3, 5]
Output : 23.33 
Explanation : Subsets with their average are, 
[2]		average = 2/1 = 2
[3]		average = 3/1 = 3
[5]		average = 5/1 = 5
[2, 3]		average = (2+3)/2 = 2.5
[2, 5]		average = (2+5)/2 = 3.5
[3, 5]		average = (3+5)/2 = 4
[2, 3, 5]	average = (2+3+5)/3 = 3.33

Sum of average of all subset is, 
2 + 3 + 5 + 2.5 + 3.5 + 4 + 3.33 = 23.33

A naive solution is to iterate through all possible subsets, get average of all of them and then add them one by one, but this will take exponential time and will be infeasible for bigger arrays.

We can get a pattern by taking an example,

arr = [a0, a1, a2, a3]
sum of average = 
a0/1 + a1/1 + a2/2 + a3/1 +
(a0+a1)/2 + (a0+a2)/2 + (a0+a3)/2 + (a1+a2)/2 +
 (a1+a3)/2 + (a2+a3)/2 + 
(a0+a1+a2)/3 + (a0+a2+a3)/3 + (a0+a1+a3)/3 + 
 (a1+a2+a3)/3 +
(a0+a1+a2+a3)/4

If S = (a0+a1+a2+a3), then above expression 
can be rearranged as below,
sum of average = (S)/1 + (3*S)/2 + (3*S)/3 + (S)/4

The coefficient with numerators can be explained as follows, suppose we are iterating over subsets with K elements then denominator will be K and numerator will be r*S, where ‘r’ denotes number of times a particular array element will be added while iterating over subsets of same size. By inspection we can see that r will be nCr(N – 1, n – 1) because after placing one element in summation, we need to choose (n – 1) elements from (N – 1) elements so each element will have a frequency of nCr(N – 1, n – 1) while considering subsets of same size, as all elements are taking part in summation equal number of times, this will the frequency of S also and will be the numerator in final expression.
In below code nCr is implemented using dynamic programming method, you can read more about that here,

//  C++ program to get sum of average of all subsets
#include <bits/stdc++.h>
using namespace std;

// Returns value of Binomial Coefficient C(n, k)
int nCr(int n, int k)
{
    int C[n+1][k+1];
    int i, j;

    // Calculate value of Binomial Coefficient in bottom
    // up manner
    for (i = 0; i <= n; i++)
    {
        for (j = 0; j <= min(i, k); j++)
        {
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;

            // Calculate value using previously stored
            // values
            else
                C[i][j] = C[i-1][j-1] + C[i-1][j];
        }
    }
    return C[n][k];
}

//  method returns sum of average of all subsets
double resultOfAllSubsets(int arr[], int N)
{
    double result = 0.0; // Initialize result

    // Find sum of elements
    int sum = 0;
    for (int i = 0; i < N; i++)
         sum += arr[i];

    //  looping once for all subset of same size
    for (int n = 1; n <= N; n++)

        /* each element occurs nCr(N-1, n-1) times while
           considering subset of size n  */
        result += (double)(sum * (nCr(N - 1, n - 1))) / n;

    return result;
}

//  Driver code to test above methods
int main()
{
    int arr[] = {2, 3, 5, 7};
    int N = sizeof(arr) / sizeof(int);
    cout << resultOfAllSubsets(arr, N) << endl;
    return 0;
}

Output:

63.75

This article is contributed by Utkarsh Trivedi. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

GATE CS Corner    Company Wise Coding Practice

Recommended Posts:



3.7 Average Difficulty : 3.7/5.0
Based on 10 vote(s)










Writing code in comment? Please use ide.geeksforgeeks.org, generate link and share the link here.