Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 求两个随机节点间路径的递归公式的优化_Algorithm - Fatal编程技术网

Algorithm 求两个随机节点间路径的递归公式的优化

Algorithm 求两个随机节点间路径的递归公式的优化,algorithm,Algorithm,我已经编写了一个递归公式,可以在网格模式中排列的两个节点之间找到路径。我的代码有两个问题。第一个问题是,有时开始节点的位置会从一个数字更改为另一个数字,但我通过在递归之后重新分配它来解决这个问题,所以这没什么大不了的。第二个问题是它的运行速度慢得令人无法忍受。生成5x5大约需要30秒,但我还无法生成7x7,这是我的最终目标。我希望有人会看到,如果有任何优化,可以作出 如下所示,Node类有一个Key属性和一个Value属性。关键点是网格中从0开始的位置。因此,对于5x5,左上角节点的键为0,右下

我已经编写了一个递归公式,可以在网格模式中排列的两个节点之间找到路径。我的代码有两个问题。第一个问题是,有时开始节点的位置会从一个数字更改为另一个数字,但我通过在递归之后重新分配它来解决这个问题,所以这没什么大不了的。第二个问题是它的运行速度慢得令人无法忍受。生成5x5大约需要30秒,但我还无法生成7x7,这是我的最终目标。我希望有人会看到,如果有任何优化,可以作出

如下所示,Node类有一个Key属性和一个Value属性。关键点是网格中从0开始的位置。因此,对于5x5,左上角节点的键为0,右下角节点的键为24。每个节点都具有上、下、左和右属性,这些属性是它连接到的其他节点。当该方向上没有节点时,该值为null。例如,在5x5中,Key=0的节点的Up为null,Key=5的节点的Down为null,Key=1的节点的Left为null,Right为null。作为另一个示例,仍然在5x5中,键为6的节点将具有键为1的节点的向上部分、键为11的节点的向下部分、键为5的节点的左侧以及键为7的节点的右侧。Position属性是路径。路径从位置为1的节点开始,然后到达位置为2的节点,以此类推,直到到达末端节点,即NxN板上的位置N*N(例如,5x5板的末端节点位置为25)。这些节点被添加到名为nodeList(一个全局变量)的列表中。其中一个节点被随机标记为Start-(boolean),另一个节点被随机指定为End-(boolean)


下一部分是路径。我们希望在开始节点和结束节点之间找到一条随机路径(从1开始),该路径每接触一个节点,而不接触同一节点两次。这是一个游戏,所以重要的是它是随机的,这样用户就不会玩同一个棋盘两次。如果给定起始位置和结束位置,这是不可能的,则选择新的起始位置和结束位置,并再次运行算法

class Node
{
    public int Key { get; set; }
    public int? Position { get; set; } = null;
    public Node Up { get; set; } = null;
    public Node Down { get; set; } = null;
    public Node Left { get; set; } = null;
    public Node Right { get; set; } = null;
    public bool Start = false;
    public bool End = false;

    public Node(int key)
    {
        Key = key;
    }
}


public bool GeneratePath()
    {
        var current = nodeList.Where(w => w.Start).FirstOrDefault();
        var start = current;
        int position = 1;

        bool Recurse(Node caller)
        {
            if (current.Position == null)
            {
                current.Position = position;
            }
            if (current.End)
            {
                return true;
            }               


            var directions = GetDirections();

            for (var i = 0; i < 4; i++)
            {
                var done = false;
                if (directions[i] == 0 && current.Up != null && current.Up.Position == null
                    && (!current.Up.End || position == n * n - 1))
                {
                    var temp = current;
                    current = current.Up;
                    position++;
                    done = Recurse(temp);
                }
                else if (directions[i] == 1 && current.Down != null && current.Down.Position == null 
                    && (!current.Down.End || position == n * n - 1))
                {
                    var temp = current;
                    current = current.Down;
                    position++;
                    done = Recurse(temp);
                }
                else if (directions[i] == 2 && current.Left != null && current.Left.Position == null 
                    && (!current.Left.End || position == n * n - 1))
                {
                    var temp = current;
                    current = current.Left;
                    position++;
                    done = Recurse(temp);
                }
                else if (directions[i] == 3 && current.Right != null && current.Right.Position == null 
                    && (!current.Right.End || position == n*n - 1))
                {
                    var temp = current;
                    current = current.Right;
                    position++;
                    done = Recurse(temp);
                }
                if(done)
                {
                    return true;
                }
            }


            current.Position = null;
            position--;

            if(caller == null)
            {
                return false;
            }

            current = caller;

            return false;
        }

        var success = Recurse(null);

        if (success)
        {
            start.Position = 1;
        }

        return success;
    }



