- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个算法可以创建一个图形,该图形具有以最短图形路径形式编码的 3 位二进制字符串的所有表示,其中路径中的偶数表示 0,而奇数表示 1:
from itertools import permutations, product
import networkx as nx
import progressbar
import itertools
def groups(sources, template):
func = permutations
keys = sources.keys()
combos = [func(sources[k], template.count(k)) for k in keys]
for t in product(*combos):
d = {k: iter(n) for k, n in zip(keys, t)}
yield [next(d[k]) for k in template]
g = nx.Graph()
added = []
good = []
index = []
# I create list with 3-bit binary strings
# I do not include one of the pairs of binary strings that have a mirror image
list_1 = [list(i) for i in itertools.product(tuple(range(2)), repeat=3) if tuple(reversed(i)) >= tuple(i)]
count = list(range(len(list_1)))
h = 0
while len(added) < len(list_1):
# In each next step I enlarge the list 'good` by the next even and odd number
if h != 0:
for q in range(2):
good.append([i for i in good if i%2 == q][-1] + 2)
# I create a list `c` with string indices from the list` list_1`, that are not yet used.
# Whereas the `index` list stores the numbering of strings from the list` list_1`, whose representations have already been correctly added to the `added` list.
c = [item for item in count if item not in index]
for m in c:
# I create representations of binary strings, where 0 is 'v0' and 1 is 'v1'. For example, the '001' combination is now 'v0v0v1'
a = ['v{}'.format(x%2) for x in list_1[m]]
if h == 0:
for w in range(2):
if len([i for i in good if i%2 == w]) < a.count('v{}'.format(w)):
for j in range(len([i for i in good if i%2 == w]), a.count('v{}'.format(w))):
good.insert(j,2*j + w)
sources={}
for x in range(2):
sources["v{0}".format(x)] = [n for n in good if n%2 == x]
# for each representation in the form 'v0v0v1' for example, I examine all combinations of strings where 'v0' is an even number 'a' v1 'is an odd number, choosing values from the' dobre2 'list and checking the following conditions.
for aaa_binary in groups(sources, a):
# Here, the edges and nodes are added to the graph from the combination of `aaa_binary` and checking whether the combination meets the conditions. If so, it is added to the `added` list. If not, the newly added edges are removed and the next `aaa_binary` combination is taken.
g.add_nodes_from (aaa_binary)
t1 = (aaa_binary[0],aaa_binary[1])
t2 = (aaa_binary[1],aaa_binary[2])
added_now = []
for edge in (t1,t2):
if not g.has_edge(*edge):
g.add_edge(*edge)
added_now.append(edge)
added.append(aaa_binary)
index.append(m)
for f in range(len(added)):
if nx.shortest_path(g, aaa_binary[0], aaa_binary[2]) != aaa_binary or nx.shortest_path(g, added[f][0], added[f][2]) != added[f]:
for edge in added_now:
g.remove_edge(*edge)
added.remove(aaa_binary)
index.remove(m)
break
# Calling a good combination search interrupt if it was found and the result added to the `added` list, while the index from the list 'list_1` was added to the` index` list
if m in index:
break
good.sort()
set(good)
index.sort()
h = h+1
added
的 3 位二进制字符串的输出路径:
[[0, 2, 4], [0, 2, 1], [2, 1, 3], [1, 3, 5], [0, 3, 6], [3, 0, 7]]
[[0, 0, 0], [0, 0, 1], [0, 1, 1], [1, 1, 1], [0, 1, 0], [1, 0, 1]]
h = 0
找到前 4 个子列表,并且在步骤
h = 1
中添加了最后两个子列表。
for m in c
上使用多处理循环,因为查找元素的顺序在这里无关紧要。
from multiprocessing import Pool
added = []
def foo(i):
added = []
# do something
added.append(x[i])
return added
if __name__ == '__main__':
h = 0
while len(added)<len(c):
pool = Pool(4)
result = pool.imap_unordered(foo, c)
added.append(result[-1])
pool.close()
pool.join()
h = h + 1
foo
中。函数,
added
列表已创建。在每个后续步骤中
h
在循环中,列表
added
应按后续值递增,当前列表
added
应该在函数
foo
中使用.是否可以在循环的每个后续步骤中将列表的当前内容传递给函数?因为在上面的代码中,
foo
函数创建
added
的新内容每次都从头开始列出。如何解决这个问题?
[[0, 2, 4], [0, 2, 1], [2, 1, 3], [1, 3, 5], [0, 1, 2], [1, 0, 3]]
nx.shortest_path (graph, i, j) == added[k]
对于每个最终节点
i, j
来自
added[k] for k in added list
.
h = 0
到元素
[0, 2, 4], [0, 2, 1], [2, 1, 3], [1, 3, 5]
很好,而在步骤中添加的元素
h = 1
, 即
[0, 1, 2], [1, 0, 3]
显然可以在不影响上一步中的元素的情况下找到。
h
的步骤while 循环按顺序运行,但
for m in c
循环是多处理的。或其他部分解决方案,可以改进更大组合的整个算法。
最佳答案
我认为您不能像目前那样并行化代码。您想要并行化的部分,for m in c
循环访问三个全局列表 good
, added
和 index
和图形g
本身。您可以使用 multiprocessing.Array
对于列表,但这会破坏并行化的整个点,如 multiprocessing.Array
( docs ) 是同步的,因此进程实际上不会并行运行。
因此,需要重构代码。我首选的并行化算法的方法是使用一种生产者/消费者模式
1.
将是
list_1
的设置代码,
count
可能还有
h == 0
案件。之后,您将构建一个“作业订单”队列,这将是
c
列表 -> 将该列表传递给一群 worker -> 返回结果并汇总。问题是每次执行
for m in c
loop 可以访问全局状态,并且每次迭代后全局状态都会发生变化。这在逻辑上意味着您不能并行运行代码,因为第一次迭代会更改全局状态并影响第二次迭代的操作。也就是说,根据定义,一种顺序算法。您不能(至少不容易)并行化迭代构建图的算法。
multiprocessing.starmap
和
multiprocessing.Array
,但这并不能解决问题。你还有图
g
这也在所有进程之间共享。所以整个事情需要以这样的方式重构,每次迭代
for m in c
循环独立于该循环的任何其他迭代,或者必须更改整个逻辑,以便
for m in c
不需要循环开始。
'101'
),您将在现有图中生成所有可能的连接点,然后将新的三元组添加到图中并根据测量最短路径消除节点。这需要检查图形上的最短路径并进行修改,这会阻止并行化。
'101'
(注意引号
''
是二进制字符串,
'00'
和
'1'
也是如此,其中
1
、
0
、
4
等(图中没有引号)是顶点标签。
job_queue
其中包含所有三元组 '000'
这将是 ( 0
, 2
, 4
) - 这是微不足道的,无需检查任何内容,因为在您开始时图形是空的,因此最短路径是根据定义您插入的路径。 '011'
的部分路径,
'001'
,
'010'
相反(
'110'
和
'001'
因为图是无向的)。我们将利用现有图包含
job_queue
中剩余三元组的子解决方案这一事实。 .假设下一个三元组是
'010'
,您遍历二进制字符串
'010'
或
list('010')
'0'
的路径/顶点图中已存在 --> 继续 '01'
的路径/顶点图中已存在 --> 继续 '010'
的路径/顶点存在你已经完成了,不需要添加任何东西(这实际上是一个失败案例:'010'
不应该再出现在作业队列中,因为它已经被解决了)。 '01'
图中不存在。插入
'1'
在这种情况下将是节点
1
到图形并将其连接到三个
even
之一节点,我认为哪个节点并不重要,但您必须记录它连接到哪个节点,假设您选择了
0
.该图现在看起来像
0 - 2 - 4
\ *
\ *
\*
1
1 - 2
(标有星号)获取路径
0 - 1 - 2
为
'010'
,如果边
1-2
,这是最大化编码的三元组数量的路径被添加到图形中。如果您添加
1-4
你只编码
'010'
三重,如
1 - 2
编码
'010'
还有
'001'
和
'100'
.
1
至
2
起初,而不是
0
(第一个连接是随机选择的),你现在有一个图表
0 - 2 - 4
|
|
|
1
1
至
4
或到
0
,但您再次得到一个图形,该图形对
job_queue
中剩余的最大三元组数进行编码。 .
g
,对于 3 位字符串,并行的节省不是那么大,但对于 32 位字符串,它们会。这是它的工作原理。
0-1
生成所有可能的完整路径-> (0-1-2), (0-1-4)
. job_queue
中。 .(0-1-2)
解决另外两个三元组 '001' (4-2-1) or (2-0-1)
和 '100' (1-0-2) or (1-2-4)
. (0-1-4)
只解决了三重'010'
,即它本身 job_queue
中剩余的最多三元组的边/路径是最佳解决方案(我没有证据)。
2.
以上并行复制图形到每个 worker 。因为您没有修改图形,只检查它解决了多少个三元组,所以您可以并行执行此操作。每个 worker 都应该有一个类似的签名
check_graph(g, path, copy_of_job_queue):
# do some magic
return (n_paths_solved, paths_solved)
path
要么是
(0-1-2)
或
(0-1-4)
,
copy_of_job_queue
应该是
job_queue
上剩余路径的副本.对于 K 个 worker ,您创建 K 个队列副本。一旦工作池完成,您就知道哪条路径
(0-1-2)
或
(0-1-4)
解决最多的三元组。
job_queue
进行了大量复制和循环。 , 如果您要处理大位空间,例如 32 位,则
job_queue
很长,所以你可能不想继续复制给所有的 worker 。
job_queue
实际上是
dict
其中关键是三元组,比如
'010'
,该值是一个 bool 标志,表示该三元组是否已在图中编码。
关于python - 创建表示 3 位二进制字符串的所有组合的最小图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48250410/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!