ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 彭希仁

[讨论] 求A点到B点之间最短的一条路线(看谁速度最快)

[复制链接]

TA的精华主题

TA的得分主题

发表于 2008-11-8 02:57 | 显示全部楼层
按照左下右的选择顺序,向小的方向走(左下右等于1的不算)

求最短距离.rar

13.46 KB, 下载次数: 39

TA的精华主题

TA的得分主题

发表于 2008-11-8 08:05 | 显示全部楼层
原帖由 彭希仁 于 2008-11-7 20:21 发表



我的解法是灌水法,30000行只需要3秒就可以搞定,


其中这二句花了2秒多钟

arr = Range("A1:AE" & .End(xlUp).Row)

..............
Range("A1:AE" & .End(xlUp).Row) = arr




彭版说的灌水算法是指的BFS 算法吗?
迫不及待想看下你的解答,学习一下。

TA的精华主题

TA的得分主题

发表于 2008-11-8 08:58 | 显示全部楼层
下面的内容在网上找的 希望对各位有帮助,,,我只想早点看到答案啊...

迷宫最短路径问题



 求两点路径是一个数据结构上的典型的迷宫问题,很多数据结构的书上都有介绍,解决办法如下:从一点开始出发,向四个方向查找,每走一步,把走过的点的值-1(即本节点值+1),防止重复行走,并把走过的点压入堆栈(表示路径),如果遇到墙、或者已走过的点则不能前进……
-1表示路,空白表示墙,求其中任意两点的最短路径。

求两点路径是一个数据结构上的典型的迷宫问题.

从一点开始出发,向四个方向查找,每走一步,把走过的点的值+1(即本节点值+1),防止重复行走,并把走过的点压入堆栈(表示路径),如果遇到墙、或者已走过的点则不能前进,如果前方已经无路可走,则返回,路径退栈,这样递归调用,直到找到终点为止。


如果我们调整调用offset的顺序,即先左右,后上下,可能会得到更短的路径,但无法确保在任何情况下都能得到最短路径。

得到最短路径的方法:

每走一步,就对前方的节点赋值为此节点+1,走过的路径也可以重复行走。这样走遍所有的节点,记录最短的路径。




‘迷宫数据,存于文本文件
11 11                      '迷宫规模
0 0 10 11                  '入口和出口
-1 0 0 1 1 0 0 -1
1 0 0 1 1 1 1 1 1 0 0 1
1 1 0 1 1 0 0 1 1 0 0 1
1 1 1 0 1 0 1 1 1 1 1 1
0 0 1 1 1 0 1 0 1 0 0 1
1 1 1 1 0 1 1 0 1 0 0 1
1 1 0 1 0 1 0 1 1 0 0 1
1 1 1 1 1 1 0 1 1 1 1 1
0 1 0 0 1 0 0 0 1 0 1 0
1 1 1 1 1 1 1 1 0 0 1 0
1 0 0 1 0 1 0 1 1 0 1 0
1 1 1 0 1 1 0 1 1 1 1 1
0 0 1 1 1 1 1 1 1 0 0 0



Private Type TNode
        Rows As Integer
        Cols As Integer
        Last As Integer
        End Type
Dim State() As TNode
Dim Rows As Integer, Cols As Integer
Dim Goal As TNode
Dim Maze() As Integer
Dim Rep() As Boolean
Dim dx(3) As Integer, dy(3) As Integer

Private Sub Form_Resize()
With txtS
  .Top = 0
  .Left = 0
  .Height = ScaleHeight
  .Width = ScaleWidth
End With
End Sub

Private Sub InputData()
Dim FName As String
Dim i As Integer
With CommonDialog1
  .Filter = "(*.txt)|*.txt"
  .ShowOpen
  FName = .FileName
End With
Open FName For Input As #1
Input #1, Rows, Cols
Input #1, State(0).Rows, State(0).Cols
Input #1, Goal.Rows, Goal.Cols
ReDim Maze(Rows, Cols)
For i = 0 To 3
  Input #1, dx(i), dy(i)
Next
For i = 0 To Rows
  For j = 0 To Cols
   Input #1, Maze(i, j)
  Next
Next
Close
ReDim Rep(Rows, Cols)
End Sub

Private Function Moves(Temp As TNode, ByVal i As Integer) As Boolean
With Temp
  If .Rows + dx(i) >= 0 And .Rows + dx(i) <= Rows And _
     .Cols + dy(i) >= 0 And .Cols + dy(i) <= Cols Then
   If Maze(.Rows + dx(i), .Cols + dy(i)) = 1 Then
    .Rows = .Rows + dx(i)
    .Cols = .Cols + dy(i)
    Moves = True
   End If
  End If