private int[] GetDirections()
    {
        List<int> toPerm = new List<int>();
        for (var i = 0; i < 4; i++)
        {
            toPerm.Add(i);
        }

        Random random = new Random();
        var perms = HelperMethods.GetPermutations(toPerm, toPerm.Count);
        var randomNumber = random.Next(0, perms.Count());
        var directions = perms.ElementAt(randomNumber).ToArray();

        return directions;

    }



public static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> list, int length)
    {
        if (length == 1) return list.Select(t => new T[] { t });
        return GetPermutations(list, length - 1)
            .SelectMany(t => list.Where(o => !t.Contains(o)),
                (t1, t2) => t1.Concat(new T[] { t2 }));
    }
类节点
{
公共int密钥{get;set;}
公共int?位置{get;set;}=null;
公共节点Up{get;set;}=null;
公共节点向下{get;set;}=null;
公共节点左{get;set;}=null;
公共节点权限{get;set;}=null;
公共bool Start=false;
公共bool End=false;
公共节点(int键)
{
钥匙=钥匙;
}
}
公共布尔生成路径()
{
var current=nodeList.Where(w=>w.Start).FirstOrDefault();
无功启动=电流;
int位置=1;
布尔递归(节点调用方)
{
if(current.Position==null)
{
当前位置=位置;
}
如果(当前结束)
{
返回true;
}               
var directions=GetDirections();
对于(变量i=0;i<4;i++)
{
var done=false;
如果(方向[i]==0&¤t.Up!=null&¤t.Up.Position==null
&&(!current.Up.End | | position==n*n-1))
{
var温度=电流;
电流=电流。上升;
位置++;
完成=递归(临时);
}
如果(方向[i]==1&¤t.Down!=null&¤t.Down.Position==null),则为else
&&(!current.Down.End | | position==n*n-1))
{
var温度=电流;
电流=电流下降;
位置++;
完成=递归(临时);
}
如果(方向[i]==2&¤t.Left!=null&¤t.Left.Position==null),则为else
&&(!current.Left.End | | position==n*n-1))
{
var温度=电流;
电流=电流。左;
位置++;
完成=递归(临时);
}
如果(方向[i]==3&¤t.Right!=null&¤t.Right.Position==null),则为else
&&(!current.Right.End | | position==n*n-1))
{
var温度=电流;
电流=电流。右;
位置++;
完成=递归(临时);
}
如果(完成)
{
返回true;
}
}
当前位置=空;
位置--;
if(调用者==null)
{
返回false;
}
当前=呼叫方;
返回false;
}
var success=Recurse(null);
如果(成功)
{
起始位置=1;
}
回归成功;
}
私有int[]GetDirections()
{
List toPerm=新列表();
对于(变量i=0;i<4;i++)
{
toPerm.添加(i);
}
随机=新随机();
var perms=HelperMethods.GetPermutations(toPerm,toPerm.Count);
var randomNumber=random.Next(0,perms.Count());
var directions=perms.ElementAt(randomNumber.ToArray();
返回方向;
}
公共静态IEnumerable GetPermutations(IEnumerable列表,int-length)
{
if(length==1)返回列表。选择(t=>newt[]{t});
返回GetPermutations(列表,长度-1)
.SelectMany(t=>list.Where(o=>!t.Contains(o)),
(t1,t2)=>t1.Concat(新的T[]{t2});
}

重申一下,我想知道我是否可以做一些优化,因为它对我来说太慢了。

所以我找到了一个