Program: 90303
Project: 90303
Buggy source:
/** 
 * This method uses an adapted greedy strategy for the fixed four position model, above, under left and right form the point of interest. It uses no priority search tree, because it will not function with symbols only with points. Instead it uses two minimum heaps. They work similar to a sweep line algorithm but have not a O(n log n +k) runtime. To find the rectangle that has the top edge, I use also a minimum Heap. The rectangles are sorted by their y coordinates.
 * @param labels label positions and text
 * @param symbols symbol positions
 * @param areaLabels area label positions and text
 * @return list of labels without overlaps with symbols and other labels by the four fixed position greedy strategy
 */
private List<PointTextContainer> processFourPointGreedy(List<PointTextContainer> labels,List<SymbolContainer> symbols,List<PointTextContainer> areaLabels,int tileSize){
  List<PointTextContainer> resolutionSet=new ArrayList<PointTextContainer>();
  ReferencePosition[] refPos=new ReferencePosition[(labels.size()) * 4];
  PriorityQueue<ReferencePosition> priorUp=new PriorityQueue<ReferencePosition>(labels.size() * 4 * 2 + labels.size() / 10 * 2,ReferencePositionYComparator.INSTANCE);
  PriorityQueue<ReferencePosition> priorDown=new PriorityQueue<ReferencePosition>(labels.size() * 4 * 2 + labels.size() / 10 * 2,ReferencePositionHeightComparator.INSTANCE);
  PointTextContainer tmp;
  int dis=START_DISTANCE_TO_SYMBOLS;
  for (int z=0; z < labels.size(); z++) {
    if (labels.get(z) != null) {
      if (labels.get(z).symbol != null) {
        tmp=labels.get(z);
        refPos[z * 4]=new ReferencePosition(tmp.x - tmp.boundary.getWidth() / 2,tmp.y - tmp.symbol.symbol.getHeight() / 2 - dis,z,tmp.boundary.getWidth(),tmp.boundary.getHeight());
        refPos[z * 4 + 1]=new ReferencePosition(tmp.x - tmp.boundary.getWidth() / 2,tmp.y + tmp.symbol.symbol.getHeight() / 2 + tmp.boundary.getHeight() + dis,z,tmp.boundary.getWidth(),tmp.boundary.getHeight());
        refPos[z * 4 + 2]=new ReferencePosition(tmp.x - tmp.symbol.symbol.getWidth() / 2 - tmp.boundary.getWidth() - dis,tmp.y + tmp.boundary.getHeight() / 2,z,tmp.boundary.getWidth(),tmp.boundary.getHeight());
        refPos[z * 4 + 3]=new ReferencePosition(tmp.x + tmp.symbol.symbol.getWidth() / 2 + dis,tmp.y + tmp.boundary.getHeight() / 2 - 0.1f,z,tmp.boundary.getWidth(),tmp.boundary.getHeight());
      }
 else {
        refPos[z * 4]=new ReferencePosition(labels.get(z).x - ((labels.get(z).boundary.getWidth()) / 2),labels.get(z).y,z,labels.get(z).boundary.getWidth(),labels.get(z).boundary.getHeight());
        refPos[z * 4 + 1]=null;
        refPos[z * 4 + 2]=null;
        refPos[z * 4 + 3]=null;
      }
    }
  }
  removeNonValidateReferencePosition(refPos,symbols,areaLabels,tileSize);
  for (int i=0; i < refPos.length; i++) {
    this.referencePosition=refPos[i];
    if (this.referencePosition != null) {
      priorUp.add(this.referencePosition);
      priorDown.add(this.referencePosition);
    }
  }
  while (priorUp.size() != 0) {
    this.referencePosition=priorUp.remove();
    this.label=labels.get(this.referencePosition.nodeNumber);
    resolutionSet.add(new PointTextContainer(this.label.text,this.referencePosition.x,this.referencePosition.y,this.label.paintFront,this.label.paintBack,this.label.symbol));
    if (priorUp.size() == 0) {
      return resolutionSet;
    }
    priorUp.remove(refPos[this.referencePosition.nodeNumber * 4 + 0]);
    priorUp.remove(refPos[this.referencePosition.nodeNumber * 4 + 1]);
    priorUp.remove(refPos[this.referencePosition.nodeNumber * 4 + 2]);
    priorUp.remove(refPos[this.referencePosition.nodeNumber * 4 + 3]);
    priorDown.remove(refPos[this.referencePosition.nodeNumber * 4 + 0]);
    priorDown.remove(refPos[this.referencePosition.nodeNumber * 4 + 1]);
    priorDown.remove(refPos[this.referencePosition.nodeNumber * 4 + 2]);
    priorDown.remove(refPos[this.referencePosition.nodeNumber * 4 + 3]);
    LinkedList<ReferencePosition> linkedRef=new LinkedList<ReferencePosition>();
    while (priorDown.size() != 0) {
      if (priorDown.peek().x < this.referencePosition.x + this.referencePosition.width) {
        linkedRef.add(priorDown.remove());
      }
 else {
        break;
      }
    }
    for (int i=0; i < linkedRef.size(); i++) {
      if ((linkedRef.get(i).x <= this.referencePosition.x + this.referencePosition.width) && (linkedRef.get(i).y >= this.referencePosition.y - linkedRef.get(i).height) && (linkedRef.get(i).y <= this.referencePosition.y + linkedRef.get(i).height)) {
        priorUp.remove(linkedRef.get(i));
        linkedRef.remove(i);
        i--;
      }
    }
    priorDown.addAll(linkedRef);
  }
  return resolutionSet;
}

