Java 如何使用不相交集实现迷宫?
下面是我使用的DisjointSet类:Java 如何使用不相交集实现迷宫?,java,maze,disjoint-sets,Java,Maze,Disjoint Sets,下面是我使用的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 =
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;
}
公共类分离集{
公共分隔集(整数大小){
s=新整数[大小];
对于(int i=0;i
这是我的迷宫课:
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
}
}
公共类迷宫
{
公共媒介迷宫;
公共向量图;
公共向量路径;
公共休息室;
公众内部高度;
公共整数宽度;
公共随机发生器;
公共断开;
公共设施规模;
公共迷宫(整数w、整数h、整数种子)
{
宽度=w;
高度=h;
dsSize=宽度*高度;
LASTROOM=dsSize-1;
//所有墙壁的迷宫初始化
迷宫=新向量();
对于(int i=0;i0)
添加(新墙(j+i*高度,j+(i-1)*高度));
如果(j>0)
添加(新墙(j+i*高度,j-1+i*高度));
}
}
//迷宫图拓扑的创建
图形=新向量();
对于(int i=0;i
很长一段时间以来,我一直在寻找一种实现generate()和solve()以及迷宫墙壁随机排序的方法,而我似乎在互联网上找不到任何算法或实现来实现这一点
generate()应该通过maze变量中的排列墙,如果由墙连接的两个部分(房间)不在同一集中,则销毁它。该方法还应该在房间图中添加一条边(每个房间都有一个邻接命名路径的列表,房间类有一个标识每个图形顶点的变量id)
solve()应求解迷宫路径,并生成迷宫类的向量,该向量包含到达出口的房间顺序。第一个房间的位置为0,最后一个房间的位置为LASTROOM
注:迷宫及房间施工人员如下:
public Wall(int r1, int r2)
{
room1 = r1;
room2 = r2;
}
public Room(int i)
{
id = i;
distance = -1;
paths = new Vector<Integer>();
}
公共墙(内部r1、内部r2)
{
房间1=r1;
房间2=r2;
}
公共房间(内部一)
{
id=i;
距离=-1;
路径=新向量();
}
如果有人能提出一个能在Java中工作的实现,我将不胜感激,谢谢 首先,我真的很喜欢迷宫的概念,并且一直在用Java开发一个类似的项目,其中包括生成 要生成迷宫,您需要查看以下关键句子: 。。。每个房间都有一个命名为路径的邻接列表,房间类有一个标识每个图形顶点的变量id 这告诉我们什么?它告诉我们所需的数据结构处理此类问题时;通过边连接的相邻向量,您无疑将创建一个邻接列表。
有几种不同的方法可以做到这一点,但到目前为止,最简单的方法(在本例中可以说是最有效的方法)是创建一个链表数组。这是我创建的一个邻接列表,没有使用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
/*
*Node类创建填充节点的单个元素
*列一个班级。包含节点的邻居及其邻居的索引
*各自的边权重
*/
类节点{
公共int top;
公共重量;
公共int底部;
公众体重;
公共int左;
公共体重;
公共权利;
公权力;
国际公共航空公司;
//默认构造函数,在默认情况下将负边界初始化为-1,并使用edge
//权重为0
节点(){
top=-1;
右=-1;
底部=-1;
左=-1;
}
}//结束节点类
/*
*List类包含相互链接的节点
*创建链接列表。在中用作邻接列表
*联合查找类
*/
班级名单{
公共节点邻居;
//默认构造函数
列表(){
邻居=新节点();
}
/**
*为节点生成有效边,并为该边指定随机生成的权重
*@param i节点所在的行,用于生成外部节点边
*@param j迷宫中节点的索引从0到(2^p)^2-1
*@param twoP表示迷宫的尺寸,用于计算有效边
*@param choice随机生成的数字,用于选择要生成的边
*@param weight随机生成的数字,用于为生成的边分配权重
*@return如果赋值正确,则返回true;否则返回false。
*/
公共布尔有效值(int i,int j,int twoP,int choice,int weight){
if(neights.numConnec<4){
//顶
如果(选择)