<p>我写了两个非常简单的实现。第一个方法使用deque从右和从左弹出(一旦列表被排序),将低值与高值放在一起。第二个是@Sean McSomething建议的。在</p>
<p>下面是代码(quick'n'dirty--不幸的是,很少有注释):</p>
<pre><code>import math
import itertools
import collections
def sum_column(data):
return sum(zip(*data)[1], 0.0)
def split_groups(sensors):
sensors.sort(key=lambda item: item[1], reverse=True)
per_group = len(sensors) // 12
average = sum_column(sensors) / len(sensors)
data = collections.deque(sensors)
groups = [[] for i in xrange(12)]
cycle = itertools.cycle(groups)
try:
while True:
current = cycle.next()
if len(current) == per_group - 1:
if sum_column(current) < average:
current.append(data.popleft())
else:
current.append(data.pop())
continue
current.append(data.popleft())
current.append(data.pop())
except IndexError:
return groups
def split_groups2(sensors):
sensors.sort(key=lambda item: item[1], reverse=True)
groups = [[] for i in xrange(12)]
cycle = itertools.cycle(groups)
per_group = int(math.ceil(len(sensors) / 3.))
partitions = [sensors[i:i + per_group] for i in xrange(0, len(sensors)
per_group)]
medium, low = map(reversed, partitions[1:])
for sensor, value in itertools.chain(partitions[0], medium, low):
cycle.next().append((sensor, value))
return groups
def format_groups(result):
ret = []
for group in result:
tmp = []
tmp.append('\n'.join('{0} {1}'.format(k, v) for k, v in group))
tmp.append(' ' * 8 + str(int(sum_column(group))))
ret.append('\n'.join(tmp))
return '\n\n'.join(ret)
if __name__ == '__main__':
import sys
implementation = split_groups
if '--second' in sys.argv:
sys.argv.remove('--second')
implementation = split_groups2
with open(sys.argv[1]) as fobj:
sensors = []
for line in fobj:
sensor, value = line.strip().split(', ')
sensors.append((sensor, int(value)))
sys.stdout.write(format_groups(split_groups(sensors)))
sys.stdout.write('\n')
</code></pre>
<p>要点也是:<br/>
<a href="https://gist.github.com/2703965" rel="nofollow">https://gist.github.com/2703965</a></p>
<p>我把最简单的部分(格式化)留给你了。现在,它只需垂直打印(而不是按您的要求打印)。应该不会太难。在</p>
<p>这是它所能达到的最佳效果(使用这两种实现):</p>
^{pr2}$
<p>这与示例相去甚远,但这只是一个开始。您可以使用文件名和可选的<code>--second</code>开关从命令行启动它(以使用第二个实现)。我可以使用命令行解析器,但我习惯于argparse,这在python2.4中没有。所以我就去做那个笨拙的黑客。在</p>
<p>示例运行:</p>
<pre><code>$ python2 groupit.py filename.txt
baaai 168
caaal 3
aaaaj 43
214
aaaac 150
aaaal 3
caaae 44
197
aaaae 144
aaaag 5
baaae 45
194
caaah 141
baaak 11
baaal 47
199
aaaad 135
aaaai 11
caaaj 59
205
baaad 111
aaaaf 12
caaaa 59
182
caaag 111
caaaf 16
baaah 68
195
aaaaa 100
baaaj 21
baaag 71
192
baaaf 99
baaaa 25
aaaab 75
199
caaak 89
caaad 33
caaac 77
199
aaaak 88
baaab 33
caaab 85
206
baaac 87
aaaah 34
caaai 87
208
$ python2 groupit.py --second filename.txt
baaai 168
caaal 3
aaaaj 43
214
aaaac 150
aaaal 3
caaae 44
197
aaaae 144
aaaag 5
baaae 45
194
caaah 141
baaak 11
baaal 47
199
aaaad 135
aaaai 11
caaaj 59
205
baaad 111
aaaaf 12
caaaa 59
182
caaag 111
caaaf 16
baaah 68
195
aaaaa 100
baaaj 21
baaag 71
192
baaaf 99
baaaa 25
aaaab 75
199
caaak 89
caaad 33
caaac 77
199
aaaak 88
baaab 33
caaab 85
206
baaac 87
aaaah 34
caaai 87
208
</code></pre>
<p>在问题的例子中,两种算法给出了完全相同的答案。如果你能提供更多的测试用例,我会努力改进它们。我在Python2.7上测试了脚本,因为我没有安装2.4。<br/>
抱歉回答太长了。在</p>