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; private TreeSet added; /** * 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; added=new TreeSet(); 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)); int[] moveLog=new int[list.size()]; addAllTransformations(x,moveLog); TreeSet newSet=new TreeSet(); double max=0; for(Skyline s : set)max=Math.max(max,verhouding(s)); for(Skyline s : set)if(verhouding(s)==max)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,int[] moveLog){ set.add(listToSkyline(list)); if(x!=0){ for(int i=0;i=0&&list.getBuilding(i).getLeft()-1>=leftBorder){ list.getBuilding(i).moveToLeft(); moveLog[i]++; if(added.add(list.toString()))addAllTransformations(x-1,moveLog); list.getBuilding(i).moveToRight(); moveLog[i]--; } if(moveLog[i]<=0&&list.getBuilding(i).getRight()+1<=rightBorder){ list.getBuilding(i).moveToRight(); moveLog[i]--; if(added.add(list.toString()))addAllTransformations(x-1,moveLog); list.getBuilding(i).moveToLeft(); moveLog[i]++; } } } } /*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 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)); } } }