Program to find weighted median of a given array

Given two arrays arr[] of N integers and W[] of N weights where W[i] is the weight for the element arr[i]. The task is to find the weighted median of the given array.
Note: The sum of the weight of all elements will always be 1.
Let the array arr[] be arranged in increasing order with their corresponding weights.
If N is odd, then there is only one weighted median say arr[k] which satisfies the below property:
 If N is even, then there are two weighted medians, i.e., lower and upper weighted median.The lower weighted median for element arr[k] which satisfies the following:
 The upper weighted median for element arr[k] which satisfies the following:
Examples:
Input: arr={5, 1, 3, 2, 4}, W=[0.25, 0.15, 0.2, 0.1, 0.3]Output: The weighted median is element 4
Explanation:
Here the number of element is odd, so there is only one weighted median because at K = 3 the above condition is satisfied.
The cumulative weights on each side of element 4 is 0.45 and 0.25.Input: arr=[4, 1, 3, 2], W=[0.25, 0.49, 0.25, 0.01]Output:
The lower weighted median is element 2
The upper weighted median is element 3
Explanation:Â
Here there are an even number of elements, so there are two weighted medians.
Lower weighted median is at K = 2 because at K = 2 the above condition is satisfied with cumulative weight on each side of element 2 is 0.49 and 0.5.
Upper weighted median is at K = 3 because at K = 3 the above condition is satisfied with cumulative weight on each side of element 3 is 0.5 and 0.25.
Approach: Follow the steps below to solve the given problem:
- Now to find the median of the array arr[] in increasing order with their respective order of weight shouldn’t be changed.
- So, create a set of pairs where the first element of the pair will be arr[i] and the second element of the pair will be its corresponding weights W[i].
- Then sort the set of Pairs according to the arr[] values.
- If the number of pairs is odd, then find the weighted median as:
- Traverse over the set of pairs and compute sum by adding weights.
- When the sum becomes greater than 0.5 print the arr[i] value of that Pair.
- But, if the number of pairs is even, then find both lower and upper weighted medians:
- For the lower median traverse over the set pairs from the left and compute sum by adding weights.
- When the sum becomes greater than or equal to 0.5 print the arr[i] value of that Pair.
- For the upper median traverse over the set pairs from the right and compute sum by adding weights.
- When the sum becomes greater than or equal to 0.5 print the arr[i] value of that Pair.
Below is the implementation of the above approach:
C++14
// C++ program for the above approach#include <bits/stdc++.h>using namespace std;Â
// Function to calculate weighted medianvoid weightedMedian(vector<int> arr,                    vector<float> W){         // Store pr of arr[i] and W[i]    vector<pair<int, float>> pr;Â
    for(int index = 0;             index < arr.size();             index++)        pr.push_back({arr[index],                         W[index]});Â
    // Sort the list of pr w.r.t.    // to their arr[] values    sort(pr.begin(), pr.end());         // If N is odd    if (arr.size() % 2 != 0)    {                 // Traverse the set pr        // from left to right        float sums = 0;        for(auto element : pr)        {                         // Update sums            sums += element.second;Â
            // If sum becomes > 0.5            if (sums > 0.5)                cout << "The Weighted Median is element "                     << element.first << endl;        }    }           // If N is even    else    {                 // For lower median traverse        // the set pr from left        float sums = 0;        for(auto element : pr)        {                         // Update sums            sums += element.second;Â
            // When sum >= 0.5            if (sums >= 0.5)            {                cout << "Lower Weighted Median is element "                     << element.first << endl;                break;            }        }                 // For upper median traverse        // the set pr from right        sums = 0;        for(int index = pr.size() - 1;                index >= 0;                 index--)        {            int element = pr[index].first;            float weight = pr[index].second;Â
            // Update sums            sums += weight;Â
            // When sum >= 0.5            if (sums >= 0.5)            {                cout << "Upper Weighted Median is element "                     << element;                break;            }        }    }}Â
