1

只是想知道是否有人可以帮助我解决我遇到的一些编程数学问题。

我要创建的是 Nuke (vfx) 的提交脚本(使用 python 和 .bat)。我遇到的问题是我无法弄清楚如何将剩余的帧添加到已经计算的堆栈中。

为了更清楚...

在 Nuke 中,我必须渲染 20 帧。我有 16 个线程。Nuke 仅使用 1 个线程。我想编写一个脚本,它需要帧数并将其除以线程数,然后使用 python 写出一个 bat 文件。问题来了,当我有剩余时。我想取剩余部分并将其应用回渲染堆栈。

示例(第一个循环)

thread1 = 1 frame
thread2 = 1 frame
thread3 = 1 frame
thread4 = 1 frame
thread5 = 1 frame
thread6 = 1 frame
...
thread16 = 1 frame

完成此操作后...余数为 4。我希望将余数分配给线程。所以...

示例(第二个循环)

thread1 = 2 frame
thread2 = 2 frame
thread3 = 2 frame
thread4 = 2 frame
thread5 = 1 frame
thread6 = 1 frame
...
thread16 = 1 frame

4 被添加到前几个线程中,总共 20 帧。

我将非常感谢任何人提供的任何帮助、提示和评论。:)

谢谢

4

4 回答 4

4

这是Bresenham 算法的经典用法:

def partition(lst, n):
    increment = len(lst) / float(n)
    last = 0
    i = 1
    results = []
    while last < len(lst):
        idx = int(round(increment * i))
        results.append(lst[last:idx])
        last = idx
        i += 1
    return results


for i, frames in enumerate(partition(range(20),16)):
    if len(frames)>1:
        print 'thread'+str(i+1),'=', len(frames),'frames'
    else:
        print 'thread'+str(i+1),'=', len(frames),'frame'

分区位来自这个答案

它打印:

thread1 = 1 frame
thread2 = 2 frames
thread3 = 1 frame
thread4 = 1 frame
thread5 = 1 frame
thread6 = 2 frames
thread7 = 1 frame
thread8 = 1 frame
thread9 = 1 frame
thread10 = 2 frames
thread11 = 1 frame
thread12 = 1 frame
thread13 = 1 frame
thread14 = 2 frames
thread15 = 1 frame
thread16 = 1 frame

如果您不介意前面加载的两个框架线程,您也可以使用Mark Dickinson 的解决方案。

然后你有:

def partition(lst, n):
    q, r = divmod(len(lst), n)
    indices = [q*i + min(i, r) for i in xrange(n+1)]
    return [lst[indices[i]:indices[i+1]] for i in xrange(n)]

打印:

thread1 = 2 frames
thread2 = 2 frames
thread3 = 2 frames
thread4 = 2 frames
thread5 = 1 frame
thread6 = 1 frame
thread7 = 1 frame
thread8 = 1 frame
thread9 = 1 frame
thread10 = 1 frame
thread11 = 1 frame
thread12 = 1 frame
thread13 = 1 frame
thread14 = 1 frame
thread15 = 1 frame
thread16 = 1 frame
于 2012-05-22T00:22:42.303 回答
1

frames可以是任何对象的列表,例如 dict 或“Frame”对象。在这里,我刚刚使用了整数

>>> frames = range(20)
>>> threads = 16
>>> [frames[x::threads] for x in range(threads)]
[[0, 16], [1, 17], [2, 18], [3, 19], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15]]

我认为您最好将帧放入其中Queue,因为某些帧可能比其他帧渲染得更快

于 2012-05-22T02:43:47.120 回答
0
frames=20
tPos=16
Ts=divmod(frames,tPos)
threads=[Ts[0]+1 if i < Ts[1] else Ts[0] for i in range(tPos)]

>>> threads    
>>> [2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

If you are having trouble with list comprehensions, the same thing can be written this way:

threads=[]
for i in range(tPos):
    threads.append(Ts[0]+1 if i<Ts[1] else Ts[0])

Then to format it, do something like:

for i,e in enumerate(threads):
    print 'thread{} {}frames'.format(i,e)
于 2012-05-22T01:18:34.603 回答
0

这就是我最终使用的......谢谢你帮助大家。

frames=20 
tPos=16 
Ts=divmod(frames,tPos) 
threads=[] 
for i in range(tPos): 
    threads.append(Ts[0]+1 if i<Ts[1] else Ts[0])

start = 1
end = 0
x=1
while x <= (tPos):
    end = start +(threads[x-1]-1)
    print (start, "-", end)
    start = end + 1
    x+=1


prints:
1 - 2
3 - 4
5 - 6
7 - 8
9 - 9
10 - 10
11 - 11
12 - 12
13 - 13
14 - 14
15 - 15
16 - 16
17 - 17
18 - 18
19 - 19
20 - 20
于 2012-05-22T19:20:11.557 回答