Harvard Online CS50 – 学位

刚刚开始学习CS50人工智能入门课程,我认为我已经正确实现了BFS队列搜索算法来寻找两个演员之间的最短路径。我不知道可能的问题出在哪里,但我希望有人能指出我可能做错的地方。此外,没有任何错误提示,这实际上让问题变得更加难以理解。

def shortest_path(source, target):
    """
    返回从源到目标的最短路径列表,包含(movie_id, person_id)对。
    如果没有可能的路径,则返回None。
    """
    # 初始化前沿为队列,因为BFS使用队列并能找到最短路径
    frontier = QueueFrontier()
    # 将第一个节点添加到前沿
    frontier.add(Node(source, None, None))
    # 初始化已探索节点为一个空集合
    nodesExplored = set()
    if source == target:
        raise Exception("不能选择同一个演员两次!")
    # 持续循环直到找到解决方案
    while True:
        # 如果没有解决方案,则返回None
        if frontier.empty():
            return None
        # 从前沿选择一个节点并移除它
        node = frontier.remove()
        # 如果节点是目标节点,则我们已经达到目标状态,即我们的解决方案
        if node.state == target:
            # 初始化解决方案数组
            solutions = []
            # 如果节点有父节点,则继续搜索
            while node.parent is not None:
                solutions.append(node.action, node.state)
                node = node.parent
            solutions.reverse()
            return solutions
        # 标记节点为已探索
        nodesExplored.add(node.state)
        # 将邻居节点添加到前沿
        for movie_id, person_id in neighbors_for_person(node.state):
            if not frontier.contains_state(person_id) and person_id not in nodesExplored:
                child = Node(person_id, node, movie_id)
                frontier.add(child)

应该发生的情况是:

$ python degrees.py large Loading data... Data loaded. Name: Emma Watson Name: Jennifer Lawrence 3 degrees of separation. 1: Emma Watson and Brendan Gleeson starred in Harry Potter and the Order of the Phoenix 2: Brendan Gleeson and Michael Fassbender starred in Trespass Against Us 3: Michael Fassbender and Jennifer Lawrence starred in X-Men: First Class

但是在我输入第二个演员后什么都没有发生。屏幕保持空白,没有返回任何东西,甚至没有错误提示,所以我得到的是:

$ python degrees.py large Loading data... Data loaded. Name: Emma Watson Name: Jennifer Lawrence


回答:

我的猜测是你的frontier.contains_state(person_id)检查过多,因为你阻止了将同一演员在不同电影中的节点添加到前沿,从而切断了可能的解决方案路径

这个似乎可以工作:

def shortest_path(source, target):
    frontier = QueueFrontier()
    frontier.add(Node(source, None, None))
    nodesExplored = set()
    if source == target:
        raise Exception("不能选择同一个演员两次!")
    while True:
        if frontier.empty():
            return None
        node = frontier.remove()
        if node.state == target:
            solutions = []
            while node.parent is not None:
                solutions.append((node.action, node.state))
                node = node.parent
            solutions.reverse()
            return solutions
        nodesExplored.add(node.state)
        for movie_id, person_id in neighbors_for_person(node.state):
            if not (person_id in nodesExplored):
                child = Node(person_id, node, movie_id)
                frontier.add(child)

然而,课程笔记也提到:“如果你检测到目标节点,无需将其添加到前沿,你可以直接返回解决方案。”我认为你的代码可以通过移动目标检查来进一步改进…祝你在课程中好运,我也刚开始学习cs50 😉

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注