我有X个正数,索引为x_i。每个x_i需要进入K组之一(其中K是预定的)。设S_j为K_j中所有x_i的总和。我需要分配所有x_i,以便最小化所有S_j的方差。什么算法实现了这个?我确定有一类算法可以解决这样的问题,但我不知道。
由于
答案 0 :(得分:1)
那是。鉴于此类大多数问题都是import numpy as np
import timeit
import matplotlib.pyplot as plt
CPUHz = 3.3e9
divpd_cycles = 4.5
L2cachesize = 2*2**20
L3cachesize = 8*2**20
def timeit_command(command, pieces, size):
return min(timeit.repeat("for i in xrange(%d): %s" % (pieces, command),
"import numpy; A = numpy.random.rand(%d)" % size, number = 6))
def run():
totaliterations = 1e7
commands=["A/=0.5", "A/=0.51", "A/0.5", "A*=2.0", "A*2.0", "A+=2.0"]
styles=['-', '-', '--', '-', '--', '-']
def draw_graph(command, style, compute_overhead = False):
sizes = []
y = []
for pieces in np.logspace(0, 5, 11):
size = int(totaliterations / pieces)
sizes.append(size * 8) # 8 bytes per double
time = timeit_command(command, pieces, (4 if compute_overhead else size))
# Divide by 2 because SSE instructions process two doubles each
cycles = time * CPUHz / (size * pieces / 2)
y.append(cycles)
if compute_overhead:
command = "numpy overhead"
plt.semilogx(sizes, y, style, label = command, linewidth = 2, basex = 10)
plt.figure()
for command, style in zip(commands, styles):
print command
draw_graph(command, style)
# Plot overhead
draw_graph("A+=1.0", '-', compute_overhead=True)
plt.legend(loc = 'best', prop = {'size':9}, handlelength = 3)
plt.xlabel('Array size in bytes')
plt.ylabel('CPU cycles per SSE instruction')
# Draw vertical and horizontal lines
ymin, ymax = plt.ylim()
plt.vlines(L2cachesize, ymin, ymax, color = 'orange', linewidth = 2)
plt.vlines(L3cachesize, ymin, ymax, color = 'red', linewidth = 2)
xmin, xmax = plt.xlim()
plt.hlines(divpd_cycles, xmin, xmax, color = 'blue', linewidth = 2)
,您不太可能找到有效的最优算法。
packing problem有一个简单的4/3 - 1 /(3K)近似算法(来自 Multiprocessor scheduling):
对数字进行排序,然后将它们分配给目前为止最小的组。