Project Euler 107:Minimal network 最小网络

时间:2022-09-12 05:02:02

Minimal network

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

Project Euler 107:Minimal network  最小网络

The same network can be represented by the matrix below.

  A B C D E F G
A - 16 12 21 - - -  
B 16 - - 17 20 - -  
C 12 - - 28 - 31 -  
D 21 17 28 - 18 19 23  
E - 20 - 18 - - 11  
F - - 31 19 - - 27  
G - - - 23 11 27 -  

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.

Project Euler 107:Minimal 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.


最小网络

下面这个无向网络包含有7个顶点和12条边,其总重量为243。

Project Euler 107:Minimal network  最小网络

这个网络也可以用矩阵的形式表示如下。

  A B C D E F G
A - 16 12 21 - - -  
B 16 - - 17 20 - -  
C 12 - - 28 - 31 -  
D 21 17 28 - 18 19 23  
E - 20 - 18 - - 11  
F - - 31 19 - - 27  
G - - - 23 11 27 -  

然而,我们其实可以优化这个网络,移除其中的一些边,同时仍然保证每个顶点之间都是连通的。节省重量最多的网络如下图所示,其总重量为93,相比原来的网络节省了243 ? 93 = 150。

Project Euler 107:Minimal network  最小网络

在这个6K的文本文件network.txt(右击并选择“目标另存为……”)中存放了一个包含有40个顶点的网络的连通矩阵。移除其中冗余的边,同时仍然保证每个顶点之间都是连通的,求最多能节省的重量。

解题

Prim算法 或者 kruskal 算法

Java

package Level4;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.TreeMap; public class PE0107{
static int[][] network = new int[40][40];
static int len = 40;
static int AllSum=0;
static int shortestSum =0;
public static void run(){
String filename = "src/Level4/p107_network.txt";
readData(filename);
AllSum = getArrSum();
System.out.println("所有元素的和:"+AllSum);
shortestSum = Prim();
System.out.println("最短路径的和:"+shortestSum);
System.out.println("路径之差:"+ (AllSum - shortestSum));
}
public static int Prim(){
ArrayList<Integer> known = new ArrayList<Integer>();
ArrayList<Integer> goods = new ArrayList<Integer>();
TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
known.add(0);
map.put(0, 0);
while(true){
int min = Integer.MAX_VALUE;
int index = -1;
int mapindex = -1;
for(int i=0;i<known.size();i++){
for(int j=0;j< len;j++){
int now = network[map.get(i)][j];
if(now < min && now!=-1 && !known.contains(j)){
min = now;
index = j;
mapindex = known.size();
}
}
}
goods.add(min);
known.add(index);
map.put(mapindex,index);
if( known.size() == len)
break;
}
int sum =0;
for(int i=0;i<goods.size() ;i++){
sum+=goods.get(i);
}
return sum;
}
public static int getArrSum(){
int sum = 0;
for(int i=0;i<network.length;i++){
for(int j=i+1;j<network[0].length;j++){
if(network[i][j]!=-1)
sum +=network[i][j];
}
}
return sum;
}
public static void StrToArr(int index,String line){
String[] strArr = line.split(","); for(int i=0;i<strArr.length;i++){
if(!strArr[i].equals("-")){
network[index][i] = Integer.parseInt(strArr[i]);
}else{
network[index][i] = -1;
}
}
}
public static void readData(String filename){
BufferedReader bufferedReader;
int index = 0;
try {
bufferedReader = new BufferedReader(new FileReader(filename));
String line ="";
try {
while((line = bufferedReader.readLine())!=null){
StrToArr(index,line);
index++;
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("文件没有数据");
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
System.out.println("没有发现文件");
}
}
public static void main(String[] args){
long t0 = System.currentTimeMillis();
run();
long t1 = System.currentTimeMillis();
long t = t1 - t0;
System.out.println("running time="+t/1000+"s"+t%1000+"ms");
}
}