随机交换(swap randomization)的python实现

随机交换内容可以看这:http://blog.csdn.net/lgnlgn/article/details/5936945


其实是直接翻译作者perl源码过来的... 作者perl源码在这:http://www.cs.helsinki.fi/hiit_bru/software/swaps/ 作者用的是self loop的实现方式。

不懂perl不过还是勉强看懂过程,python源码直接贴出来:


import sys
import random

g = {}
iref = []
jref = []
n = 0
rowc = 0


def swap():
    a = random.randint(0, n-1)
    b = random.randint(0, n-1)
    aj = jref[a]
    ai = iref[a]
    bj = jref[b]
    bi = iref[b]
    if g.get((aj, bi)) is None and g.get((bj, ai)) is None:
        ##delete edges
        g.pop((aj , ai))
        g.pop((bj , bi))
        ## add edges
        g[(aj, bi)] = a
        g[(bj, ai)] = b
        ## replace $ai with $bi and $bi with $ai
        iref[a] = bi
        iref[b] = ai
        return 1
    return 0
        


def main(dbpath, prefix, iterlen, loop):
    f = open(dbpath)
    global iref, jref, g , n , rowc
    for line in f.xreadlines():
        items = line.split()
        for item in items:
            i = int(item)
            g[(rowc, i)] = n
            jref.append(rowc)
            iref.append(i)
            n += 1
        rowc += 1
    f.close()
    swaps = 0
    i = 0
    size = iterlen * loop


    while i <= size:
        if i % iterlen == 0:
            k = 0
            row = []
            f = open("%s.%d.dat" %(prefix, i/iterlen) , 'w')
            for l in xrange(n+1):
                if l < n and k == jref[l]:
                    row.append(iref[l])
                else:
                    row.sort()
                    f.write(" ".join(map(str, row)) + "\n")
                    if l < n:
                        row = [iref[l]]
                        k = jref[l]
            f.close()
            if i >0:
                print "%d\t%d\t%.5f\t%.5f" %(i, swaps, (swaps+0.0)/i, (swaps+0.0)/n)
            else:
                print "0  0  0  0"


        swaps += swap()
        i += 1
            
if __name__ == '__main__':
    if not len(sys.argv) == 5:
        print "usage: EXE dbpath, prefix, iterlen, loops"
    else:
        main(sys.argv[1], sys.argv[2], int(sys.argv[3]), int(sys.argv[4]) )


变量名没完全沿用,jref是为每个item存行号用的,iref存的是item的id, db视为一个图结构g,(行号,id)作为map的key

程序首先读取数据集进内存,分别存在上述3个空间里。

迭代进行local swap操作,成功返回1,不成功返回0

当迭代达到iterlen的步数 输出swap后的db

在小本本上跑的 python代码和perl代码 时间差不多,内存python 少一些;也试过pypy1.4,速度更快一些但内存消耗大一些。

作者有c的实现,肯定效率更高, 

准备在jung里试试,图结构里直接swap, 另外有向边的swap也值得尝试~

-------------------

突然发现原来有个bug ,open("%s.%d.dat" %(prefix, i%iterlen) , 'w') 

%应该是/ 。否则一直输出到0。

java的也实现了一下,速度比Python快一倍多,但如果限制内存频繁GC,倒也快不了太多

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章