- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在解决 this assignment 中的第二个练习(这不是作业,我实际上是在尝试解决 this other problem )。我的解决方案使用 BFS 来搜索“熄灯”问题变体的最小解决方案,其中按下一盏灯会翻转同一行和同一列上每个灯的状态。
我认为我的实现是正确的,但它有点太慢了:它目前在我的计算机上运行需要 12 秒以上(这对我的目的来说是 Not Acceptable )。
from copy import deepcopy
from itertools import chain
from Queue import PriorityQueue
# See: http://www.seas.upenn.edu/~cis391/Homework/Homework2.pdf
class Puzzle(object):
def __init__(self, matrix):
self.matrix = matrix
self.dim = len(matrix)
def __repr__(self):
return str(self.matrix)
def solved(self):
return sum([sum(row) for row in self.matrix]) == 0
def move(self, i, j):
for k in range(self.dim):
self.matrix[i][k] = (self.matrix[i][k] + 1) % 2
self.matrix[k][j] = (self.matrix[k][j] + 1) % 2
self.matrix[i][j] = (self.matrix[i][j] + 1) % 2
return self
def copy(self):
return deepcopy(self)
def next(self):
result = []
for i in range(self.dim):
for j in range(self.dim):
result.append(self.copy().move(i, j))
return result
def solve(self):
q = PriorityQueue()
v = set()
q.put((0, self))
while True:
c = q.get()
if c[1].solved():
return c[0]
else:
for el in c[1].next():
t = el.tuple()
if t not in v:
v.add(t)
q.put((c[0] + 1, el))
def tuple(self):
return tuple(chain.from_iterable(self.matrix))
根据 cProfile
,罪魁祸首似乎是 deepcopy
调用。另一方面,我看不到其他选择:我需要向队列中添加另一个 Puzzle
对象,其中包含 self.matrix
的新副本。
如何加快实现速度?
这是我正在使用的测试用例:
print Puzzle([
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]).solve()
应该返回1(我们只需要按下右下角的灯)。
编辑:这是另一个粗糙的测试用例:
print Puzzle([
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]
]).solve()
它的解最多为14:按下对角线上所有已经亮着的灯。不幸的是,@zch 令人印象深刻的加速不足以解决这个问题,这让我相信,由于高分支因子,BFS 不是解决这个问题的正确方法。
最佳答案
还有许多优化工作要做。
首先,避免 deepcopy
,实现你自己的复制(这本身对我来说快了 5 倍):
class Puzzle(object):
def __init__(self, matrix):
self.matrix = [list(row) for row in matrix]
self.dim = len(matrix)
def copy(self):
return Puzzle(self.matrix)
其次,在 BFS 中您不需要优先级队列,使用 Queue
或实现您自己的队列。这提供了一些加速。第三,在将其放入队列之前检查是否已解决,而不是在取出东西之后。这应该可以让您在可比的时间内更深入地学习:
def solve(self):
v = set()
q = [(0, self)]
i = 0
while True:
c = q[i]
i += 1
for el in c[1].next():
t = el.tuple()
if t not in v:
if el.solved():
return c[0] + 1
v.add(t)
q.append((c[0] + 1, el))
此外,使用位列表的列表内存效率非常低。您可以将所有位打包成一个整数并获得更快的解决方案。此外,您可以为允许的移动预先计算掩码:
def bits(iterable):
bit = 1
res = 0
for elem in iterable:
if elem:
res |= bit
bit <<= 1
return res
def mask(dim, i, j):
res = 0
for idx in range(dim * i, dim * (i + 1)):
res |= 1 << idx
for idx in range(j, dim * dim, dim):
res |= 1 << idx
return res
def masks(dim):
return [mask(dim, i, j) for i in range(dim) for j in range(dim)]
class Puzzle(object):
def __init__(self, matrix):
if isinstance(matrix, Puzzle):
self.matrix = matrix.matrix
self.dim = matrix.dim
self.masks = matrix.masks
else:
self.matrix = bits(sum(matrix, []))
self.dim = len(matrix)
self.masks = masks(len(matrix))
def __repr__(self):
return str(self.matrix)
def solved(self):
return self.matrix == 0
def next(self):
for mask in self.masks:
puzzle = Puzzle(self)
puzzle.matrix ^= mask
yield puzzle
def solve(self):
v = set()
q = [(0, self)]
i = 0
while True:
c = q[i]
i += 1
for el in c[1].next():
t = el.matrix
if t not in v:
if el.solved():
return c[0] + 1
v.add(t)
q.append((c[0] + 1, el))
最后,对于另一个 5 因子,您可以只传递位矩阵,而不是整个 Puzzle
对象,并且另外内联一些最常用的函数。
def solve(self):
v = set()
q = [(0, self.matrix)]
i = 0
while True:
dist, matrix = q[i]
i += 1
for mask in self.masks:
t = matrix ^ mask
if t not in v:
if t == 0:
return dist + 1
v.add(t)
q.append((dist + 1, t))
对我来说,这些优化加起来可以提速大约 250 倍。
关于python - 进行 BFS 时避免深层复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27337694/
我正在编写一个应用程序,允许用户创建一个“问卷”,然后向其中添加问题。我正在使用核心数据来存储信息。我创建了一个问卷实体,并与问题实体建立了“一对多”关系。我的问题是,如果要允许用户复制(复制)整个调
有没有办法复制或复制 SharedPreference?或者我需要从一个变量中获取每个变量,然后将它们放入另一个变量中吗? 最佳答案 尝试这样的事情: //sp1 is the shared pref
下面的(A)和(B)有区别吗? (假设 NON ARC,如果重要的话) // --- (A) --- @interface Zoo : NSObject{} @property (copy) Dog
我正在尝试将 mysql SELECT 查询保存到文件中,如下所示: $result = mysqli_query($db,$sql); $out = fopen('tmp/csv.csv', 'w'
我需要创建一个 CVPixelBufferRef 的副本,以便能够使用副本中的值以按位方式操作原始像素缓冲区。我似乎无法使用 CVPixelBufferCreate 或 CVPixelBufferCr
我在 Source 文件夹中有一个 Active wave 录音 wave-file.wav。我需要使用新名称 wave-file-copy.wav 将此文件复制到 Destination 文件夹。
在使用 GNU Autotools 构建的项目中,我有一个脚本需要通过 make 修改以包含安装路径。这是一个小例子: configure.ac: AC_INIT(foobar, 1.0) AC_PR
我想将 SQL 的行复制到同一个表中。但是在我的表中,我有一个“文本”列。 使用此 SQL: CREATE TEMPORARY TABLE produit2 ENGINE=MEMORY SELECT
谁能给我解释一下 df2 = df1 df2 = df1.copy() df3 = df1.copy(deep=False) 我已经尝试了所有选项并执行了以下操作: df1 = pd.DataFram
Hazelcast 是否具有类似于 Ehcache 的复制? http://www.ehcache.org/generated/2.9.0/pdf/Ehcache_Replication_Guide.
我有以下拓扑。一个 Ubuntu 16.04。运行我的全局 MySQL 服务器的 Amazon AWS 上的实例。我想将此服务器用作许多本地主服务器(Windows 机器 MySQL 服务器)的从服务
使用 SQLyog,我正在测试表中是否设置了正确的值。我尝试过 SELECT type_service FROM service WHERE email='test@gmail.com' 因此,只输出
有人可以提供一些关于如何配置 ElasticSearch 进行复制的说明。我在 Windows 中运行 ES,并且了解如果我在同一台服务器上多次运行 bat 文件,则会启动一个单独的 ES 实例,并且
一 点睛 ThreadGroup 复制线程的两个方法。 public int enumerate(Thread list[]) // 会将 ThreadGroup 中的 active 线程全部复制到
一 点睛 ThreadGroup 复制线程组的两个方法。 public int enumerate(ThreadGroup list[]) // 相对于 enumerate(list,true) pu
官方documentation Cassandra 说: Configure the keyspace and create the new datacenter: Use ALTER KEYSPAC
This question already has answers here: How to weight smoothing by arbitrary factor in ggplot2? (2个答
我们有一个表格来表明对各种俱乐部的兴趣。输出将数据记录在 Excel 电子表格中,其中列有他们的首选姓名、姓氏、电子邮件、代词,以及他们感兴趣的俱乐部的相应列中的“1”(下面的模型)。 我们希望为俱乐
This question already has answers here: Closed 8 years ago. Possible Duplicate: In vim, how do I get
如何复制形状及其所在的单元格?当我手动复制时,形状会跟随单元格,但是当我使用宏进行复制时,我会得到除形状之外的所有其他内容。 Cells(sourceRow, sourceColumn).Copy C
我是一名优秀的程序员,十分优秀!