我必须使用算法来查找学校项目的路径。我在地图上有一系列12个目标,必须在路径结束之前到达。地图是70x70阵列。我已经做了什么:
目标用数字10到21标记,我列在0到12的列表中。(21是最后一个目标)
private casa[] acharCasas(){
casa[] casas = new casa[12];
for (int linha = 0; linha < jogo.getMapa().length; linha++) {
for (int coluna = 0; coluna < jogo.getMapa()[0].length; coluna++) {
if(jogo.getMapa()[linha][coluna] >= 10 && jogo.getMapa()[linha][coluna] <= 21){
casas[jogo.getMapa()[linha][coluna]-10] = new casa (linha,coluna);
}
}
}
return casas;
}
casas_visitadas
是已访问目标的数量,posL = row
,posC = Col
。我想做的是计算你到达下一个未完成目标的距离,+从这个目标到下一个目标的距离......到最终目标。
public double distanciaDasOutrasCasas(){
double somaTotal = 0;
int posL = linha,posC = coluna;
for (int i = casas_visitadas; i < 12; i++) {
somaTotal += Math.sqrt(
Math.pow( (double) (casas[i].linha - posL),2) +
Math.pow( (double) (casas[i].coluna - posC),2)
);
posL = casas[i].linha;
posC = casas[i].coluna;
}
return somaTotal;
}
我将它们添加到ArrayList中。以下是构造函数:
public ArrayList<Direcao> movimentosPossiveis(){
ArrayList<Direcao> movimentos = new ArrayList<>();
if (linha > 0) movimentos.add(Direcao.CIMA); // if isnt the first row add UP
if (coluna > 0) movimentos.add(Direcao.ESQUERDA);//if inst the first col add LEFT
if (linha < jogo.getMapa().length) movimentos.add(Direcao.BAIXO); // last row add down
if (coluna < jogo.getMapa()[linha].length) movimentos.add(Direcao.DIREITA); // add right
return movimentos;
}
public ArrayList<cell> permutaCelula(){
ArrayList<Direcao> movimentos = movimentosPossiveis();
ArrayList<cell> novasCelulas = new ArrayList<>();
for (Iterator<Direcao> iterator = movimentos.iterator(); iterator.hasNext();) {
Direcao D = iterator.next();
switch (D){
case CIMA:
novasCelulas.add(
new cell(this /*father*/, Direcao.CIMA /*direction from father */, custo_total /*total cost*/, linha-1/*row-1*/, coluna/*col*/, casas_visitadas/*goals visiteds*/)
);
break;
case BAIXO:
novasCelulas.add(
new cell(this, Direcao.CIMA, custo_total, linha+1, coluna, casas_visitadas)
);
break;
case ESQUERDA:
novasCelulas.add(
new cell(this, Direcao.CIMA, custo_total, linha, coluna-1, casas_visitadas)
);
break;
case DIREITA:
novasCelulas.add(
new cell(this, Direcao.CIMA, custo_total, linha, coluna+1, casas_visitadas)
);
break;
}
}
return novasCelulas;
}
public double convertePesoDoChao(){
System.out.println(" L " + this.linha + " Coluna "+ coluna);
int chao = jogo.getMapa()[this.linha][this.coluna];
switch (chao) {
case 0:
return 200; //rock field, slowest field
case 1:
return 1;
case 2:
return 3.5;
case 3:
return 5;
case 22:
if(quantidadeDeCavaleirosVivos() != 0) return Double.MAX_VALUE; // cant go to master without find all goals
finalizado = true; // found
caminhoFinal = converteCelulaParaMovimentos(); // converts cells movements
return 0;
default:
casas_visitadas++;
return 0;
}
}
public cell(cell pai, Direcao oPaiMexeuPraQualDirecao, double custo_total, int linha, int coluna, int casas_visitadas) {
this.pai = pai; // father
this.oPaiMexeuPraQualDirecao = oPaiMexeuPraQualDirecao; // direction from father
this.linha = linha; //row
this.coluna = coluna; // col
this.casas_visitadas = casas_visitadas; //goals visited
this.custo_total = custo_total + convertePesoDoChao(); // fathers total cost + field cost
}
public cell(int linha, int coluna) { //starter cell
this.linha = linha;
this.coluna = coluna;
this.custo_total = 0;
this.pai = null;
}
我的启发式是总费用+距离目标
public double heuristica(){
return custo_total *10 + distanciaDasOutrasCasas();
}
if(!finalizado){
this.jogo = jogo;
colunaInicial = jogo.getColuna();
linhaInicial = jogo.getLinha();
casas = acharCasas();
ArrayList<cell> franja = new ArrayList<>();
franja.add(new cell(linhaInicial,colunaInicial));
while(!finalizado){
Collections.sort(franja);
franja.addAll(franja.get(0).permutaCelula());
franja.remove(0);
}
}
总共花了三个多小时,花了太长时间才找到方法......任何提示?我检查了Netbeans分析器,问题是对数组进行排序。
我的完整代码is here
obs:在完整的代码上,游戏调用动作移动,在第一次调用时我需要找到最好的方法,并保存它,稍后我只是弹出一堆动作
obs2:对不起我的英文不好,我在某些部分使用谷歌翻译