Je cherche un bon algorithme pour le problème suivant: Étant donné une grille 3D de voxels (qui peut être vide ou remplie), si je choisis deux voxels non adjacents, je veux savoir s'ils sont connectés les uns aux autres par d'autres voxels.
Par exemple (pour illustrer la situation en 2D), où # est un carré rempli:
1 2 3
a # # #
b # #
c # # #
Si je choisis a3 et c3, je veux déterminer le plus rapidement possible s'ils sont connectés; s'il y a un chemin entre a3 et c3 à travers des pixels pleins. (La situation réelle est dans une grille de voxels 3D, bien sûr.)
J'ai regardé les algorithmes de remplissage et les algorithmes de recherche de chemin, mais je ne sais pas lequel choisir. Les deux font un travail inutile: le remplissage par inondation essaie de remplir tous les voxels, mais ce n'est pas nécessaire. Les algorithmes de recherche de chemin visent généralement à trouver le chemin le plus court, ce qui n'est pas non plus nécessaire. Je ne ai besoin de savoir s'il est un chemin.
Quel algorithme dois-je utiliser?
Edit: sur la base des commentaires, je pense qu'il faudrait ajouter ce qui suit: le contenu des voxels n'est pas connu à l'avance, et aussi, l'algorithme est nécessaire pour détecter si la suppression (le vidage) d'un voxel entraînerait la rupture du groupe de voxels en deux ou plusieurs petits groupes.
la source
c3->c2->b2->a2->a3
:?Réponses:
Un * fonctionnerait très bien. La recherche de chemin est ce que vous voulez, trouver le chemin le plus court est tout aussi rapide (ou plus rapide) que de trouver n'importe quel chemin. Dans cette situation, A * est probablement le plus approprié étant donné que vous avez un point de départ et un point d'arrivée. cela signifie que vous avez l'heuristique ajoutée pour accélérer la recherche.
Avec A *, le premier chemin que vous trouvez est généralement le plus court, il ne fait donc pas de travail supplémentaire après avoir déjà trouvé un chemin.
Pour quelques optimisations, consultez ma réponse ici .
la source
Si vous êtes prêt à effectuer un prétraitement et à consommer le coût de stockage, alors le partitionnement des voxels en groupes connectés au moment de la construction donne une réponse évidente à `` y a-t-il un chemin du tout ''. Il y a un chemin entre deux voxels s'ils sont dans le même groupe. Le problème avec cela est évidemment que vous devez stocker des informations de groupe quelque part, et cela dépend de la disposition de vos données. Si vous stockez une liste simple, vous pouvez simplement la diviser en plusieurs listes, une pour chaque groupe connecté spatialement. Si vous vous organisez dans une sorte de BVH, alors vous pourriez probablement obtenir des efficacités raisonnablement bonnes si vous pouvez dire "tous les voxels dans ce nœud et ci-dessous appartiennent au groupe X".
Alternativement, vous pouvez effectuer une pré-partitionnement spatial et stocker un ensemble plus petit de voxels «concentrateurs» pour chaque groupe connecté. Ensuite, vous pouvez rechercher un chemin à partir de vos voxels source et cible vers leur voxel concentrateur le plus proche, ce qui devrait être beaucoup plus court / moins cher à calculer. Si vous pouvez trouver un chemin d'un voxel à un voxel concentrateur, alors le voxel fait partie du groupe du voxel concentrateur. Avec une sélection intelligente de ces voxels de concentrateur, vous pouvez minimiser le nombre de traversées de chemin. Par exemple, une sphère peut avoir un seul voxel central en son centre, mais un groupe long et mince peut avoir un voxel central tous les X voxels sur sa longueur. Si vos voxels source et cible se trouvent à l'une ou l'autre extrémité de la longueur, ils n'ont qu'à parcourir au plus X voxels pour trouver un concentrateur, et même s'il peut y avoir un grand nombre de voxels entre le début et la fin de la longueur,
Tout dépend de la pathologie de vos groupes de voxels: si vous vous attendez à un grand nombre de petits groupes déconnectés, l'augmentation des coûts de stockage va largement contrebalancer les performances de la recherche de chemins. Si vous vous attendez à relativement peu de groupes connectés mais à des topologies étranges, la recherche de chemin naïve peut être extrêmement coûteuse et le coût de stockage et la recherche de chemin minimale sont une option beaucoup moins chère.
la source
Je ne connais pas très bien les voxels, mais j'imagine que vous pourriez obtenir de très bonnes performances en utilisant un algorithme de recherche de premier ordre tel que A *. Le problème avec l'utilisation de A * dans ce cas est que l'heuristique que l'on utiliserait normalement est conçue pour prioriser la recherche du chemin le plus court et pas seulement de «n'importe quel chemin» aussi rapidement que possible.
Vous pouvez avoir de la chance en utilisant une autre heuristique qui étend moins de nœuds tels que
f (p) = g (p) + w (p) * h (p)
où w> = 1. vous diminuez la valeur de «w» plus vous vous rapprochez de l'objectif, donnant ainsi une priorité plus élevée au coût du chemin «g» plus vous vous rapprochez du voxel que vous recherchez.
J'espère que ça aide!
la source