博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
作业分析,Karger最小割:(python)Engineering: Algorithms1 - SELF PACED Algorithms: Design and Analysis...
阅读量:4631 次
发布时间:2019-06-09

本文共 5366 字,大约阅读时间需要 17 分钟。

Programming Assignment 3

1/1 point (graded)

Download the following text file (right click and select "Save As..."): 

The file contains the adjacency list representation of a simple undirected graph. There are 200 vertices labeled 1 to 200. The first column in the file represents the vertex label, and the particular row (other entries except the first column) tells all the vertices that the vertex is adjacent to. So for example, the 6th row looks like : "6 155 56 52 120 ......". This just means that the vertex with label 6 is adjacent to (i.e., shares an edge with) the vertices with labels 155,56,52,120,......,etc

Your task is to code up and run the randomized contraction algorithm for the min cut problem and use it on the above graph to compute the min cut. (HINT: Note that you'll have to figure out an implementation of edge contractions. Initially, you might want to do this naively, creating a new graph from the old every time there's an edge contraction. But you should also think about more efficient implementations.) (WARNING: As per the video lectures, please make sure to run the algorithm many times with different random seeds, and remember the smallest cut that you ever find.) Write your numeric answer in the space provided. So e.g., if your answer is 5, just type 5 in the space provided.

 

 

目前已经得到正确答案,把解决问题的思路记录一下:

 

1,读取文件

file = open("你的路径/kargerMinCut.txt",'r')dic = {}i = 1str = ''for line in file:    dic[i] = []    for char in line:        if (char == "\t" or char == "\n") and str != "":            dic[i].append(int(str))            str = ""        if char != "\t" and char != "\n":            str += char    i += 1for j in range(1,i):    dic[j] = dic[j][1:]

 

这里犯了个小错误:‘\n’ ‘\t’ 只是一个字符

最后结果是把文件内容读到一个dict里面,key是node的名字1-200,value是一个list,存储图的连接信息。

 

2,建立数据库

为了避免每次运行代码都做一个新的图,这里我一共用了3个list同时更新:存储节点或者合并过的节点的archive,存储node是否在当前图里的activation,存储每个node的邻居的neighbor

activation = []for j in range(len(dic)):    activation.append(True)act_num = len(dic)
ii = len(dic) + 1archive = []for j in range(1,ii):    archive.append({j})
neighbor = []for j in range(len(dic)):    neighbor.append(dic[j+1])

 

 

3,开始运行Karger算法

 

3,1初始化几个变量

act_num = len(activation)min_lib_element = 0min_lib = -1length = len(neighbor)

 

act_num表示现在还剩下的有效node的个数,一开始是200

min_lib_element表示这次循环的链接数结果

min_lib表示目前运行过的循环,最小链接数结果

length表示初始的长度,用于每次循环开始前的activation和act_num的初始化

 

3,2随机选择两个nodes

这里需要随机选node1和node2两个变量,形式是{1}或者{50,57,75,199}这样,

首先看node1,从1-act_num随机选一个int出来叫index,然后到activation里面找第index个True的元素,对应在archive里面的元素就是node1

然后看node1的neighbor,随机选一个出来,但这里选的neighbor不一定在activation里面对应True,所以需要循环activation表,找到坐标k,使得activation[k]为True,这个neighbor又在archive[k]里面,那么这个archive[k]就是node2

 

其中找node1时候用到的函数如下:

def find_true(activation,archive,index):    i = 0    for k in range(len(activation)):        if activation[k] == True:            i += 1        else:            continue        if i == index:            return archive[k]

 

 

3,3如何处理nodes合并

举个例子:

node NO.1和node NO.2合并以后的

archive:[{1},{2},{3},...,{200},{1,2}]

activation:[False,False,True,...,True,True]

neighbor前200个元素来自第一步的dic,后面需要写一个函数来计算任意两个nodes组合以后新的neighbor。当然,如果组合之后新的node已经在archive里面了,那就直接调用之前计算的结果。

 

合并函数如下:

def contract(node1,node2,archive,activation,act_num,neighbor):    activation[archive.index(node1)] = False    activation[archive.index(node2)] = False    node_temp = node1|node2    if node_temp not in archive:        archive.append(node_temp)        activation.append(True)        combine_node(node1,node2,neighbor)    else:        activation[archive.index(node_temp)] = True    for x in node_temp:        activation[archive.index({x})] = False    act_num -= 1    return act_num

 

 

 

如果这个组合是新的,那么需要在上面那个函数里嵌套使用这个函数来更新neighbor表:

def combine_node(node1,node2,neighbor):    same = list(node1)+list(node2)    temp = []    for n1 in node1:        for nbr in neighbor[n1-1]:            if nbr not in temp and nbr not in same:                temp.append(nbr)                    for n2 in node2:        for nbr in neighbor[n2-1]:            if nbr not in temp and nbr not in same:                temp.append(nbr)    neighbor.append(temp)

 

 

3,4 循环

for _ in range(你想循环的次数):       #initialization    for j in range(length):        activation[j] = True    for j in range(length,len(activation)):        activation[j] = False    act_num = copy.deepcopy(length)   # 只要保持激活的节点还有2个以上,那就继续缩并节点    while(act_num > 2):        index = random.randint(1,act_num)        node1 = find_true(activation,archive,index)        pseudo_node2_index = random.choice(neighbor[archive.index(node1)])- 1        if activation[pseudo_node2_index] == True:            node2 = archive[pseudo_node2_index]        else:            for k in range(len(activation)):                if activation[k] == True and list(archive[pseudo_node2_index])[0] in archive[k]:                    node2 = archive[k]        act_num = contract(node1,node2,archive,activation,act_num,neighbor)    node = []    for k in range(len(activation)):        if activation[k] == True:            node.append(archive[k])    for n1 in node[0]:        for n2 in node[1]:            if {n1,n2} in libedge:                min_lib_element += 1    if min_lib < 0:        min_lib = min_lib_element    elif min_lib_element < min_lib:        min_lib = min_lib_element    min_lib_element = 0

 

 

 

#最后执行以下这个,看结果print(min_lib)

 

 

 

结束!结果是17

 

 

4,总结:

做到后面发现用pandas来做,代码可能可以更精简

 

转载于:https://www.cnblogs.com/ecoflex/p/9235130.html

你可能感兴趣的文章
PAT_B_1027 打印沙漏
查看>>
POJ-1185 炮兵阵地 动态规划+状态压缩
查看>>
NYOJ 366 D的小L
查看>>
PYTHON 写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者...
查看>>
Docker 初识
查看>>
【12.16】VC++调用Word OLE进行自动化生成报表
查看>>
用Maven创建第一个web项目
查看>>
php中的抽象类(abstract class)和接口(interface)
查看>>
linux安装ActiveMQ
查看>>
面向对象与软件工程---团队作业1
查看>>
认识一下Kotlin语言,Android平台的Swift
查看>>
Selenium2(WebDriver)总结(二)---Firefox的firebug插件参数设置(补充)
查看>>
spring中实现自己的初始化逻辑
查看>>
Accommodation development for Kaikoura
查看>>
Oracle11.2新特性之listagg函数 (行列转换)
查看>>
Flutter学习之动态ListView
查看>>
myeclipse中安装svn插件
查看>>
微信小程序----调用用户信息
查看>>
Ubuntu系统---安NVIDIA 驱动后 CUDA+cuDNN 安装
查看>>
Spring Boot配置全局异常捕获
查看>>