用Python建模图形

用Python建模图形,python,algorithm,graph,minimum-spanning-tree,Python,Algorithm,Graph,Minimum Spanning Tree,我正在尝试解决一个与Python中的图形相关的问题。因为这是一个可接受的编程问题,所以我不使用任何其他第三方软件包 该问题以5x5方格网的形式呈现图形。 假设机器人位于电网上用户提供的位置。网格索引位于左上角的(0,0)和右下角的(4,4)。网格中的每个单元格由以下3个字符中的任意一个表示。”b'(ascii值98)表示机器人的当前位置,d'(ascii值100)表示网格中的脏单元格,'-'(ascii值45)表示网格中的干净单元格。 例如,下面是一个示例网格,其中机器人位于0 0: b---d

我正在尝试解决一个与Python中的图形相关的问题。因为这是一个可接受的编程问题,所以我不使用任何其他第三方软件包

该问题以
5x5
方格网的形式呈现图形。 假设机器人位于电网上用户提供的位置。网格索引位于左上角的
(0,0)
和右下角的
(4,4)
。网格中的每个单元格由以下3个字符中的任意一个表示。”
b
'(ascii值98)表示机器人的当前位置,
d
'(ascii值100)表示网格中的脏单元格,'-'(ascii值45)表示网格中的干净单元格。 例如,下面是一个示例网格,其中机器人位于
0 0

b---d
-d--d
--dd-
--d--
----d
目标是以最少的步骤清洁网格中的所有单元。 步骤定义为任务,其中 i) 机器人改变它的位置 ii)机器人改变电池状态(从d变为-)

假设最初标记为
b
的位置不需要清洁。机器人可以上下左右移动

我的方法

我已经阅读了一些关于图形的教程,并决定将图形建模为25 X 25的邻接矩阵,0表示没有路径,1表示矩阵中的路径(因为我们只能在4个方向上移动)。接下来,我决定将Floyd Warshell的所有对最短路径算法应用于它,然后对路径的值求和。 但我有一种感觉,那是行不通的。 我认为问题在于以下任一方面:

i) 最小生成树(这是我无法做到的,因为我无法将网格建模并存储为图形)

ii)一个*搜索(同样是一个猜测,但这里的问题相同,我无法将网格正确地建模为一个图形)


如果你能提出一个解决此类问题的好方法,我将不胜感激。此外,一些关于各种形式的基于图形的问题(或这些问题的链接)的提示和伪代码也会有所帮助。谢谢

问题当然可以存储为图形。节点(脏单元)之间的成本是它们的成本。忽略清洁单元的成本,因为无论采用何种路径,总成本都是相同的。

让我们假设
V={V|V=b或V=d}
,并获得一个完整的连通图
G(V,E)
。您可以计算
E
中每条边的成本,时间复杂度为
O(n^2)
。之后,问题变得完全相同:从指定的顶点开始,找到覆盖
V
G
最短路径


我们从1832年起就称之为这个问题。

在我看来,这个问题就是这个问题。不幸的是,这个问题是NP难的,所以如果我是正确的,你需要给出一个近似值(基于曼哈顿距离的最小生成树)。

我想你在这里问了两个问题

1。如何在Python中将此问题表示为图形?

当机器人四处移动时,他将从一个肮脏的广场移动到另一个广场,有时会沿途穿过一些干净的空间。你的工作是确定参观脏广场的顺序

# Code is untested and may contain typos. :-)

# A list of the (x, y) coordinates of all of the dirty squares.
dirty_squares = [(0, 4), (1, 1), etc.]
n = len(dirty_squares)    

# Everywhere after here, refer to dirty squares by their index
# into dirty_squares.

def compute_distance(i, j):
  return (abs(dirty_squares[i][0] - dirty_squares[j][0])
          + abs(dirty_squares[i][1] - dirty_squares[j][1]))

# distances[i][j] is the cost to move from dirty square i to
# dirty square j.
distances = []
for i in range(n):
  distances.append([compute_distance(i, j) for j in range(n)])

# The x, y coordinates of where the robot starts.
start_node = (0, 0)

# first_move_distances[i] is the cost to move from the robot's
# start location to dirty square i.
first_move_distances = [
  abs(start_node[0] - dirty_squares[i][0])
      + abs(start_node[1] - dirty_squares[i][1]))
  for i in range(n)]

# order is a list of the dirty squares.
def cost(order):
  if not order:
    return 0  # Cleaning 0 dirty squares is free.
  return (first_move_distances[order[0]]
          + sum(distances[order[i]][order[i+1]]
                for i in range(len(order)-1)))
您的目标是找到一种重新排序列表(范围(n))的方法,以最小化成本

2。如何找到解决此问题的最少移动次数?

正如其他人所指出的,这个问题的广义形式是难以解决的(NP难)。您有两条信息可以帮助约束问题,使其易于处理:

  • 这个图形是一个网格
  • 最多有24个脏方块
  • 我喜欢你在这里用*的本能。它通常有助于解决移动次数最少的问题。但是,A*需要相当数量的代码。我认为您最好使用分支绑定方法(有时称为分支和修剪),该方法应该同样有效,但更易于实现

    我们的想法是开始使用深度优先搜索枚举所有可能的解决方案,如下所示:

      # Each list represents a sequence of dirty nodes.
      []
      [1]
      [1, 2]
      [1, 2, 3]
      [1, 3]
      [1, 3, 2]
      [2]
      [2, 1]
      [2, 1, 3]
    
    每次要递归到分支时,检查该分支是否比目前发现的最便宜的解决方案更昂贵。如果是这样,您可以跳过整个分支


    如果这不够有效,请添加一个函数来计算剩余成本的下限。然后,如果cost([2])+lower_-bound(set([1,3])比目前发现的最便宜的解决方案更昂贵,那么您可以跳过整个分支。下界越紧,可以跳过的分支就越多。

    好吧,这不是竞争,这是一个叫做HackerRank的论坛,我已经明确了解决问题的方法,它不会把我带到任何地方。这个问题是否规定了脏方数的限制?矩阵是否固定为5*5?是的,矩阵固定为5*5@DanielStutzbach不,它没有指定脏方的数量或位置,我们得到的只是矩阵和起始位置