Fixed version (ground truth):
/** 
 * This method uses an adapted greedy strategy for the fixed four position model, above, under left and right form the point of interest. It uses no priority search tree, because it will not function with symbols only with points. Instead it uses two minimum heaps. They work similar to a sweep line algorithm but have not a O(n log n +k) runtime. To find the rectangle that has the top edge, I use also a minimum Heap. The rectangles are sorted by their y coordinates.
 * @param labels label positions and text
 * @param symbols symbol positions
 * @param areaLabels area label positions and text
 * @return list of labels without overlaps with symbols and other labels by the four fixed position greedy strategy
 */
private List<PointTextContainer> processFourPointGreedy(List<PointTextContainer> labels,List<SymbolContainer> symbols,List<PointTextContainer> areaLabels,int tileSize){
  List<PointTextContainer> resolutionSet=new ArrayList<PointTextContainer>();
  ReferencePosition[] refPos=new ReferencePosition[(labels.size()) * 4];
  PriorityQueue<ReferencePosition> priorUp=new PriorityQueue<ReferencePosition>(labels.size() * 4 * 2 + labels.size() / 10 * 2,ReferencePositionYComparator.INSTANCE);
  PriorityQueue<ReferencePosition> priorDown=new PriorityQueue<ReferencePosition>(labels.size() * 4 * 2 + labels.size() / 10 * 2,ReferencePositionHeightComparator.INSTANCE);
  PointTextContainer tmp;
  int dis=START_DISTANCE_TO_SYMBOLS;
  for (int z=0; z < labels.size(); z++) {
    if (labels.get(z) != null) {
      if (labels.get(z).symbol != null) {
        tmp=labels.get(z);
        refPos[z * 4]=new ReferencePosition(tmp.x - (float)tmp.boundary.getWidth() / 2,tmp.y - (float)tmp.symbol.symbol.getHeight() / 2 - dis,z,tmp.boundary.getWidth(),tmp.boundary.getHeight());
        refPos[z * 4 + 1]=new ReferencePosition(tmp.x - (float)tmp.boundary.getWidth() / 2,tmp.y + (float)tmp.symbol.symbol.getHeight() / 2 + (float)tmp.boundary.getHeight() + dis,z,tmp.boundary.getWidth(),tmp.boundary.getHeight());
        refPos[z * 4 + 2]=new ReferencePosition(tmp.x - (float)tmp.symbol.symbol.getWidth() / 2 - tmp.boundary.getWidth() - dis,tmp.y + (float)tmp.boundary.getHeight() / 2,z,tmp.boundary.getWidth(),tmp.boundary.getHeight());
        refPos[z * 4 + 3]=new ReferencePosition(tmp.x + (float)tmp.symbol.symbol.getWidth() / 2 + dis,tmp.y + (float)tmp.boundary.getHeight() / 2 - 0.1f,z,tmp.boundary.getWidth(),tmp.boundary.getHeight());
      }
 else {
        refPos[z * 4]=new ReferencePosition(labels.get(z).x - (((float)labels.get(z).boundary.getWidth()) / 2),labels.get(z).y,z,labels.get(z).boundary.getWidth(),labels.get(z).boundary.getHeight());
        refPos[z * 4 + 1]=null;
        refPos[z * 4 + 2]=null;
        refPos[z * 4 + 3]=null;
      }
    }
  }
  removeNonValidateReferencePosition(refPos,symbols,areaLabels,tileSize);
  for (int i=0; i < refPos.length; i++) {
    this.referencePosition=refPos[i];
    if (this.referencePosition != null) {
      priorUp.add(this.referencePosition);
      priorDown.add(this.referencePosition);
    }
  }
  while (priorUp.size() != 0) {
    this.referencePosition=priorUp.remove();
    this.label=labels.get(this.referencePosition.nodeNumber);
    resolutionSet.add(new PointTextContainer(this.label.text,this.referencePosition.x,this.referencePosition.y,this.label.paintFront,this.label.paintBack,this.label.symbol));
    if (priorUp.size() == 0) {
      return resolutionSet;
    }
    priorUp.remove(refPos[this.referencePosition.nodeNumber * 4 + 0]);
    priorUp.remove(refPos[this.referencePosition.nodeNumber * 4 + 1]);
    priorUp.remove(refPos[this.referencePosition.nodeNumber * 4 + 2]);
    priorUp.remove(refPos[this.referencePosition.nodeNumber * 4 + 3]);
    priorDown.remove(refPos[this.referencePosition.nodeNumber * 4 + 0]);
    priorDown.remove(refPos[this.referencePosition.nodeNumber * 4 + 1]);
    priorDown.remove(refPos[this.referencePosition.nodeNumber * 4 + 2]);
    priorDown.remove(refPos[this.referencePosition.nodeNumber * 4 + 3]);
    LinkedList<ReferencePosition> linkedRef=new LinkedList<ReferencePosition>();
    while (priorDown.size() != 0) {
      if (priorDown.peek().x < this.referencePosition.x + this.referencePosition.width) {
        linkedRef.add(priorDown.remove());
      }
 else {
        break;
      }
    }
    for (int i=0; i < linkedRef.size(); i++) {
      if ((linkedRef.get(i).x <= this.referencePosition.x + this.referencePosition.width) && (linkedRef.get(i).y >= this.referencePosition.y - linkedRef.get(i).height) && (linkedRef.get(i).y <= this.referencePosition.y + linkedRef.get(i).height)) {
        priorUp.remove(linkedRef.get(i));
        linkedRef.remove(i);
        i--;
      }
    }
    priorDown.addAll(linkedRef);
  }
  return resolutionSet;
}