Как я узнаю, что у моей вершины есть связь?
Я делаю игру "Охота на Wumpus", используя структуру данных графа. Каждая вершина в нем представляет собой массив размером 4, представляющий каждое направление: север, юг, восток, запад. Направления хранятся в перечислении. Когда одна вершина связана с другой, предполагается, что ее смежность изменяется таким образом, что она соединяется с другой вершиной (я все еще не понимаю, почему моя вершина является массивом размера 4, но имеет только одно направление).
Когда я соединяю одну вершину с другой и распечатываю массив соседей, я получаю странный вывод. Когда я печатаю несвязанную вершину, я получаю [null, null, null, null] для соседей; когда я печатаю связанную вершину, я получаю [ноль, нуль, ноль, [ноль, ноль, ноль, ноль]. Я не знаю, какими должны быть соседи - должны ли они печатать в виде целых чисел, представляющих индекс перечисления направления или направление? Что должно быть распечатано?
import java.util.ArrayList;
import java.util.Collection;
enum Direction{
EAST,
WEST,
NORTH,
SOUTH
}
public class Vertex extends Agent implements Comparable<Vertex>{
private Vertex[] connections;
private Direction dir;
private int cost;
private boolean marked;
public Vertex(double x0, double y0){
super( x0, y0);
connections = new Vertex[4];
this.dir = dir;
this.cost = cost;
this.marked = marked;
}
public Direction opposite(Direction dir) {
//that returns the compass opposite of a direction (i.e. South for North...)
if(dir == Direction.EAST){
dir = Direction.WEST;
}
else if(dir == Direction.WEST){
dir = Direction.EAST;
}
else if(dir == Direction.NORTH){
dir = Direction.SOUTH;
}
else dir = Direction.NORTH;
return dir;
}
void connect(Vertex other, Direction dir){
//modify the object's adjacency list/map so that it connects with the other Vertex. This is a uni-directional link.
connections[dir.ordinal()] = other;
}
Vertex getNeighbor(Direction dir){
//returns the Vertex in the specified direction or null.
return this.connections[dir.ordinal()];
}
Collection getNeighbors(){
//returns a Collection, which could be an ArrayList, of all of the object's neighbors.
ArrayList<Vertex> neighborList = new ArrayList<Vertex>();
for (Direction dir: Direction.values()){
neighborList.add(this.getNeighbor(dir));
}
return neighborList;
}
public int getCost(){
return this.cost;
}
public int setCost(int c){
return this.cost = c;
}
public boolean getMarked(){
return this.marked;
}
public boolean setMarked(boolean m){
return this.marked = m;
}
public int compareTo(Vertex other){
return (this.cost - other.cost);
}
/*
* returns a string containing the number of neighbors, the cost, and the marked flag
*/
public String toString(){
String s = "";
s += this.getNeighbors() + "\n" ;
s += "cost: " + this.cost + "\n";
s += "marked: " + this.marked;
return s;
}
public static void main (String args[]){
Vertex newE = new Vertex(0.5, 0.5);
Vertex newerE = new Vertex(0.123, 1.56);
newE.connect(newerE, Direction.SOUTH);
newE.setCost(1);
newE.setMarked(true);
System.out.println(newE.toString());
}
}
1 ответ
Что ж, когда вы получаете вывод [null, null, null, [null, null, null, null]], вы знаете, что есть ссылка на ваш подключенный узел. Таким образом, второй массив связан с первым, но не наоборот. Поскольку ваш код не соединяет второй узел, а первый связан. Я думаю, что вы не должны печатать список узлов, это приведет к проблемам.
В одном случае узлы соединены вместе, поэтому родительский элемент подключен к дочернему элементу, а дочерний элемент - к родительскому. Когда вы сейчас распечатаете это, вы получите рекурсивное выполнение.
[null, null, null, child [parent [[null, null, null, child [...]]], null, null, null]]
Это приведет к исключению. Вы можете использовать идентификатор для этого, как идентификатор. Таким образом, вы просто распечатываете идентификатор для связанных объектов или, возможно, позицию ->
[1, NULL, NULL, 2]
[(Х, у),(х, у),(х, у),(х, у)]
Просто используйте что-то, чтобы идентифицировать узлы, после этого вы можете легко увидеть, существует ли узел или нет.
Итак, еще один момент, что вы знаете, что у вас есть 4 точки для подключения, так почему бы не использовать:
private Node north;
private Node south;
private Node west;
private Node east;
Это будет легче в дальнейшем, и вам больше не придется использовать это перечисление. И вы также можете удалить направление в классе Vertex, кстати, это также сбивает с толку Vertex - это точка, а точки не имеют направления:)
Или вы просто используете 2x2 Grid для этого, например:
private Node[][]
Вы можете указать размер сетки через позиции, которые вы знаете, где получить доступ к соседу. Например, координата [1,1] связана с помощью [0,1],[1,0],[2,1],[1,2]. И вы также можете легко распечатать всю сетку.
Вы можете поместить этот расчет в алгоритм, чтобы проверить соседей. Таким образом, вам не нужно сохранять узлы в каждом классе узлов. Положение рендеринга, которое вы можете получить, например, используя этот объект (просто если вы хотите его отрендерить):
node[1][2].getX();
И я также предлагаю вам взглянуть на древовидные структуры:)