package skyline; import java.util.TreeSet; /** * Klasse die het algoritme implementeert om een optimale stad te bouwen. * Het is NIET toegelaten bestaande methodes en/of signaturen te wijzigen, maar * het staat je vrij naar behoefte methodes en velden toe te voegen. * @author Timbermont Bouke **/ public class SkylineSolver{ private BuildingList list; private double o,l; private TreeSet set; private int leftBorder,rightBorder; private double orgineleVerhouding; /** * Creeert een nieuwe instantie van SkylineSolver met gegeven * lijst van Buildings. * @param list de Buildings die gebruikt moeten worden. **/ public SkylineSolver(BuildingList list) { this.list=list; set=new TreeSet(); leftBorder=listToSkyline(list).coords[0]; rightBorder=listToSkyline(list).coords[listToSkyline(list).coords.length-2]; } /** * Geeft een lijst van optimale Skylines terug. * @param o Vrij in te stellen parameter O uit de opgave * @param l Vrij in te stellen parameter L uit de opgave * @param x Maximaal aantal verschuivingen **/ public TreeSet getOptimalSkylines(double o, double l, int x) { this.o=o; this.l=l; orgineleVerhouding=verhouding(listToSkyline(list)); System.out.println("org verh: "+orgineleVerhouding); addAllTransformations(x); TreeSet newSet=new TreeSet(); for(Skyline s : set)if(verhouding(s)>orgineleVerhouding)newSet.add(s); return newSet; } /*Deze methode voegt in onze treeset alle verschillende skylines in op *recursieve wijze. Wanneer een skyline reeds is toegevoegd of buiten de *stadsgrenzen valt, wordt de methode niet verder opgeroepen. */ private void addAllTransformations(int x){ boolean check=set.add(listToSkyline(list)); if(check&&x!=0){ for(int i=0;i=leftBorder){ list.getBuilding(i).moveToLeft(); addAllTransformations(x-1); list.getBuilding(i).moveToRight(); } if(list.getBuilding(i).getRight()+1<=rightBorder){ list.getBuilding(i).moveToRight(); addAllTransformations(x-1); list.getBuilding(i).moveToLeft(); } } } } /*De volgende methode neemt een skyline en berekent ervan de verhouding *die aangeeft in hoeverre die skyline ideaal is. */ public double verhouding(Skyline s){ double teller=s.getSurface()-Math.min((double)s.getSurface(),o); double len=s.coords[s.coords.length-2]-s.coords[0]; double noemer=1+len-Math.min(len,l); return teller/noemer; } /*De volgende mthode neemt een buildinglist en maakt er een skyline van op *recursieve wijze. */ public static Skyline listToSkyline(BuildingList list){ if(list.size()>1){ BuildingList[] halflist=new BuildingList[2]; halflist[0]=new BuildingList(); halflist[1]=new BuildingList(); int i=0; for(Building building:list){ halflist[i%2].addBuilding(building); i++; } return Skyline.merge(listToSkyline(halflist[0]),listToSkyline(halflist[1])); }else{ return new Skyline(list.getBuilding(0)); } } }