- package ads1ss12.pa;
- import java.util.*;
- /**
- * Klasse zum Berechnen eines k-MST mittels Branch-and-Bound. Hier sollen Sie
- * Ihre Lösung implementieren.
- */
- public class KMST extends AbstractKMST {
- int numNodes, numEdges, k;
- TreeSet<Edge> ts_edges;
- TreeSet<Edge> kmst_tree;
- /**
- * Der Konstruktor. Hier ist die richtige Stelle für die
- * Initialisierung Ihrer Datenstrukturen.
- *
- * @param numNodes
- * Die Anzahl der Knoten
- * @param numEdges
- * Die Anzahl der Kanten
- * @param edges
- * Die Menge der Kanten
- * @param k
- * Die Anzahl der Knoten, die Ihr MST haben soll
- */
- public KMST(Integer numNodes, Integer numEdges, HashSet<Edge> edges, int k) {
- // TODO: Hier ist der richtige Platz fuer Initialisierungen
- this.numNodes=numNodes;
- this.numEdges=numEdges;
- this.ts_edges = new TreeSet<Edge>(edges);
- this.k=k;
- }
- /**
- * Diese Methode bekommt vom Framework maximal 30 Sekunden Zeit zur
- * Verfügung gestellt um einen gültigen k-MST zu finden.
- *
- * <p>
- * Fügen Sie hier Ihre Implementierung des Branch-and-Bound Algorithmus
- * ein.
- * </p>
- */
- @Override
- public void run() {
- // TODO: Diese Methode ist von Ihnen zu implementieren
- kmstSolution(ts_edges);
- ts_edges=removeLastEdges(ts_edges, this.getSolution().getUpperBound());
- doBnB(ts_edges, new TreeSet<Edge>(),0,0);
- }
- public TreeSet<Edge> removeLastEdges(TreeSet<Edge> edges, int upper){
- int sum=0, count=0;
- TreeSet<Edge> result = new TreeSet<Edge>(edges);
- /*for(Edge e : result){
- sum+=e.weight;
- if(++count==(k-2)){
- break;
- }
- }
- upper-=sum;*/
- while(result.last().weight>upper){
- result.pollLast();
- }
- return result;
- }
- public void doBnB(TreeSet<Edge> edges, TreeSet<Edge> removed, int numWith, int depth){
- TreeSet<Edge> kmst, tree;
- if(numWith>k-1) return;
- tree = new TreeSet<Edge>(edges);
- tree.removeAll(removed);
- int count = 0;
- int lowerBound = 0;
- for(Edge e: tree){
- lowerBound += e.weight;
- if(++count==this.k-1)
- break;
- }
- if(lowerBound>=getSolution().getUpperBound() || count != this.k-1)
- return;
- if((kmst = doPrim(tree, 0)) != null){
- int sum = 0;
- for(Edge e : kmst){
- sum += e.weight;
- }
- if(setSolution(sum,kmst)){
- ts_edges = removeLastEdges(ts_edges,sum);
- TreeSet<Edge> tmp = new TreeSet<Edge>(edges);
- tmp.removeAll(ts_edges);
- removed.addAll(tmp);
- }
- doBnB(new TreeSet<Edge>(edges), new TreeSet<Edge>(removed), numWith+1, depth+1);
- Edge edge = new Edge(0,0,0);
- count = 0;
- for(Edge e : edges){
- edge = e;
- if(count++== depth)
- break;
- }
- removed.add(edge);
- doBnB(new TreeSet<Edge>(edges), new TreeSet<Edge>(removed), numWith, depth+1);
- }
- }
- public void kmstSolution(TreeSet<Edge> edges){
- TreeSet<Edge> final_ts = new TreeSet<Edge>();
- int begin=0, sum=0;
- for(int j=0;j<edges.size()/2;j++){
- final_ts=doPrim(edges, begin);
- if(final_ts!=null){
- for(Edge e: final_ts){
- sum += e.weight;
- }
- if(begin>0){
- if(sum<=this.getSolution().getUpperBound()){
- this.setSolution(sum, new TreeSet<Edge>(final_ts));
- kmst_tree=new TreeSet<Edge>(final_ts);
- }
- }
- else{
- this.setSolution(sum, new TreeSet<Edge>(final_ts));
- kmst_tree=new TreeSet<Edge>(final_ts);
- }
- }
- begin++;
- sum=0;
- }
- }
- public TreeSet<Edge> doPrim(TreeSet<Edge> tree, int edgeNr){
- TreeSet<Edge> result = new TreeSet<Edge>();
- HashSet<Integer> intSet = new HashSet<Integer>();
- Edge edge = new Edge(0,0,0);
- if(edgeNr==0){
- edge = tree.first();
- intSet.add(edge.node1);
- intSet.add(edge.node2);
- }
- else{
- int count = 0;
- for(Edge e : tree){
- edge = e;
- if(count++ == edgeNr) break;
- }
- intSet.add(edge.node1);
- intSet.add(edge.node2);
- }
- result.add(edge);
- while(this.k-1 > result.size()){
- boolean found = false;
- for(Edge e: tree){
- boolean a = (intSet.contains(e.node1));
- boolean b = (intSet.contains(e.node2));
- if((a||b) && !(a&&b)){
- result.add(e);
- intSet.add(e.node1);
- intSet.add(e.node2);
- found = true;
- break;
- }
- }
- if(!found){
- return null;
- }
- }
- if(result.size()!=this.k-1 || intSet.size()!=this.k ){
- return null;
- }
- return result;
- }
- }