【发布时间】:2021-03-22 15:23:22
【问题描述】:
我的班级有一个作业,我们正在尝试找到通往目的地的最佳(最便宜)路径。说明如下:
每种科技都有一个名称、购买该科技的成本、一个表示玩家是否已经拥有该科技的布尔值,以及当玩家购买该科技时可供购买的 0 到 N 个科技的列表。 Tactigo 中的技术分为三类:社会、军事和科学。三者中的每一个都以玩家在购买更先进的技术之前必须购买的基本技术开始。这些基本技术很特别,因为它们总是可供购买。 查看图表,您会注意到一些技术被多个技术解锁。请记住,只要有任何技术解锁它们,它们就会被解锁。换句话说,您需要“对动物友善”或“对人做迪克”才能购买“攻击动物训练”。你不需要两者,只需要一个。你的任务是找到获得任何给定技术的最便宜的方法。玩家可能已经拥有任何一套技术,所以你必须考虑到这一点。例如,如果玩家已经拥有“与人为善”并想找到最便宜的方式来获得“交友”,则返回的路径应该只是“交友”。他们不需要购买任何其他东西。
图表如下:
我最初想在计算每条路径的成本时对 3 个类别中的每一个进行深度优先搜索。我的这个功能的代码如下:
//---------------------------------------------------------------------------------------------------------------------
// This function finds the best path to the tech we want.
// * goalTech: The index of the tech we're looking for. Call GetTechByIndex() to get the actual Tech instance.
// * bestPath: The best path to the goal tech. This is an array sorted in the order of the best path from the
// start to the goal. This is an output variable; it's what you need to populate with this function.
//---------------------------------------------------------------------------------------------------------------------
void TechTree::FindBestPath(int goalTech, Path& bestPath)
{
//First ensure that best path is cleared out
bestPath.clear();
//Get Tech Instance for this Goal Tech
const Tech* pGoalTech = GetTechByIndex(goalTech);
//make sure we get a valid tech
assert(pGoalTech != nullptr);
//Check first if user already has this unlocked.
if (pGoalTech->HasTech())
{
//just return
return;
}
//Check if the goal tech is one of the three starting techs.
if (pGoalTech == GetBasicSocialTech()|| pGoalTech == GetBasicScienceTech() || pGoalTech == GetBasicMilitaryTech())
{
//now we know that one of the basic techs are the goal, so we just add one of those to the path
if (pGoalTech == GetBasicSocialTech())
bestPath.push_back(GetBasicSocialTech());
else if (pGoalTech == GetBasicMilitaryTech())
bestPath.push_back(GetBasicMilitaryTech());
else
bestPath.push_back(GetBasicScienceTech());
return; //now return
}
//my process will be as follows.
//1. Since all the edges are directed we need to traverse down three different graphs: Social (starting at index 0), Military (starting at index 4) and Science (starting at index 8)
//2. I am going to perform a depth-first search starting at Social and then moving down to Military and then Science.
//3. As I am performing a depth-first I am going to keep track of a path and its respective cost, if a search gets to the goal I will make sure to register that and then move onto the next graph.
//4. When there are no more paths to search I send the lowest cost one back.
///start with social at index 0
const Tech* pStartSocialTech = GetBasicSocialTech();
std::pair<int, std::vector<const Tech*>> bestCurrentPath;
//get starting cost for this category before we move into neighbors,
// if player already has this tech we set this to zero if not we get the cost of buying into this category
int startingCost = pStartSocialTech->HasTech() ? 0 : pStartSocialTech->GetCost();
/*pStartSocialNeighbors = get all neighbors for starting point at social
while (destination is not found AND there are more neighbors to pStartSocialNeighbors)
{
DFS(neighbor, dest) //if this finds the destination we store a path and its cost, otherwise it doesnt do anything and we move on to next basic tree
}
//do the same thing for military and science...
*/
}
我上面有很多 cmets,但我只是想知道这是否是最好的路线。其他选项是 Dijkstras 或 A*,但我不知道您将如何遍历此有向图的路径。我不是在寻找直接的答案,因为这是一项家庭作业,但我正在寻找一些指导。
谢谢!
【问题讨论】: