在数组中查找N个非邻居元素,以便求和最大

时间:2018-04-04 22:36:13

标签: java arrays eclipse

我有一个代表一个区域的二维数组(int [] [])。每个点中的整数代表相同的值。

目标是在2d数组中选取N个点,使其值的总和为最大值。还有一个额外的难点是无法选择两个站在一起的点,所以如果你选择一个,那么8个空间就会被禁止。

Here's an example for a given map with N=5

以下是我计划如何构建它的方法:

public static int[][] getBestPoints(int[][] matrix, int N) {
    int[][] bestPoints = []; //the best option picked from the candidates
    Map<Int,int[][]> candidates = new HashMap<Int, int[]>{};

    //candidates is a map that stores the possition of N elements and the 
    //total sum of their represented values

   //Here there'd be a loop section that searchs for all the best 
   //combinations and stores them in the var candidates

    return bestPoints; //solution for the example picture {{1,3},{1,5},{2,1},{4,2},{5,4}}

}

关于从哪里开始的任何想法?提前谢谢!

1 个答案:

答案 0 :(得分:0)

这些矩阵中的每个单元格都可以存储在这样的类中:

import java.util.Comparator;

public class Cell {

private int row;
private int column;
private Integer value;
private Integer cost;

public static final Comparator<Cell> SUM_COMPARATOR = (Cell c1, Cell c2) -> c1.getSum().compareTo(c2.getSum());

@Override
public int hashCode() {
    int hash = 7;
    hash = 71 * hash + this.row;
    hash = 71 * hash + this.column;
    return hash;
}

@Override
public boolean equals(Object obj) {
    if (this == obj) {
        return true;
    }
    if (obj == null) {
        return false;
    }
    if (getClass() != obj.getClass()) {
        return false;
    }
    final Cell other = (Cell) obj;
    if (this.row != other.row) {
        return false;
    }
    if (this.column != other.column) {
        return false;
    }
    return true;
}

public int getRow() {
    return row;
}

public void setRow(int row) {
    this.row = row;
}

public int getColumn() {
    return column;
}

public void setColumn(int column) {
    this.column = column;
}

public Integer getValue() {
    return value;
}

public void setValue(Integer value) {
    this.value = value;
}

public Integer getCost() {
    return cost;
}

public void setCost(Integer cost) {
    this.cost = cost;
}

public Integer getSum() {
    return cost+value;
}
}

上面的Cell类存储成本和值,然后List包含两个矩阵的信息。使用Collections.sort()(和Collections.reverse())使用在类Cell中实现的SUM_COMPARATOR对它们进行排序,该类比较成本和值的总和。迭代已排序的元素并将它们进行距离检查,如下所示:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test {

private static final int NUMBER_OF_CELLS_AROUND_EXCLUDED = 1;

public static void main(String[] args){

    List<Cell> cells = new ArrayList<>();

    // load prices and values in each Cell instance here...

    // and sort them
    Collections.sort(cells, Cell.SUM_COMPARATOR);
    Collections.reverse(cells);

    // then iterate both lists, which contain the
    List<Cell> chosen = new ArrayList<>();
    for (Cell cell : cells){
        if (notTooClose(cell, chosen.get((chosen.size()-1)))){
            chosen.add(cell);
        }
        if (chosen.size() == 5)
            break;
    }
}

private static boolean notTooClose(Cell cellA, Cell cellB){
    int rowDist = Math.abs(cellA.getRow()-cellB.getRow());
    int colDist = Math.abs(cellA.getColumn()-cellB.getColumn());

    return rowDist > NUMBER_OF_CELLS_AROUND_EXCLUDED && 
           colDist > NUMBER_OF_CELLS_AROUND_EXCLUDED;
}
}