简体   繁体   中英

Java 2D Minimization

I need help writing a program that is given a specified number of coordinate points in the form (X,Y). The number of points that will be given is the first line in the program; it can be read in through a scanner.

I need to calculate the least amount of area to cover all of the points with the lines x = a, and y = b. So, the area would be a * b (Area of a rectangle).

However, one coordinate point (X, Y) must be removed to optimize the area. The point that is removed should minimize the area as much as possible. I need help writing algorithm to do so.

This is a sample input, and output that I was given ::

SAMPLE INPUT

4

2 4

1 1

5 2

17 25

SAMPLE OUTPUT

12


In this example, the first line of input (4) indicates that four points will be input. The next four lines are the coordinates in form (x, y). The last point which is (17, 25) is removed as the outlier which leaves us with the first three points.

如果剩下的三个点都画了

If the three remaining points are graphed, they can all be inside a box (3 by 4) hence the output is 12; (3 * 4). It is OK for the line to be on the point like in this example. However, the outlier is not always the last point, or very big. The outlier could be very small, the area just needs to be minimized.

-- This is what I have so far (I know it's not very much..) - please help me!

It's mostly just the algorithm that I need help with..

import java.io.*;
import java.util.*;

public class Area {

    public static void main(String args[]) {

        Scanner scan = new Scanner(System.in);

        int numOfPoints = scan.nextInt();
        int Xcoordinates[] = new int[numOfPoints];
        int Ycoordinates[] = new int[numOfPoints];


        for (int i = 0; i <= numOfCows - 1; i++) {
            Xcoordinates[i] = scan.nextInt();
            Ycoordinates[i] = scan.nextInt();
        }

The bruteforce solution is of course to compute the area of every combination of points and select the minimum.

public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);

    int numOfPoints = scan.nextInt();
    int[][] points = new int[numOfPoints][2];

    for (int i = 0; i < numOfPoints; i++) {
        points[i][0] = scan.nextInt();
        points[i][1] = scan.nextInt();
    }

    // Testcase, comment everything above out.
    /*
     * int numOfPoints = 4; int[][] points = { { 2, 4 }, { 1, 1 }, { 5, 2 },
     * { 17, 25 } };
     */

    // As we try to minimize, we start with the biggest possible value.
    int minArea = Integer.MAX_VALUE;
    // We don't know which one to skip yet, so this value should be anything
    // *but* a valid value.
    int skippedPoint = -1;
    // Pretty straightforward. Check every point, get minimum
    for (int skipped = 0; skipped < numOfPoints; skipped++) {
        int area = calculateArea(points, skipped);
        if (area < minArea) {
            skippedPoint = skipped;
            minArea = area;
        }
    }

    System.out.println("The original area was " + calculateArea(points, -1) + " units big.");
    System.out.println("The minimized area is " + minArea + " units big.");
    System.out.println("This was reached by leaving the " + (skippedPoint + 1) + ". point (" + Arrays.toString(points[skippedPoint]) + ") out.");
}

/**
 * Implementation of Rajeev Singh's AABB-algorithm
 * 
 * @param points
 *            All points
 * @param skipped
 *            The point to skip
 * @return The area of the axis-aligned bounding box of all points without
 *         the specified point
 */
private static int calculateArea(int[][] points, int skipped) {
    // Initialize values with the opposite of the desired result, see
    // minimization-problem above.
    int max_x = Integer.MIN_VALUE, min_x = Integer.MAX_VALUE, max_y = Integer.MIN_VALUE, min_y = Integer.MAX_VALUE;

    for (int i = 0; i < points.length; i++) {
        if (i == skipped) {
            continue; // This is where the magic happens. Continue
                        // immediatly jumps to the start of the loop.
        }

        int[] point_i = points[i];
        if (point_i[0] > max_x) {
            max_x = point_i[0];
        }
        if (point_i[0] < min_x) {
            min_x = point_i[0];
        }

        if (point_i[1] > max_y) {
            max_y = point_i[1];
        }
        if (point_i[1] < min_y) {
            min_y = point_i[1];
        }
    }

    return (max_x - min_x) * (max_y * min_y);
}

You now have the minimal area and the point that has been left out.

Let you have 4 points (2 4), (1 1), (5 2), (17 25) . As you can always remove one point to optimize area hence,there are C(4,3) combinations possible of points,which are:

{ { (2 4), (1 1), (5 2) } , { (1 1), (5 2), (17 25) } , { (2 4), (5 2),(17 25) } , { (2 4),(1 1),(17 25) } }


Minimum area you can find for a set will be:

(Max(all x coordinates)-Min(all x coordinates)) * (Max(all y coordinates)-Min(all y coordinates))


  1. { (2 4), (1 1), (5 2) }

    Minimum area for this set is equal to (5-1)*(4-1) = 4*3 = 12

  2. { (1 1), (5 2), (17 25) }

    Minimum area you can find for this set will be: (17-1)*(25-1) = 16*24 = 384

  3. { (2 4), (5 2), (17 25) }

    Minimum area you can find for this set will be: (17-2)*(25-2) = 15*23 = 345

  4. { (2 4),(1 1),(17 25) }

    Minimum area you can find for this set will be: (17-1)*(25-1) = 16*24 = 384


Out of all the area for the set { (2 4), (1 1), (5 2) } is minimum which is equal to 12 ,so the required answer is 12 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM