我有一个代表一个区域的二维数组(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}}
}
关于从哪里开始的任何想法?提前谢谢!
答案 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;
}
}