- 论坛徽章:
- 1
|
本帖最后由 jeppeter 于 2013-03-13 22:46 编辑
回复 1# lapertem44
下面是我测试过的代码,你可以再测试一下,如果有错,告诉我。- def ValidateAnts(l,a):
- lastone = 0.0
- for v in a:
- if abs(v) <= 0.0 or abs(v) >= l:
- raise Exception('error input %d for long %d'%(v,l))
- if abs(v) < abs(lastone):
- raise Exception('input value %d or ascending order'%(v))
- lastone = v
- def AntSplit(l,a):
- lastone = 0
- totalsize = 0
- pos = list()
- # we assume first one to be select
- lastsel = 1
- ValidateAnts(l,a)
- for i in xrange(1,len(a)+1):
- pos.append(i)
- cura = []
- for v in a:
- cura.append(float(v))
- logging.info('a is %s'%(repr(a)))
- while len(cura) > 0 :
- leastsize = l
- lastv = cura[0]
- if lastv < 0:
- leastsize = abs(lastv)
- for v in cura[1:]:
- # if we have 2 value
- # if we have the opposite direction
- # so we calcuate the most size to step when
- # we should test
- if lastv >0 and v < 0:
- size = (abs(v) - abs(lastv))/2
- if size < leastsize :
- leastsize = size
- lastv = v
- if cura[-1] > 0:
- size = l - abs(cura[-1])
- if size < leastsize:
- leastsize = size
- # now we do not met in the way
- if leastsize == l:
- if cura[0] > 0:
- # if it is the leftmost ,so it will
- lastsel = pos[0]
- # now to set the one
- totalsize += (l - cura[0])
- else:
- lastsel = pos[-1]
- # now to set the step
- totalsize += (l + cura[-1])
- break
- logging.info('leastsize %f'%(leastsize))
- # now to check for the
- curb = []
- lastone = cura[0]+leastsize
- for i in xrange(1,len(cura)):
- # now to modify the value
- v = cura[i] + leastsize
- if abs(lastone) == abs(v):
- # if we met ,so turn opposite
- lastone = -lastone
- v = -v
- #logging.info('push %f into curb v %f'%(lastone,v))
- curb.append(lastone)
- lastone = v
- # we append last one when nothing is on
- #logging.info('push %f into curb'%(lastone))
- curb.append(lastone)
- assert(len(curb) == len(cura))
- logging.info('len curb(%d) len cura (%d)'%(len(curb),len(cura)))
- logging.info('curb %s'%(repr(curb)))
- #assert(len(curb) == len(cura))
- totalsize += leastsize
- cura = []
- for i in xrange(0,len(curb)):
- v = curb[i]
- if abs(v) > 0 and abs(v) < l:
- cura.append(v)
- else:
- logging.info('delete %d %d'%(i,pos[i]))
- lastsel = pos[i]
- del pos[i]
- logging.info('cura %s'%(repr(cura)))
- logging.info('pos %s'%(repr(pos)))
-
- return lastsel,totalsize
复制代码 这里解释一下代码,
函数的输入参数是两个:
1, l 就是你前面所说的长度
2, a,就是你所说的要输入的数列。
这里的第11-22行是初始化一些参数,
生成 cura表示是我们要处理的数列,这里把数据变成float类型,是更好的把你的问题变成可能是因为会出现0.5的数字处理。
而pos就是一个数列,可以得到最后一个离开棒子的蚂蚁的初始位置
24-41 :计算,不引起数据变化的最大长度,这里要满足两个条件:
1, 没有蚂蚁走出棒子,换句话说,就是没有一个值abs(v) <= 0 or abs(v) >= l (棒子长度)
2, 没有蚂蚁要转向。
26-27 是因为,有可能最左边的蚂蚁是向左爬,那它可能不在棒子上,就是在最左边离棒子的距离。
33-36 是计算,如果两个蚂蚁是相向而行,也就是在左边的蚂蚁向右,而在右边的蚂蚁向左,则它们会在多少时间相遇。
38-41 是计算,如果最右边的蚂蚁向右爬,它可能不在棒子上,与最右边的距离。
以上的计算,就是得到当前引起变化的最小距离。
43-53 前面的计算,可能会得到最大值就是棒子的长度,(现在来看,不会出现),这个时候,就是已经结束了。这个值就是所有的蚂蚁向一个方向,或者是向左,或者是向右,
44-48 如果向右,则取最左边的蚂蚁距离最右端点的距离是步长。 而现在保留的最左边的蚂蚁当时的点就是最后一个蚂蚁的最初点。pos[0]
49-53 如果向左,则取最右边的蚂蚁距离最左端点的距离是步长。 而现在保留的最右边的蚂蚁当时的点就是最后一个蚂蚁的最初点。pos[-1]
57-70 生成因为改变了,下一次迭代所有的蚂蚁的位置与方向信息。
57 保留前一次,因为前一次,会与当前的有关系。
59-67 生成下一次的蚂蚁位置与方向。
60 这个就是得到当前的蚂蚁的位置,因为这个蚂蚁如果是-7+2 表示向右,前进2,那位置就是-5
61 如果两个蚂蚁碰头。这个是前一个(就是左边的蚂蚁)与后一个(就是右边的蚂蚁)相遇了,这个时候,要它们转向。
所以, 这个时候,要修改原来的符号,这样就转向了。
70 ,这个可能整个数据没有了,那就把最后一个加入。
75 加上了这一次引起变化,步长是多少。
76-85 这一次得到下一次迭代的蚂蚁位置。
79-80 ,如果蚂蚁不在边界的位置(也就是在棒子的两头),则加入下一次的迭代。
82-84 ,如果已经在边界的位置,则去除这个蚂蚁,它不在下一次迭代的范围内。
83 是表示最后一个离开棒子的蚂蚁的初始位置,在while循环之外会有用。
84 去除这个位置的信息,
上面的解释希望能对你有帮助。谢谢。 |
|