Loading src/edu/bu/ec504/hw3/p2/MyCanvas.java +83 −6 Original line number Diff line number Diff line // referencing: https://stackoverflow.com/questions/15882202/minimum-number-of-circles-with-radius-r-to-cover-n-points package edu.bu.ec504.hw3.p2; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Random; public class MyCanvas extends Canvas { Loading @@ -17,12 +22,84 @@ public class MyCanvas extends Canvas { @Override public ArrayList<CanvasPoint> generateCovering() { // This demo implementation generates a trivial covering, where there is // a circle around each point. ArrayList<CanvasPoint> centers = new ArrayList<>(); for (CanvasPoint pnt: this) { centers.add(new CanvasPoint(pnt.x, pnt.y)); ArrayList<CanvasPoint> coveredPoints = new ArrayList<>(); ArrayList<CanvasPoint> selectedCircles = new ArrayList<>(); Map<CanvasPoint, ArrayList<CanvasPoint>> circleCandidates = new HashMap<>(); // generate 10 circles for each point whose center is within a radius distance from the point for (CanvasPoint point : this) { // store generated circles in list ArrayList<CanvasPoint> circlesForPoint = new ArrayList<>(); for (int i = 0; i < 10; i++) { // generate random distance, angle of new circle from current point double angle = rand.nextDouble() * 2 * Math.PI; double distance = rand.nextDouble(); // generate the center of the new circle based on the angle, distance, and current point double centerX = point.x + distance * Math.cos(angle); double centerY = point.y + distance * Math.sin(angle); CanvasPoint circleCenter = new CanvasPoint(centerX, centerY); circlesForPoint.add(circleCenter); } // add all generated circles for a given point to HashMap circleCandidates.put(point, circlesForPoint); } // trim the list of circles to the minimum number that covers all points while (coveredPoints.size() < this.points.size()) { // find the current circle that covers most points CanvasPoint bestCircle = null; int maxCover = 0; // for every proposed circle... for (Map.Entry<CanvasPoint, ArrayList<CanvasPoint>> entry : circleCandidates.entrySet()) { // ... track the number of points it covers... for (CanvasPoint candidateCenter : entry.getValue()) { // ... and update the number of new points it covers int coverCount = 0; for (CanvasPoint point : this.points) { if (!coveredPoints.contains(point) && _distance(candidateCenter, point) < 1.0f) { coverCount++; } } // track the circle found to cover the most points if (coverCount > maxCover) { maxCover = coverCount; bestCircle = candidateCenter; } } return centers; } // find the points covered by the selected circle // add the circle to the list to return and update the points that are covered if (bestCircle != null) { selectedCircles.add(bestCircle); // Add the center of the selected circle to the list for (CanvasPoint point : this.points) { if (_distance(bestCircle, point) < 1.0f && !coveredPoints.contains(point)) { coveredPoints.add(point); } } } // exit if no new circle was found else { break; } } return selectedCircles; } private double _distance(CanvasPoint pnt1, CanvasPoint pnt2) { return Math.sqrt( Math.pow(pnt1.x - pnt2.x,2) + Math.pow(pnt1.y - pnt2.y,2) ); } //FIELDS private final Random rand = new Random(); } Loading
src/edu/bu/ec504/hw3/p2/MyCanvas.java +83 −6 Original line number Diff line number Diff line // referencing: https://stackoverflow.com/questions/15882202/minimum-number-of-circles-with-radius-r-to-cover-n-points package edu.bu.ec504.hw3.p2; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Random; public class MyCanvas extends Canvas { Loading @@ -17,12 +22,84 @@ public class MyCanvas extends Canvas { @Override public ArrayList<CanvasPoint> generateCovering() { // This demo implementation generates a trivial covering, where there is // a circle around each point. ArrayList<CanvasPoint> centers = new ArrayList<>(); for (CanvasPoint pnt: this) { centers.add(new CanvasPoint(pnt.x, pnt.y)); ArrayList<CanvasPoint> coveredPoints = new ArrayList<>(); ArrayList<CanvasPoint> selectedCircles = new ArrayList<>(); Map<CanvasPoint, ArrayList<CanvasPoint>> circleCandidates = new HashMap<>(); // generate 10 circles for each point whose center is within a radius distance from the point for (CanvasPoint point : this) { // store generated circles in list ArrayList<CanvasPoint> circlesForPoint = new ArrayList<>(); for (int i = 0; i < 10; i++) { // generate random distance, angle of new circle from current point double angle = rand.nextDouble() * 2 * Math.PI; double distance = rand.nextDouble(); // generate the center of the new circle based on the angle, distance, and current point double centerX = point.x + distance * Math.cos(angle); double centerY = point.y + distance * Math.sin(angle); CanvasPoint circleCenter = new CanvasPoint(centerX, centerY); circlesForPoint.add(circleCenter); } // add all generated circles for a given point to HashMap circleCandidates.put(point, circlesForPoint); } // trim the list of circles to the minimum number that covers all points while (coveredPoints.size() < this.points.size()) { // find the current circle that covers most points CanvasPoint bestCircle = null; int maxCover = 0; // for every proposed circle... for (Map.Entry<CanvasPoint, ArrayList<CanvasPoint>> entry : circleCandidates.entrySet()) { // ... track the number of points it covers... for (CanvasPoint candidateCenter : entry.getValue()) { // ... and update the number of new points it covers int coverCount = 0; for (CanvasPoint point : this.points) { if (!coveredPoints.contains(point) && _distance(candidateCenter, point) < 1.0f) { coverCount++; } } // track the circle found to cover the most points if (coverCount > maxCover) { maxCover = coverCount; bestCircle = candidateCenter; } } return centers; } // find the points covered by the selected circle // add the circle to the list to return and update the points that are covered if (bestCircle != null) { selectedCircles.add(bestCircle); // Add the center of the selected circle to the list for (CanvasPoint point : this.points) { if (_distance(bestCircle, point) < 1.0f && !coveredPoints.contains(point)) { coveredPoints.add(point); } } } // exit if no new circle was found else { break; } } return selectedCircles; } private double _distance(CanvasPoint pnt1, CanvasPoint pnt2) { return Math.sqrt( Math.pow(pnt1.x - pnt2.x,2) + Math.pow(pnt1.y - pnt2.y,2) ); } //FIELDS private final Random rand = new Random(); }