Я пытаюсь создать матрицу смежности из 2D-массива узлов. Матрица смежности будет передан в программу, будут группироваться узлы либо черезОптимизация создания матрицы смежности из 2D-массива узлов
- Спектральный алгоритм кластеризации
- алгоритм кластеризации Kmeans
** класса Node **
public class Node{
public int _id;
public bool _isWalkable;
public int _positionX;
public int _positionY;
public Vector3 _worldPosition;
}
Класс сетки
public class Grid : MonoBehaviour
{
void CreateGrid()
{
grid = new Node[_gridSizeX, _gridSizeY];
Vector3 worldBottomLeft = transform.position -
Vector3.right * worldSize.x/2 - Vector3.forward * worldSize.y/2;
//set the grid
int id = 0;
for (int x = 0; x < _gridSizeX; x++)
{
for (int y = 0; y < _gridSizeY; y++)
{
Vector3 worldPosition = worldBottomLeft + Vector3.right *
(x * _nodeDiameter + _nodeRadius) +
Vector3.forward * (y * _nodeDiameter + _nodeRadius);
//check to see if current position is walkable
bool isWalkable =
!Physics.CheckSphere(worldPosition, _nodeRadius, UnwalkableMask);
grid[x, y] = new Node(isWalkable, worldPosition, x, y);
grid[x, y].Id = id ++;
}
}
totalNodes = id;
}
}
Узлы хранятся внутри 2D-массива, называемого сеткой, и представляют собой путь, способный двигаться, чтобы персонаж мог двигаться дальше. Я успешно реализовал алгоритм A * с эвристикой эвклидовой дистанции. Я бы хотел, чтобы кластер этих узлов использовал вышеупомянутые алгоритмы кластеризации, но сначала мне нужно создать для них алгоритм смежности. Это лучший псевдокод я мог придумать
int[][] _adjacencyMatrix = new int[gridSizeX*gridSizeY][gridSizeX*gridSizeY];
for(int x = 0; x < gridSize;x< XgridSize; i++)
{
for(int y = 0; y < gridSize;y< YgridSize; i++)
{
if(!Grid[x][y]._isWalkable)
continue;
Node n = Grid[x][y];
List<Node> neighbors = GetNeighbors(n);
for(int k; k<neighbors.Count(); k++)
{
_adjacencyMatrix[n._id][neighbors[k]._id]=1;
}
}
}
public List<Node> GetNeighbours(Node n)
{
//where is this node in the grid?
List<Node> neighbours = new List<Node>();
//this will search in a 3X3 block
for (int x = -1; x <= 1; x++)
{
for (int y = -1; y <= 1; y++)
{
if (x == 0 && y == 0)
continue; //we're at the current node
int checkX = n._positionX + x;
int checkY = n._positionY + y;
if (checkX >= 0 && checkX < _gridSizeX && checkY >= 0
&& checkY < _gridSizeY)
{
if(grid[checkX, checkY]._isWalkable)
neighbours.Add(grid[checkX, checkY]);
else
continue;
}
}
}
return neighbours;
}
Моя главная забота
Моя главная забота с этим общая сложность алгоритма выше. Похоже, что это будет тяжело, и у меня есть в общей сложности (75^2 = 5625) узлов в матрице смежности, размер которой будет 5625X5625! Должен быть лучший способ найти соседей, чем это, не так ли?
Неужели вы не проверяете n.isWalkable() где-нибудь? –
kmeans не использует попарные расстояния. –