我正试图解决这个问题,但我在实施方面遇到了一些麻烦,问题是这样的:
拥有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)
你们会怎么做?你有什么好主意吗?
答案 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来找到最短路径。
如果您对这些类型的问题感兴趣,您应该考虑参加高等水平的人工智能课程,他们会解决这些类型的问题: - )