End With
End Function

Private Sub PrintPath(State() As TNode, ByVal Tail As Integer)
If Tail > 0 Then
  Tail = State(Tail).Last
  PrintPath State, Tail
  txtS = txtS & State(Tail).Rows & " " & State(Tail).Cols & vbCrLf
End If
End Sub

Private Sub BFS()
Dim Temp As TNode
Dim Head As Integer, Tail As Integer
InputData
Head = 0
Tail = 0
Do While Head <= Tail
  For i = 0 To 3
   Temp = State(Head)
   If Moves(Temp, i) Then
    If Not Rep(Temp.Rows, Temp.Cols) Then
     Rep(Temp.Rows, Temp.Cols) = True
     Tail = Tail + 1
     ReDim Preserve State(Tail)
     State(Tail) = Temp
     State(Tail).Last = Head
     If Temp.Rows = Goal.Rows And Temp.Cols = Goal.Cols Then
      Tail = Tail + 1
      ReDim Preserve State(Tail)
      State(Tail).Last = Tail - 1
      PrintPath State, Tail
      Exit Sub
     End If
    End If
   End If
  Next
  Head = Head + 1
Loop
End Sub

Private Sub DFS()
Dim Temp As TNode
Dim Head As Integer
InputData
Head = 0
Do While Head >= 0
  For i = 0 To 3
   Temp = State(Head)
   If Moves(Temp, i) Then
    If Not Rep(Temp.Rows, Temp.Cols) Then
     Rep(Temp.Rows, Temp.Cols) = True
     Head = Head + 1
     ReDim Preserve State(Head)
     State(Head) = Temp
     State(Head).Last = Head - 1
     txtS = txtS & State(Head).Rows & " " & State(Head).Cols & vbCrLf
     If Temp.Rows = Goal.Rows And Temp.Cols = Goal.Cols Then Exit Sub
     i = 0
    End If
   End If
  Next
  Head = Head - 1
Loop
End Sub

Private Sub mnuBFS_Click()
ReDim State(0)
BFS
End Sub

Private Sub mnuDFS_Click()
ReDim State(0)
DFS
End Sub

Private Sub mnuOpen_Click()
mnuBFS_Click
End Sub

Private Sub mnuSave_Click()
Dim FName As String
Dim i As Integer
With CommonDialog1
  .Filter = "(*.txt)|*.txt"
  .ShowSave
  FName = .FileName
End With
Open FName For Append As #1
Print #1, vbCrLf
Print #1, txtS
Close
End Sub

TA的精华主题

TA的得分主题

 楼主| 发表于 2008-11-8 08:59 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
原帖由 HHAAMM 于 2008-11-8 02:57 发表
按照左下右的选择顺序,向小的方向走(左下右等于1的不算)



有时算出来的结果并不是最短路线哦

TA的精华主题

TA的得分主题

 楼主| 发表于 2008-11-8 09:20 | 显示全部楼层
736.jpg

大家看看以上图片,其实原理就是灌水一样,通过填数字的方式慢慢的向外延伸.

出这题的目的就是希望能突破思维的惯性,见到更多的解题思路.有些时候书本看多了也不是什么好事,因为容易限制人的思维.反而是什么都不看,随心所欲.才有可能写出更好的程序.

[ 本帖最后由 彭希仁 于 2008-11-8 10:27 编辑 ]

TA的精华主题

TA的得分主题

发表于 2008-11-8 11:44 | 显示全部楼层
没有可以学习的答案   自己继续乱摸索   
看起来可以了/。 求最短距离.rar (17.71 KB, 下载次数: 44)

TA的精华主题

TA的得分主题

发表于 2008-11-8 16:02 | 显示全部楼层
原来彭兄弟的灌水法和我的方法是一样的。把递归去掉,改了一下代码。找最短路径挺快,就是画上最短路径比较慢了。
求最短距离2.rar (15.55 KB, 下载次数: 78)

这个方法的速度对这种两三个分支路线的寻找来说还没什么,假如设置障碍比较少的话,效率应该比较差了。应该用上加权的方法,也就是说每次先考虑朝越靠近终点的方向移动...

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2008-11-8 21:35 | 显示全部楼层
winland 厉害!学习了。

TA的精华主题

TA的得分主题

发表于 2008-11-8 21:42 | 显示全部楼层
称之为灌水法确实形象

TA的精华主题

TA的得分主题

发表于 2008-11-9 00:21 | 显示全部楼层

八月院长终于出手了!我要好好学习!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-15 10:08 , Processed in 0.042348 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表