// Driver Codeint main(){         // Given array arr[]    vector<int> arr = { 4, 1, 3, 2 };         // Given weights W[]    vector<float> W = { 0.25, 0.49, 0.25, 0.01 };         // Function Call    weightedMedian(arr, W);}Â
// This code is contributed by mohit kumar 29 |
Java
// Java program for the// above approachimport java.util.*;class GFG{Â
static class Pair implements Comparable<Pair>{Â Â int first;Â Â double second;Â
  Pair(int f, double s)  {    first = f;    second = s;  }Â
  @Override  public int compareTo(Pair o)  {    if(this.second > o.second)      return 1;    else if(this.second == o.second)      return 0;    return -1;  }}Â
// Function to calculate weighted medianstatic void weightedMedian(Vector<Integer> arr,                           Vector<Double> W){  // Store pr of arr[i] and W[i]  Vector<Pair> pr = new Vector<>();Â
  for(int index = 0;       index < arr.size();       index++)    pr.add(new Pair(arr.get(index),                    W.get(index)));Â
  // Sort the list of pr w.r.t.  // to their arr[] values  Collections.sort(pr);Â
  // If N is odd  if (arr.size() % 2 != 0)  {    // Traverse the set pr    // from left to right    float sums = 0;    for(Pair element : pr)    {      // Update sums      sums += element.second;Â
      // If sum becomes > 0.5      if (sums > 0.5)        System.out.print(               "The Weighted Median is element " +                 element.first + "\n");    }  }Â
  // If N is even  else  {    // For lower median traverse    // the set pr from left    double sums = 0;    for(Pair element : pr)    {      // Update sums      sums += element.second;Â
      // When sum >= 0.5      if (sums <= 0.5)      {        System.out.print(               "Lower Weighted Median is element " +                 element.first + "\n");        break;      }    }Â
    // For upper median traverse    // the set pr from right    sums = 0;    for(int index = pr.size() - 1;            index >= 0; index--)    {      int element = pr.get(index).first;      double weight = pr.get(index).second;Â
      // Update sums      sums += weight;Â
      // When sum >= 0.5      if (sums >= 0.5)      {        System.out.print(               "Upper Weighted Median is element " +                 element);        break;      }    }  }}Â
// Driver Codepublic static void main(String[] args){Â Â Â Â Â // Given array arr[]Â Â Vector<Integer> arr = new Vector<>();Â Â arr.add(4);Â Â arr.add(1);Â Â arr.add(3);Â Â arr.add(2);Â
  // Given weights W[]  Vector<Double> W =  new Vector<>();  W.add(0.25);  W.add(0.49);  W.add(0.25);  W.add(0.01);Â
  // Function Call  weightedMedian(arr, W);}}Â
// This code is contributed by gauravrajput1 |
Python3
# Python3 program for the above approachÂ
# Function to calculate weighted mediandef weightedMedian(arr, W):Â
    # Store pairs of arr[i] and W[i]    pairs = []         for index in range(len(arr)):        pairs.append([arr[index], W[index]])Â
    # Sort the list of pairs w.r.t.    # to their arr[] values    pairs.sort(key = lambda p: p[0])Â
    # If N is odd    if len(arr) % 2 != 0:Â
        # Traverse the set pairs        # from left to right        sums = 0        for element, weight in pairs:                     # Update sums            sums += weightÂ
            # If sum becomes > 0.5            if sums > 0.5:                print("The Weighted Median", end = ' ')                print("is element {}".format(element))Â
    # If N is even    else:Â
        # For lower median traverse        # the set pairs from left        sums = 0        for element, weight in pairs:                         # Update sums            sums += weightÂ
            # When sum >= 0.5            if sums >= 0.5:                print("Lower Weighted Median", end = ' ')                print("is element {}".format(element))                breakÂ
        # For upper median traverse        # the set pairs from right        sums = 0        for index in range(len(pairs)-1, -1, -1):                     element = pairs[index][0]            weight = pairs[index][1]                         # Update sums            sums += weightÂ
            # When sum >= 0.5            if sums >= 0.5:                print("Upper Weighted Median", end = ' ')                print("is element {}".format(element))                breakÂ
# Driver Codeif __name__ == "__main__":Â Â Â Â Â Â Â Â Â # Given array arr[]Â Â Â Â arr = [4, 1, 3, 2]Â Â Â Â Â Â Â Â Â # Given weights W[]Â Â Â Â W = [0.25, 0.49, 0.25, 0.01]Â
    # Function Call    weightedMedian(arr, W) |
