0


我尝试使用 BFS 制作魔方求解器的目标。我知道它的所有排列方式可能会很慢。=P 这不是给学校的,以防有人想知道。

可能很容易解决的问题
每当我将加扰魔方的另一个状态放入其中时,queue<array>它只是一个浅拷贝,所以一旦添加了魔方的其他状态,队列中的先前状态实际上改变并与新的状态相匹配。换句话说,我如何确保内部的所有元素都queue<array>保持不变?

我已尝试修复此
https://stackoverflow.com/a/129395/984680
我基本上使用此代码在多维数据集从队列中出来时创建它的新副本,然后在之前创建另一个新副本我再次将其放入队列(处于不同状态)。下面的代码显示了在将新副本插入队列之前如何制作新副本。

    //make deep copy of ccube (char array)
    char[][][] newcube = DeepClone(ccube);
    buffer.Enqueue(new State(newcube, calg + face + " ")); //even though newcube gets put into array, it ends up changed after ccube changes

这是从队列前面拉出数组时所做的深度复制。

    ccube = DeepClone(buffer.Peek().cube);

即使我多次克隆该数组(有些东西告诉我不需要制作这么多副本),我添加的新状态仍然与旧状态相同。我知道这一点是因为队列中只有 2 个不同的元素,即使我每次都让立方体的所有面都以各种方式转动。

提前感谢任何能够提供帮助的人。

4

1 回答 1

0

问题是数组在 C# 中是可变的,即当您更改某个位置的元素时,您正在修改现有数组而不是生成新数组。

字符串在 C#中是不可变的,并且由于您已经将该多维数据集表示为 a char[][][],因此您可以利用这一事实。有界正交 3D 空间可双射 (1:1) 映射到有界 1D 空间,也就是说,您char[][][]可以映射到字符串(只要立方体的尺寸在立方体的生命周期内不变),因此将其与不变性相结合字符串,您可以轻松地深度克隆您的多维数据集。

public class Cube
{
    public int Width { get; private set; }
    public int Height { get; private set; }
    public int Depth { get; private set; } 

    private string _data;

    public Cube(int width, int height, int depth)
    {
        Width = width;
        Height = height;
        Depth = depth;
        _data = "".PadRight(Width*Height*Depth);
    }

    public char Get(int x, int y, int z)
    {
        return _data[(Width*Height*z) + (Width*y) + x];
    }

    public void Set(int x, int y, int z, char c)
    {
        var sb = new StringBuilder(_data);
        sb[(Width*Height*z) + (Width*y) + x] = c;
        _data = sb.ToString();
    }

    public Cube Clone()
    {
        return new Cube(Width, Height, Depth) { _data = this._data };
    }
}

每当您调用aCube.Clone()时,您都会得到一个与前一个完全无关的新立方体,因此您可以将其排入缓冲区等。

于 2013-06-09T21:26:30.300 回答