/* * IvlComparator.java 2005-05-12 * * Dirk Ansorge, FernUniversitaet Hagen * */ package twodsack.util.comparator; import twodsack.setelement.datatype.*; import twodsack.util.collectiontype.*; import java.util.*; /** * This class implements a comparator for Intervals. It implements only one single method and is used with any kind of collections * that need comparators. The objects that are accepted by the {@link #compare(Object,Object)} method are of type {@link twodsack.util.collectiontype.MultiSetEntry}. * The objects stored in such * a MultiSetEntry must be of type {@link twodsack.util.collectiontype.Interval}. If not, an exception is thrown.

* The comparator's constructor needs a flag when construced: The meet flag indicates, how intervals which have the same * x coordinate are sorted. If meet==true, for two such intervals which have the same x coordinate and one is a left and the other * is a right interval, the left interval is defined to be smaller than the other one. If meet==true, the right interval is defined * to be smaller than the left interval. */ public class IvlComparator implements Comparator { /* * fields */ private boolean meet; /* * constructors */ /** * This constructor must not be used. */ private IvlComparator() {} /** * Constructs a new IvlComparator instance with a value for the flag meet. * * @param meet flag which tells how intervals with the same x coordinate shall be sorted */ public IvlComparator(boolean meet) { this.meet = meet; } /* * methods */ /** * Compares two objects and returns one of {0, 1, -1}. * Compares the objects stored in the MultiSetEntry types. For the compare operation, some rules are defined: *

    *
  1. An interval with a smaller x coordinate is always smaller than the other. *
  2. "blue" is considered to be smaller than "green". *
  3. If meet==true intervals are always sorted that way, that the most possible 'overlaps' of intervals occur; if meet==false * intervals are sorted such, that a minimal number of 'overlaps' occurs. *

* Returns 0, if both intervals are equal.

* Returns -1, if ino1.o is smaller.

* Returns 1 otherwise * * @param ino1 the first object * @param ino2 the second object * @return one of {0, 1, -1} as int * @throws WrongTypeException if ino1.o or ino2.o is not of type {@link twodsack.util.collectiontype.Interval} */ public int compare(Object ino1, Object ino2) throws WrongTypeException { //For three segments s1=(1,1,3,1),s2=(3,0,3,2),s3=(3,1,5,1), the order is //for meet=false (s1.r/l means right/left interval border): //s1.l,s1.r,s2.l,s2.r,s3.l,s3.r //for meet=true: //s1.l,s2.l,s3.l,s1.r,s2.r,s3.r if((((MultiSetEntry)ino1).value instanceof Interval) && (((MultiSetEntry)ino2).value instanceof Interval)) { Interval i1 = (Interval)(((MultiSetEntry)ino1).value); Interval i2 = (Interval)(((MultiSetEntry)ino2).value); if (meet) { if (!i1.x.equal(i2.x)) return i1.comp(i2); else { //intervals have same number if (i1.number == i2.number) if (i1.mark == "blueleft" || i1.mark == "greenleft") return -1; else return 1; else { //intervals have different numbers; compare for buddy flag if (!i1.buddyOnSameX && i2.buddyOnSameX) if (i2.mark == "blueleft" || i2.mark == "greenleft") return 1; else return -1; else if ((i1.buddyOnSameX && i2.buddyOnSameX) || (!i1.buddyOnSameX && !i2.buddyOnSameX)) { if (i1.mark == i2.mark) return i1.comp(i2); else if ((i1.mark == "blueleft" || i1.mark == "greenleft") && (i2.mark == "blueleft" || i2.mark == "greenleft")) if (i1.mark == "blueleft") return -1; else return 1; else if ((i1.mark == "blueright" || i1.mark == "greenright") && (i2.mark == "blueright" || i2.mark == "greenright")) if (i1.mark == "blueright") return -1; else return 1; else if ((i1.mark == "blueleft" || i1.mark == "greenleft") && (i2.mark == "blueright" || i2.mark == "greenright")) return -1; else return 1; }//else if else if (i1.buddyOnSameX && !i2.buddyOnSameX) if (i1.mark == "blueleft" || i1.mark == "greenleft") return -1; else return 1;//-1; }//else }//else System.out.println("IvlComparator: Uncaught case."); i1.print(); i2.print(); throw new RuntimeException("An error occurred in the ROSEAlgebra."); }//if meet else { if (!i1.x.equal(i2.x)) return i1.comp(i2); else { //intervals have same number if (i1.number == i2.number) if (i1.mark == "blueleft" || i1.mark == "greenleft") return -1; else return 1; else { //intervals have different numbers; compare for buddy flag if (!i1.buddyOnSameX && i2.buddyOnSameX) if (i1.mark == "blueleft" || i1.mark == "greenleft") return 1; else return -1; else if ((!i1.buddyOnSameX && !i2.buddyOnSameX) || (i1.buddyOnSameX && i2.buddyOnSameX)) if (((i1.mark == "blueleft" || i1.mark == "greenleft") && (i2.mark == "blueleft" || i2.mark == "greenleft")) || ((i1.mark == "blueright" || i1.mark == "greenright") && (i2.mark == "blueright" || i2.mark == "greenright"))) return i1.comp(i2); else if (i1.mark == "blueleft" || i1.mark == "greenleft") return 1; else return -1; else if (i1.buddyOnSameX && !i2.buddyOnSameX) if (i2.mark == "blueleft" || i2.mark == "greenleft") return -1; else return 1; }//else }//else System.out.println("IvlComparator: Uncaught case."); i1.print(); i2.print(); throw new RuntimeException("An error occurred in the ROSEAlgebra."); }//else if meet }//if else throw new WrongTypeException("Exception in IvlComparator: Expected type Interval - found: "+((MultiSetEntry)ino1).value.getClass()+"/"+((MultiSetEntry)ino2).value.getClass()); }//end method compare }//end class IvlComparator