[Data Structure and Algorithms] Greedy algorithm

One, Scenario-Collection Coverage Problem

Assume that there are the following pay stations and the areas covered by the station signals. How to select the fewest stations so that all regions can receive the signals

Radio StationCoverage Area
K1Beijing, Shanghai, Tianjin
K2Guangzhou, Beijing, Shenzhen
K3Chengdu, Shanghai, Hangzhou
K4Shanghai, Tianjin
K5Hangzhou, Dalian

2. Basic introduction

1) Greedy algorithm (greedy algorithm) refers to the best or the best (that is, the most favorable) choice in each step of solving a problem in the hope that the result will be the best or the best algorithm.
2) The results obtained by the greedy algorithm are not necessarily optimal (sometimes the optimal solution), but are the results of relatively approximate (near) optimal solutions.

3. Idea analysis

How do I find the set of broadcasters that cover all regions? Use the enumeration method to list the sets of each possible station, which is called the power set. Assuming there are n stations in total, the total set of broadcasters is 2^n - 1. Assuming that 10 subsets can be calculated per second, when n is very large, the number of combinations is obviously unavailable.
Currently, there are no algorithms that can quickly compute accurate values. With greedy algorithms, very close solutions can be obtained with high efficiency.
1) Traverse through all the radio and television stations and find a station that covers the most uncovered areas (this station may contain some covered areas, but that's okay);
2) Add this station to a collection (such as ArrayList) and find ways to remove the area covered by the station from the next comparison;
3) Repeat step 1 until all areas are covered.

Fourth, basic steps

  1. Set up a list allAreas={"Beijing", "Shanghai", "Tianjin", "Guangzhou", "Shenzhen", "Chengdu", "Hangzhou", "Dalian"} to store all uncovered areas; list select={} to store radio stations;
  2. The first time you use station K1,(K1,K2,K3 cover as much, so take one in order):
    allAreas={"Guangzhou", "Shenzhen", "Chengdu", "Hangzhou", "Dalian"}; select = {"k1"};
    The remaining urban radio coverage is
Radio StationCoverage Area
K1
K2Guangzhou, Shenzhen
K3Chengdu, Hangzhou
K4
K5Hangzhou, Dalian
  1. The second time station K2 is used,
    allAreas={"Chengdu", "Hangzhou", "Dalian"}; select = {"k1", "k2"};
    The remaining urban radio coverage is
Radio StationCoverage Area
K1
K2
K3Chengdu, Hangzhou
K4
K5Hangzhou, Dalian
  1. For the third time using station K3,
    allAreas={"Hangzhou"}; select = {"k1", "k2", "k3"};
    The remaining urban radio coverage is
Radio StationCoverage Area
K1
K2
K3
K4
K5Dalian
  1. The area covered by k4 is already covered. If K5 is used, then
    allAreas={};selects = {"k1","k2","k3","k4"};

5. Code implementation

package com.algorithm.greedy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

public class GreedyAlgorithm {
    public static void main(String[] args) {
        //Create a radio station and put it in a Map
        HashMap<String, HashSet<String>> broadcasts = new HashMap<>();
        //Place each station in broadcasts
        HashSet<String> hashSet1 = new HashSet<>();
        hashSet1.add("Beijing");
        hashSet1.add("Shanghai");
        hashSet1.add("Tianjin");
        HashSet<String> hashSet2 = new HashSet<>();
        hashSet2.add("Guangzhou");
        hashSet2.add("Beijing");
        hashSet2.add("Shenzhen");
        HashSet<String> hashSet3 = new HashSet<>();
        hashSet3.add("Chengdu");
        hashSet3.add("Shanghai");
        hashSet3.add("Hangzhou");
        HashSet<String> hashSet4 = new HashSet<>();
        hashSet4.add("Shanghai");
        hashSet4.add("Tianjin");
        HashSet<String> hashSet5 = new HashSet<>();
        hashSet5.add("Hangzhou");
        hashSet5.add("Dalian");
        //Join to map
        broadcasts.put("k1",hashSet1);
        broadcasts.put("k2",hashSet2);
        broadcasts.put("k3",hashSet3);
        broadcasts.put("k4",hashSet4);
        broadcasts.put("k5",hashSet5);
        //Store all areas
        HashSet<String> allAreas = new HashSet<>();
        allAreas.add("Beijing");
        allAreas.add("Shanghai");
        allAreas.add("Tianjin");
        allAreas.add("Guangzhou");
        allAreas.add("Shenzhen");
        allAreas.add("Chengdu");
        allAreas.add("Hangzhou");
        allAreas.add("Dalian");
        //Create an ArrayList to store the selected radio collection
        ArrayList<String> selects = new ArrayList<>();
        //Defines a temporary collection that stores the intersection of the radio coverage during traversal and the area not yet traversed
        HashSet<String> tempSet = new HashSet<>();
        //Store the intersection of maxKey's radio coverage and areas not yet traversed
        HashSet<String> tempSet2 = new HashSet<>();
        //Define the maxKey, which is saved in one traversal to cover the radio key for the largest area
        //If maxKey is not null, it is added to select
        String maxKey = null;
        while (allAreas.size() != 0) { //If allAreas is not zero, it means that not all areas have been covered
            //Traverse broadcasts and take out the corresponding key
            for (String key : broadcasts.keySet()) {
                //for every occurrence
                tempSet.clear();
                //Currently the area covered by this key
                HashSet<String> areas = broadcasts.get(key);
                tempSet.addAll(areas);
                //Find the intersection of the tempSet and allAreas sets, and assign the intersection to the tempSet
                //If this collection currently contains more uncovered areas than maxKey points to
                tempSet.retainAll(allAreas);
                if (maxKey != null) {
                    tempSet2 = broadcasts.get(maxKey);
                    tempSet2.retainAll(allAreas);
                }
                if (tempSet.size() > 0 && (maxKey == null || tempSet.size() > tempSet2.size()) ) {
                    maxKey = key;
                }
            }
            //If (maxKey!= null) maxKey should be added to select
            if (maxKey != null) {
                selects.add(maxKey);
                //Remove the area covered by the radio station that maxKey points to from allAreas
                allAreas.removeAll(broadcasts.get(maxKey));
                maxKey = null;
            }
        }
        System.out.println("selects = " + selects);
    }
}

Sixth, run results

7. Notes

1) The results obtained by the greedy algorithm are not necessarily optimal (sometimes the optimal solution), but are the results of approximating (approaching) the optimal solution.
2) For example, the time K1, K2, K3, K5 selected by the above algorithm is suitable for all regions.
3) But we find that K2, K3, K4, K5 can also cover all areas. If the cost of K2 is lower than K1, then the K1,K2,K3,K5 in our question are not optimal although they meet the requirements.

Tags: Algorithm data structure

Posted on Sun, 17 Oct 2021 12:46:07 -0400 by aisalen