Let's look at one question first:
Suppose that there are radio stations that need to be paid below, as well as the areas covered by the station signals.How to select the fewest stations so that all regions can receive signals
Introduction to Greedy Algorithms
-
Greedy algorithm (greedy algorithm) refers to an algorithm that takes the best or the best (i.e., the most favorable) choice in each step of solving a problem in the hope that the result will be the best or the best one.
-
The results obtained by the greedy algorithm are not necessarily optimal (sometimes optimal), but are the results of relatively approximate (near) optimal solutions.
Set Coverage Problem
- Suppose there are paid radio stations in the table below, as well as the areas covered by the station signals.How to select the fewest stations so that all regions can receive signals
Idea analysis:
How do you find the set of broadcasters that cover all areas? Use the enumeration method to list the sets of each possible broadcaster, which is called the power set.Assuming there are n stations in total, there are 2_-1 combinations of stations, assuming that 10 subsets can be calculated per second, as shown in Fig.
Ideas analysis using greedy algorithms:
Greedy algorithm has high efficiency: currently there is no algorithm to quickly calculate the prepared values, and greedy algorithm can get very close solution with high efficiency.Choose a strategy because you need to cover the smallest set of regions:
- Traverse through all the radio stations and find one that covers the most uncovered areas (this station may contain some covered areas, but that's okay)
- Add this station to a collection (such as ArrayList) and find ways to remove the area it covers from the next comparison.
- Repeat step 1 until all areas are covered
- code implementation
/** * Greedy algorithm, radio problem */ public class GreedyAlgorithm { public static void main(String[] args) { // Area collection, not repeatable 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"); // Radio stations and radio stations correspond to collections of coverage areas HashMap<String,HashSet<String>> broadcasts = new HashMap<>(); //Place each station in broadcasts HashSet<String> hashSet1 = new HashSet<String>(); hashSet1.add("Beijing"); hashSet1.add("Shanghai"); hashSet1.add("Tianjin"); HashSet<String> hashSet2 = new HashSet<String>(); hashSet2.add("Guangzhou"); hashSet2.add("Beijing"); hashSet2.add("Shenzhen"); HashSet<String> hashSet3 = new HashSet<String>(); hashSet3.add("Chengdu"); hashSet3.add("Shanghai"); hashSet3.add("Hangzhou"); HashSet<String> hashSet4 = new HashSet<String>(); hashSet4.add("Shanghai"); hashSet4.add("Tianjin"); HashSet<String> hashSet5 = new HashSet<String>(); 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); List<String> list = greedyAlgorithm(allAreas, broadcasts); System.out.println(list.toString()); } /** * * @param allArea All regional assemblies, * @param broadcasts Broadcasting station * @return Return the fewest radio stations to cover all areas */ public static List<String> greedyAlgorithm(HashSet<String> allArea, HashMap<String,HashSet<String>> broadcasts) { if (allArea == null || allArea.isEmpty() || broadcasts == null || broadcasts.size() == 0) { return null; } // Define a radio station to assemble the optimal solution ArrayList<String> optimalBroadcasts = new ArrayList<>(); // Define a temporary set of areas that each station can cover HashSet<String> tempSet = new HashSet<>(); // Define a variable that is the largest key that can cover an area that is not covered String maxKey; // Define a variable that Baocun maxKey can cover the size of uncovered areas int maxKeySize; // Loop as long as allArea is not empty while (!allArea.isEmpty()) { // Every while loop needs to clear maxKey, and maxKeySize, because every time a new start is sought, the last data needs to be cleared maxKey = null; maxKeySize = 0; // Traverse through each station for (String string : broadcasts.keySet()) { // Clear the tempSet first, because each iteration adds data to the tempSet. // If the last tempSet is not empty, it can confuse the data tempSet.clear(); // Get the area covered by this station HashSet<String> strings = broadcasts.get(string); // Store in temporary array tempSet.addAll(strings); // Intersect with allArea to get the coverage of the station in areas not covered tempSet.retainAll(allArea); // This shows the nature of the greedy algorithm, which chooses the best solution each time, i.e., the one that covers the most areas. if (tempSet.size() > 0 && (maxKey == null || tempSet.size() > maxKeySize)) { maxKey = string; maxKeySize = tempSet.size(); } } // At the end of the for cycle, an optimal radio station is found if (maxKey != null) { optimalBroadcasts.add(maxKey); // Remove the area covered by maxKey in allArea allArea.removeAll(broadcasts.get(maxKey)); } } return optimalBroadcasts; } }
Run Results
[K1, K2, K3, K5]
The core idea of the greedy algorithm is:
// This shows the nature of the greedy algorithm, which chooses the best solution each time, i.e., the one that covers the most areas. if (tempSet.size() > 0 && (maxKey == null || tempSet.size() > maxKeySize)) { maxKey = string; maxKeySize = tempSet.size(); }
Every time you choose the best solution, you also need to understand tempSet.retainAll(allArea); what this means