C#
// C# program for the above approachusing System;using System.Collections.Generic;Â
class GFG{     // Function to calculate weighted medianstatic void weightedMedian(int[] arr,                           float[] W){         // Store pr of arr[i] and W[i]    List<Tuple<int,                float>> pr = new List<Tuple<int,                                           float>>();      for(int index = 0; index < arr.Length; index++)        pr.Add(new Tuple<int, float>(arr[index], W[index]));      // Sort the list of pr w.r.t.    // to their arr[] values    pr.Sort();          // If N is odd    if (arr.Length % 2 != 0)    {                 // Traverse the set pr        // from left to right        float sums = 0;        foreach(Tuple<int, float> element in pr)        {                         // Update sums            sums += element.Item2;              // If sum becomes > 0.5            if (sums > 0.5)                Console.WriteLine("The Weighted Median " +                                  "is element " + element.Item1);        }    }            // If N is even    else    {                 // For lower median traverse        // the set pr from left        float sums = 0;        foreach(Tuple<int, float> element in pr)        {                         // Update sums            sums += element.Item2;              // When sum >= 0.5            if (sums >= 0.5)            {                Console.WriteLine("Lower Weighted Median " +                                  "is element " + element.Item1);                break;            }        }                  // For upper median traverse        // the set pr from right        sums = 0;        for(int index = pr.Count - 1; index >= 0; index--)        {            int element = pr[index].Item1;            float weight = pr[index].Item2;              // Update sums            sums += weight;              // When sum >= 0.5            if (sums >= 0.5)            {                Console.Write("Upper Weighted Median " +                               "is element " + element);                break;            }        }    }}Â
// Driver codestatic void Main(){         // Given array arr[]    int[] arr = { 4, 1, 3, 2 };          // Given weights W[]    float[] W = { 0.25f, 0.49f, 0.25f, 0.01f };          // Function Call    weightedMedian(arr, W);}}Â
// This code is contributed by divyeshrabadiya07 |
Javascript
<script>// Javascript program for the// above approachÂ
// Function to calculate weighted medianfunction weightedMedian(arr,W){Â
    // Store pr of arr[i] and W[i]  let pr = [];    for(let index = 0;      index < arr.length;      index++)    pr.push([arr[index],                    W[index]]);    // Sort the list of pr w.r.t.  // to their arr[] values  (pr).sort(function(a,b){return a[1]-b[1];});    // If N is odd  if (arr.length % 2 != 0)  {    // Traverse the set pr    // from left to right    let sums = 0;    for(let element=0;element< pr.length;element++)    {      // Update sums      sums += pr[element][1];        // If sum becomes > 0.5      if (sums > 0.5)        document.write(               "The Weighted Median is element " +                pr[element][0] + "<br>");    }  }    // If N is even  else  {    // For lower median traverse    // the set pr from left    let sums = 0;    for(let element=0;element< pr.length;element++)    {      // Update sums      sums += pr[element][1];        // When sum >= 0.5      if (sums <= 0.5)      {        document.write(               "Lower Weighted Median is element " +                 pr[element][0] + "<br>");        break;      }    }      // For upper median traverse    // the set pr from right    sums = 0;    for(let index = pr.length - 1;            index >= 0; index--)    {      let element = pr[index][0];      let weight = pr[index][1];        // Update sums      sums += weight;        // When sum >= 0.5      if (sums >= 0.5)      {        document.write(               "Upper Weighted Median is element " +                element);        break;      }    }  }}Â
// Driver Code// Given array arr[]let arr = [];arr.push(4);arr.push(1);arr.push(3);arr.push(2);Â
// Given weights W[]let W =Â [];W.push(0.25);W.push(0.49);W.push(0.25);W.push(0.01);Â
// Function CallweightedMedian(arr, W);Â
// This code is contributed by patel2127</script> |
Lower Weighted Median is element 2 Upper Weighted Median is element 3
Â
Time Complexity: O(N log N)
Auxiliary Space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



