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