gpt4 book ai didi

java - 如何使用不相交的集合来实现迷宫?

转载 作者:行者123 更新时间:2023-11-30 11:05:23 25 4
gpt4 key购买 nike

这是我使用的 DisjointSet 类:

public class DisjointSet{
public DisjointSet(int size){
s = new int[size];
for(int i = 0; i < size; ++i){
s[i] = -1;
}
}

public void union(int el1, int el2){
int root1 = find(el1);
int root2 = find(el2);
if(root1 == root2){
return;
}

if(s[root2] < s[root1]){
s[root1] = root2;
}
else{
if(s[root1] == s[root2]){
--s[root1];
}
s[root2] = root1;
}
}

public int find(int x){
if(s[x] < 0){
return x;
}
else{
s[x] = find(s[x]);
return s[x];
}
}

private int[] s;
}

这是我的迷宫类:

public class Maze
{
public Vector<Wall> maze;
public Vector<Room> graph;
public Vector<Integer> path;

public int LASTROOM;
public int height;
public int width;
public Random generator;
public DisjointSet ds;

public int dsSize;

public Maze(int w, int h, int seed)
{
width = w;
height = h;
dsSize = width * height;

LASTROOM = dsSize-1;

// Maze initialization with all walls
maze = new Vector<Wall>();
for(int i = 0; i < height; ++i)
{
for(int j = 0; j < width; ++j)
{
if(i > 0)
maze.add(new Wall(j+i*height, j+(i-1)*height));

if(j > 0)
maze.add(new Wall(j+i*height, j-1+i*height));
}
}

// Creation of the graph topology of the maze
graph = new Vector<Room>();
for(int i = 0; i < dsSize; ++i)
graph.add(new Room(i));

// Sort the walls of random way
generator = new Random(seed);

for(int i = 0; i < maze.size(); ++i)
{
//TODO
}

// Initialization of related structures
ds = new DisjointSet(dsSize);
path = new Vector<Integer>();
}

public void generate()
{
//TODO
}

public void solve()
{
//TODO
}
}

长期以来,我一直在寻找一种方法来实现 generate()solve() 以及迷宫墙壁的随机排序,并且我似乎无法在 Internet 上找到任何算法或实现来执行此操作。

generate() 应该穿过迷宫变量中的置换墙,如果墙连接的两个部分(房间)不在同一组中,则将其销毁。该方法还应该在房间图中添加一条边(每个房间都有一个名为 paths 的邻接列表,并且 Room 类有一个变量 id标识每个图的顶点)。

solve() 应该解决迷宫路径并生成 Maze 类的 vector ,其中包含到达导出要经过的房间的顺序。第一个房间定位在 0,最后一个房间定位在 LASTROOM

注意:迷宫房间构造函数如下:

public Wall(int r1, int r2)
{
room1 = r1;
room2 = r2;
}

public Room(int i)
{
id = i;
distance = -1;
paths = new Vector<Integer>();
}

如果有人愿意推荐一个可以在 Java 中运行的实现,我将不胜感激,谢谢。

最佳答案

首先,我真的很喜欢迷宫的想法,并且一直在用 Java 开发一个类似的项目,生成 Torus Mazes .

要生成你的迷宫,你需要看这个关键句:

... each room has a list of adjacency named paths and the Room class has a variable id that identifies each graph's vertices

这告诉我们什么?它告诉我们我们需要的数据结构!当你处理这样的问题时;由边连接的相邻 vector ,毫无疑问,您将创建一个邻接表。

有几种不同的方法可以做到这一点,但到目前为止最简单的(在这种情况下可以说是最有效的)是创建一个链表数组。这是我创建的邻接表没有使用 Java 库中的内置结构,但如果您选择使用 LinkedList<>,则可以使用相同的逻辑内置。

/*
* The Node class creates individual elements that populate the
* List class. Contains indexes of the node's neighbors and their
* respective edge weights
*/
class Node {
public int top;
public int topWeight;
public int bottom;
public int bottomWeight;
public int left;
public int leftWeight;
public int right;
public int rightWeight;
public int numConnec;

// Default constructor, ititializes neghbors to -1 by default and edge
// weights to 0
Node () {
top = -1;
right = -1;
bottom = -1;
left = -1;
}
} // End Node class


/*
* The List class contains Nodes, which are linked to one another
* to create a Linked List. Used as an adjacency list in the
* UnionFind class
*/
class List {
public Node neighbors;

// Default constructor
List () {
neighbors = new Node ();
}

/**
* Generates valid edges for the node, also assigns a randomly generated weight to that edge
* @param i The row that the node exists on, used to generate outer-node edges
* @param j The index of the node in the maze from 0 to (2^p)^2 - 1
* @param twoP Represents the dimensions of the maze, used in calculating valid edges
* @param choice Randomly generated number to choose which edge to generate
* @param weight Randomly generated number to assign generated edge a weight
* @return If the assignment was done correctly, returns true. Else returns false.
*/
public boolean validEdges (int i, int j, int twoP, int choice, int weight) {
if (neighbors.numConnec < 4) {
// Top
if (choice == 0) {
neighbors.top = generateTop(i, j, twoP);
neighbors.topWeight = weight;
neighbors.numConnec++;
}

// Right
else if (choice == 1) {
neighbors.right = generateRight(i, j, twoP);
neighbors.rightWeight = weight;
neighbors.numConnec++;
}

// Bottom
else if (choice == 2) {
neighbors.bottom = generateBottom(i, j, twoP);
neighbors.bottomWeight = weight;
neighbors.numConnec++;
}

// Left
else if (choice == 3) {
neighbors.left = generateLeft(i, j, twoP);
neighbors.leftWeight = weight;
neighbors.numConnec++;
}
}
else {
return false;
}
return true;
}

public int generateTop (int i, int j, int twoP) {
int neighbor = 0;

// Set the top neighbor
if (i == 0) {
neighbor = j + twoP * (twoP + (-1));
}
else {
neighbor = j + (-twoP);
}
return neighbor;
}

public int generateRight (int i, int j, int twoP) {
int neighbor = 0;

// Set the right neighbor
if (j == twoP * (i + 1) + (-1)) {
neighbor = twoP * i;
}
else {
neighbor = j + 1;
}
return neighbor;
}

public int generateBottom (int i, int j, int twoP) {
int neighbor = 0;

// Set the bottom neighbor
if (i == twoP + (-1)) {
neighbor = j - twoP * (twoP + (-1));
}
else {
neighbor = j + twoP;
}
return neighbor;
}

public int generateLeft (int i, int j, int twoP) {
int neighbor = 0;

// Set the left neighbor
if (j == twoP * i) {
neighbor = twoP * (i + 1) + (-1);
}
else {
neighbor = j + (-1);
}
return neighbor;
}
} // End List class

解决迷宫,这听起来像是实现 Dijkstra 算法可以解决的问题。

Dijkstra 的工作原理是从您的第一个节点开始创建已知集。然后,您确定到下一条边的最短路径并将该节点添加到已知集。每次寻找下一条最短路径时,都会加上从第一个节点经过的距离。

这个过程一直持续到所有节点都在已知集合中并且计算出到达目标的最短路径。
enter image description here
Shortest Paths

关于java - 如何使用不相交的集合来实现迷宫?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29660327/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com