project euler 107

来源:互联网 发布:什么软件商城最好用 编辑:程序博客网 时间:2024/05/17 01:01

project euler 107

题目

原文

Minimal network
The following undirected network consists of seven vertices and twelve edges with a total weight of 243.
图一图一

The same network can be represented by the matrix below.
图二图二

However, it is possible to optimise the network by removing some edges and still ensure that all points on the network remain connected. The network which achieves the maximum saving is shown below. It has a weight of 93, representing a saving of 243 − 93 = 150 from the original network.
图三图三

Using network.txt (right click and ‘Save Link/Target As…’), a 6K text file containing a network with forty vertices, and given in matrix form, find the maximum saving which can be achieved by removing redundant edges whilst ensuring that the network remains connected.

简单翻译

最小连通网
如图一所示的无向网包含七个顶点和12条边,所有边的权重之和为243

相同的图可以用图二所示的矩阵表示

然而,可以通过移除一些不必要的边来优化图,使图仍然连通。对于上面的例子,最好的优化如图三所示。优化后的边的权重和为93,与原图相比,节省了150

使用network.txt,一个6k大小包含40个顶点的图,以及连接的边的权重值,找到最优的优化,并计算最优的优化节省了多少权重值

程序

使用最小连通图的Kruskal算法,python代码如下

def problem107():    connectedList = []    for i in range(0, 40):#初始化连通网        connectedList.append([])    def connected(parameters ):#判断当前边是否已经连通了        curempty = -1        for i in range(0, 40):            if (len(connectedList[i]) == 0):                curempty = i                break        key = parameters[0]        finda = False        findb = False        aindex = -1        bindex = -2        for i in range(0, 40):            if (finda == False):                finda = parameters[0] in connectedList[i]                if (finda):                    aindex = i            if (findb == False):                findb = parameters[1] in connectedList[i]                if (findb):                    bindex = i            if (finda and findb):                break        if (aindex == bindex):#已经连通,跳过            return True        if (aindex < 0 and bindex < 0):#没有记录,添加连通区域            connectedList[curempty].append(parameters[0])            connectedList[curempty].append(parameters[1])        elif (aindex > -1 and bindex > -1):#边的两个端点分别属于两个连通区域,将两个区域合并            connectedList[aindex] += connectedList[bindex]            connectedList[bindex] = []        elif (aindex > -1):#只找到一个定点所在的区域,将另一个定点添加到该区域            connectedList[aindex].append(parameters[1])        elif (bindex > -1):            connectedList[bindex].append(parameters[0])        return False    f = open('p107_network.txt')    curline = f.readline()  #跳过第一行    curline = f.readline()    alllist = []    cur = 1    total = 0    while curline:  #从第二行开始解析        temp = curline.split(',')        templist = []        for i in range(0, cur):            if temp[i] == '-':                continue            else:                tempvalue = int(temp[i])                total += tempvalue                templist = [cur, i, tempvalue]                alllist.append(templist)        cur += 1        curline = f.readline()    alllist.sort(key=lambda data : data[2])    #Kruskal    resultList = []    cur = 0    ret = 0    for i in range(0, len(alllist)):        if (connected(alllist[i]) == False):            resultList.append(alllist[i])            ret += alllist[i][2]            cur += 1            if (cur == 39):#需要39条边来连通40个顶点                break    print total - ret
0 0
原创粉丝点击