我的家庭作业(C ++)遇到了麻烦。我不是要求完整的解决方案,但向正确方向倾斜可能会有所帮助。 :)
我有一块NxN板(最大N = 100)和一块1x2的数字(立方体)。立方体的一面涂成红色,另一面涂成蓝色。立方体的默认位置是左上角,蓝色朝上:
B B . .
. . . .
. . . .
. . . .
(4x4例子,B代表蓝色)
黑板上可能有石块(障碍物)。 我可以用我的身材做出动作:
例如,在默认位置使用右转:
. . R R
. . . .
. . . .
. . . .
然后使用rotate 90:
. . R .
. . R .
. . . .
. . . .
然后使用左翻:
. B . .
. B . .
. . . .
. . . .
当然,旋转或翻转时,你不能落在石头上。 因此,问题是 - 对于任何给定的电路板配置(图形位置和石头位置),编写一个程序,将“立方体回家”置于默认位置(蓝色方向上!)使用最小数量的移动并在可能的情况下返回1,如果不可能则返回0。
我觉得这个问题很有意思,但我不得不承认我对它有点困惑。特别是蓝色侧/红色侧面部分。我无法弄清楚如何“翻译”那些我可以在通常的最短路径算法语言中使用的动作(我从未使用过任何这些)。 所以,我很感激你能给出的每一条建议! :)
答案 0 :(得分:1)
首先,由于要求您找到确切的最佳路径,我会选择Dijksta's algorithm。
对于此算法,您需要:
给定初始位置,您的立方体可以准确到达7个新位置。很容易选择哪些是可能的。
G只是你到目前为止所做的动作数量+ 1为下一步动作:)
我会使用哈希表来跟踪访问位置。 (这可能是最难写的功能),但你现在不需要过度思考。一个简单的向量和一个逐项比较就可以了。您可以在代码运行后对其进行优化。
最后,您需要检查立方体是否处于蓝色方向的初始位置。
答案 1 :(得分:1)
您可以将每个可能的1x2块和颜色(红色或蓝色)组合解释为顶点并作为边缘移动。如果可以在一次移动中从某个其他组合到达特定的1x2块和颜色组合(顶点),则在这两个组合之间存在连接(边缘)。然后你必须在结果图中找到给定配置和“home”配置之间的最短路径(可能是广度优先搜索,因为无论你执行什么移动,移动的成本都是相同的。)
如果想要更进一步,你可以使用在图遍历期间使用启发式的高级图搜索算法(启发式是在黑板上没有障碍物时到达目的地所需的最小移动量)。例如,您可以使用A* algorithm。
答案 2 :(得分:0)
在处理此类问题时,首先要做的是找到问题的状态的表示。 在这种情况下,您需要:
如果您熟悉位掩码,则应该只使用32位整数(x位置为8位,y位置为8位,其余为2位)。
这样,您就不需要实现比较运算符。
或强>
您可以使用这3个信息定义一个简单的结构(称之为state
),并对此进行严格排序比较(只需将state
放入std::set
。
在此之后,您可以使用BFS解决此问题。
要做到这一点,你需要:
std::map<state,state>
用于存储您在密钥中已访问过的位置,以及您来自该值的位置(如果您可以使用c ++ 11,则将map
替换为unordered_map
并使用位掩码存储您的状态)std::queue<state>
,其中按下并弹出要处理的状态。伪代码:
map<state,state> visited;
queue<state> to_be_processed;
visited.insert( initial_state,initial_state); //you are not coming from anywhere
to_be_processed.push ( initial_state);
while(!to_be_processed.empty()) {
state cur = to_be_processed.pop();
if ( cur == end_state) //you are done
{
//to get the path from initial_state to end_state you have just to walk visited in the inverse order.
return 1;
}
for ( i = every possible state reachable from cur) {
if (visited.count(i) != 0) continue; //already visited
to_be_processed.push(i);
visited.insert(i,cur); //i has been visited, and you reached i from cur
}
}
return 0; //if you get here, no way
障碍的存在使问题更难以编码,但在概念上并没有不同。
请注意,在这种情况下,BFS可以正常工作,因为您从一个州到另一个州的费用总是相同的。