3

I attempted to implement Fortune's algorithm in Java, and to avoid writing an AVLTree I decided to use a TreeMap with BeachNode keys. BeachNode has the following code:

public abstract class BeachNode implements Comparable<BeachNode>{

static int idcounter=0;
int id;

public StatusNode(){
    //Allows for two nodes with the same coordinate
    id=idcounter;
    idcounter++;
}

@Override
public int compareTo(BeachNode s) {
    if(s.getX()<this.getX())
        return -1;
    if(s.getX()>this.getX())
        return 1;
    if(s.id<this.id)
        return 1;
    if(s.id>this.id)
        return -1;

    return 0;
}

public abstract double getX();
}

The getX() method of Intersection returns a value dependent on the present height of the sweep line- so it changes partway through execution.

My first question: (I'm fairly sure the answer is yes, but peace of mind would be nice)

If I ensure that for any two BeachNodes A and B, signum(A.compareTo(B)) remains constant while A and B are in the beach tree, will the TreeMap still function despite the changes underlying the compareTo?

My second question:

How can I ensure that such a contract is obeyed?

Note that in Fortune's algorithm, we track at what sweep line positions two intersections will meet- when the sweep line reaches one of these positions, one of the intersections is removed.

This means two intersections A and B in the beach tree will never cross positions, but during a CircleEvent A.compareTo(B) will return 0- interfering with processing the CircleEvent. The contract will be broken only briefly, during the CircleEvent that would remove one Intersection.

This is my first question on StackOverflow, if it is poorly posed or incomplete please inform me and I will do my best to rectify it.

1 Answer 1

1

According to the TreeMap documentation, the tree will be sorted according to the compareTo method, so any changes that are not reflected in the sign of a.compareTo(b) are allowed. However, you also need to implement an equals method with the same semantics as compareTo. This is really easy if you already have a compareTo method:

public boolean equals(Object object) {
    if (!(object instanceof BeachNode)) {
        return false;
    }
    BeachNode other = (BeachNode) object;
    return this.compareTo(other) == 0;
}

And, since you're overriding equals, you should override hashCode. This is also pretty easy, since you are only using a couple fields to define equality.

public int hashCode() {
    int hash = 1;
    hash = (17 * hash) + (Double getX()).hashCode());
    hash = (31 * hash) + id;
    return hash;
}

I'm not sure about your second question, but since the id of the two intersections should stay different, wouldn't they not be equal? If I'm wrong, hopefully someone who understands the algorithm can help you work that out.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.