“机器人手臂移动块堆栈”C中的编程挑战

时间:2012-10-21 05:40:22

标签: c algorithm recursion tree

我正试图解决这个问题,但我在实施方面遇到了一些麻烦,问题是这样的:

拥有n个堆叠的块,每个块包含m个块,在c中设计一个控制机器人手臂的程序,使用最小量的运动可以将块从正面配置移动到最终的块,你的手臂只能一次移动一个块并且只能占用堆栈顶部的块,您的解决方案应该使用指针或递归方法

换句话说,块应该从这里开始(假设有3个堆栈和3个块):

| || || |
|3|| || |
|2||1|| |

到此:

| ||1|| |
| ||2|| |
| ||3|| |

使用最短的动作打印每次动作

我在想,也许我可以使用某种树来解决它(可能是n-ary树?),因为这是指针和递归方法的完美使用,但到目前为止它已被证明是不成功的,我有定义将存储所有动作的结构有很多麻烦,因为如果以前没有完成此动作,我每次想要向树添加新动作时都要检查,我希望每个叶子都是唯一的,所以当我找到解决方案,它将给我最短的路径。

这是我想到的数据结构:

typedef struct tree(
char[MAX_BLOCK][MAX_COL] value;    
struct tree *kids
struct tree *brothers;
)Tree;

(我真的很陌生,所以如果这一切都错了,我会更加习惯于Java)

你们会怎么做?你有什么好主意吗?

1 个答案:

答案 0 :(得分:3)

你有基本的想法 - 虽然我不确定你为什么选择兄弟而不是父母。

可以通过一个简单的BFS搜索来解决这个问题,但它是一个稍微不那么有趣的解决方案,而不是那个你似乎已经为自己设定的解决方案。

我认为,如果我们简明扼要地说明我们对问题的处理方式,作为Dijkstra's,A *或其他搜索算法的表述,这将有所帮助。

如果您不熟悉Dijkstra,那么在进一步尝试之前必须先阅读算法。它是最短路径探索的基础工作之一。

熟悉Dijkstra,A *很容易被描述为

  

Dijsktra最小化距离一开始的距离。 A *添加了一个启发式算法,可以最小化到达目的地的(预期)距离。

考虑到这个算法,让我们说明A *搜索算法的特定输入。

  

给定启动配置 S-start 和结束配置 S-end ,我们可以找到从S-start到S-end的最短路径给定一组规则 R 由奖励函数 T

管理

现在,我们可以将我们的数据结构设想为不是树,而是图形。节点将是板状态,我们可以使用我们的规则R从状态转换到状态。我们将使用奖励函数T选择要遵循的边缘,启发式为A *。

您的数据结构缺少的是成本。在每个节点,您将需要存储当前最短路径,以及是否已完成。

让我们对您的数据结构进行修改,这样我们就可以轻松遍历图表并存储最短路径信息。

typedef struct node {
  char** boardState;
  struct node *children;
  struct node *parent;
  int distance;
  char status; //pseudo boolean
} node;
  

如果您有兴趣为自己发现算法,可能需要停在此处。

我们现在考虑我们系统的规则:从堆栈顶部一次一个块。每个动作都会在我们的图形中构成一个边缘,其权重由来自S-begin的最短移动次数加上我们添加的启发式控制。

然后,我们可以如下绘制算法草图:

node * curr = S-begin;
while (curr != S-end) {
  curr->status == 'T'; //T for True
  for(Node child : children) {
     // Only do this update if it is cheaper than the 
     int updated = setMin(child->distance, curr->distance + 1 + heuristic(child->board));
     if(updated == 1) child->parent = curr;  
  } 
  //set curr to the node with global minimum distance who has not been explored
}

然后,您可以通过将父母从S-end向后追溯到S-begin来找到最短路径。

如果您对这些类型的问题感兴趣,您应该考虑参加高等水平的人工智能课程,他们会解决这些类型的问题: - )