Example usage for com.google.common.collect TreeMultimap get

List of usage examples for com.google.common.collect TreeMultimap get

Introduction

In this page you can find the example usage for com.google.common.collect TreeMultimap get.

Prototype

@Override
@GwtIncompatible("NavigableSet")
public NavigableSet<V> get(@Nullable K key) 

Source Link

Usage

From source file:io.github.egonw.analysis.StructuralAnalysis.java

private void makeConnections(RichAtomSet atomSet, TreeMultimap<String, String> connectionsSet) {
    for (String key : connectionsSet.keySet()) {
        NavigableSet<String> allConnections = connectionsSet.get(key);
        SortedSet<String> sharedAtoms = new TreeSet<String>(new CMLNameComparator());
        for (String bond : allConnections.descendingSet()) {
            if (!this.isBond(bond)) {
                break;
            }//from  w  w w.  j a v a  2  s .  c  o m
            atomSet.getConnections().add(new SharedBond(bond, key));
            for (IAtom atom : this.getRichBond(bond).getStructure().atoms()) {
                sharedAtoms.add(atom.getID());
            }
        }
        for (String shared : sharedAtoms) {
            atomSet.getConnections().add(new BridgeAtom(shared, key));
        }
        Boolean ring = RichAtomSet.isRing(atomSet);
        for (String connection : Sets.difference(allConnections, sharedAtoms)) {
            if (!this.isAtom(connection)) {
                break;
            }
            if (ring && RichAtomSet.isRing(this.getRichAtomSet(key))) {
                atomSet.getConnections().add(new SpiroAtom(connection, key));
            } else {
                atomSet.getConnections().add(new SharedAtom(connection, key));
            }
        }
    }
}

From source file:org.kalypso.ui.rrm.internal.cm.LinearSumHelper.java

private static FactorElement[] modifyFactors(final int[] factors, final int sumFactors) {
    /* Keep the order of the factors. */
    final FactorElement[] elements = new FactorElement[factors.length];

    /* HINT: The index makes the object unique, because factors may be equal. */
    /* HINT: The index will be used in the compare method in the factor element. */
    /* HINT: This method is used by the tree multimap to determine equivalence. */
    for (int i = 0; i < factors.length; i++)
        elements[i] = new FactorElement(factors[i], i);

    /* Calculate the difference to 100. */
    int difference = sumFactors - 100;
    if (difference == 0)
        return elements;

    /* The sign of the difference. */
    int signum = 1;
    if (difference < 0)
        signum = -1;/*from w  w w .  j  av a 2s .  co m*/

    /* This sorted map allows a key with multiple values. */
    final TreeMultimap<Double, FactorElement> map = TreeMultimap.create();

    /* Fill the sorted map. */
    for (final FactorElement element : elements) {
        /* HINT: If the sum is greater than 100 we want to substract values from the smallest factors first. */
        /* HINT: Multiplying the factors (used as keys) with the signum */
        /* HINT: results in a normal ordered list with positive keys. */
        /* HINT: If the sum is smaller than 100 we want to add values to the greatest factors first. */
        /* HINT: Multiplying the factors (used as keys) with the signum */
        /* HINT: results in a reversed list with negative keys. */
        final int factor = signum * element.getFactor();

        /* Put the key and the value. */
        map.put(new Double(factor), element);
    }

    /* HINT: Now the keys of the map will be sorted by their natural order. */
    /* HINT: Now the values of the map will be sorted by the natural order of the index. */
    /* HINT: Only relevant if a key has more than one value. */

    /* Calculate the modification value. */
    final int mod = -1 * signum;

    /* Finally change the factors... */
    final Double[] keys = map.keySet().toArray(new Double[] {});
    for (final Double key : keys) {
        /* HINT: Here the elements will be sorted by the natural order of the index. */
        final SortedSet<FactorElement> sortedSet = map.get(key);
        for (final FactorElement factorElement : sortedSet) {
            /* Ignore 0.0 factors. */
            final int factor = factorElement.getFactor();
            if (factor == 0.0)
                continue;

            /* Adjust the factor. */
            factorElement.setFactor(factor + mod);

            /* Adjust the difference. */
            difference = difference + mod;

            /* Nothing more to do. */
            if (difference == 0)
                return elements;
        }
    }

    return elements;
}

From source file:eu.lp0.cursus.scoring.scores.impl.GenericRacePositionsData.java

@Override
protected LinkedListMultimap<Integer, Pilot> calculateRacePositionsWithOrder(Race race) {
    // Create a lap order list containing all pilots
    List<Pilot> lapOrder = new ArrayList<Pilot>(scores.getPilots().size());
    lapOrder.addAll(scores.getLapOrder(race));
    Set<Pilot> pilotsWithLaps = ImmutableSet.copyOf(lapOrder);
    SortedSet<Pilot> pilotsWithoutLaps = new TreeSet<Pilot>(new PilotRaceNumberComparator());
    pilotsWithoutLaps.addAll(Sets.difference(scores.getPilots(), pilotsWithLaps));
    lapOrder.addAll(pilotsWithoutLaps);/*from  w  w  w .  jav  a2  s .  c o  m*/

    // Add penalties to race points
    Map<Pilot, Integer> racePoints = scores.getRacePoints(race);
    Map<Pilot, Integer> racePenalties = scores.getRacePenalties(race);
    Map<Pilot, Integer> racePointsWithPenalties = new HashMap<Pilot, Integer>(scores.getPilots().size() * 2);
    for (Pilot pilot : scores.getPilots()) {
        racePointsWithPenalties.put(pilot, racePoints.get(pilot) + racePenalties.get(pilot));
    }

    // Invert race points with ordered lists of pilots
    TreeMultimap<Integer, Pilot> invRacePoints = TreeMultimap.create(Ordering.natural(),
            Ordering.explicit(lapOrder));
    Multimaps.invertFrom(Multimaps.forMap(racePointsWithPenalties), invRacePoints);

    // Calculate race positions
    LinkedListMultimap<Integer, Pilot> racePositions = LinkedListMultimap.create();
    LinkedList<SortedSet<Pilot>> pilotPointsOrdering = new LinkedList<SortedSet<Pilot>>();
    int position = 1;

    if (simulatedToEnd) {
        Set<Pilot> simulatedRacePoints = scores.getSimulatedRacePoints(race);
        for (Integer points : invRacePoints.keySet()) {
            SortedSet<Pilot> pilots = Sets.filter(invRacePoints.get(points),
                    Predicates.not(Predicates.in(simulatedRacePoints)));
            if (!pilots.isEmpty()) {
                pilotPointsOrdering.add(pilots);
            }
        }
        for (Integer points : invRacePoints.keySet()) {
            SortedSet<Pilot> pilots = Sets.filter(invRacePoints.get(points),
                    Predicates.in(simulatedRacePoints));
            if (!pilots.isEmpty()) {
                pilotPointsOrdering.add(pilots);
            }
        }
    } else {
        for (Integer points : invRacePoints.keySet()) {
            pilotPointsOrdering.add(invRacePoints.get(points));
        }
    }

    for (SortedSet<Pilot> pilots : pilotPointsOrdering) {
        switch (equalPositioning) {
        case ALWAYS:
            // Always put pilots with the same points in the same position
            racePositions.putAll(position, pilots);
            position += pilots.size();
            break;

        case WITHOUT_LAPS:
            // Add everyone with laps (by removing pilots without laps from the set) in separate positions
            for (Pilot pilot : Sets.difference(pilots, pilotsWithoutLaps)) {
                racePositions.put(position, pilot);
                position++;
            }

            // Add everyone without laps (by removing pilots with laps from the set) in the same position
            Set<Pilot> pilots2 = Sets.difference(pilots, pilotsWithLaps);
            racePositions.putAll(position, pilots2);
            position += pilots2.size();
            break;

        case NEVER:
            // Always put pilots with the same points in separate positions
            for (Pilot pilot : pilots) {
                racePositions.put(position, pilot);
                position++;
            }
            break;
        }
    }

    return racePositions;
}

From source file:se.sics.caracaldb.paxos.Paxos.java

private View consistentQuorum(Instance i) {
    SortedSet<Accepted> acceptors = acceptedSet.get(i);
    if (acceptors.size() < quorum) {
        return null; // can abort early here
    }/* ww w.  j av  a2s .c o  m*/
    TreeMultimap<View, Address> quorums = TreeMultimap.create();
    for (Accepted acc : acceptors) {
        quorums.put(acc.view, acc.getSource());
        if (quorums.get(acc.view).size() >= quorum) {
            return acc.view;
        }
    }
    return null;
}

From source file:com.publictransitanalytics.scoregenerator.output.SectorReachInformation.java

public SectorReachInformation(final Set<MovementPath> bestPaths, final int count,
        final Set<LocalDateTime> reachTimes) throws InterruptedException {

    reachCount = count;/*from   w w w  .  ja  v a2 s  .c o m*/
    this.reachTimes = reachTimes.stream().map(time -> time.toLocalTime().toString())
            .collect(Collectors.toSet());

    final TreeMultimap<Integer, SimplePath> frequencyMap = TreeMultimap.create(Integer::compareTo,
            (p1, p2) -> p1.toString().compareTo(p2.toString()));

    if (bestPaths != null) {
        final ImmutableMultiset.Builder<SimplePath> bestSimplePathsBuilder = ImmutableMultiset.builder();
        for (final MovementPath bestPath : bestPaths) {
            bestSimplePathsBuilder.add(new SimplePath(bestPath));
        }
        final ImmutableMultiset<SimplePath> bestSimplePaths = bestSimplePathsBuilder.build();

        for (final SimplePath path : bestSimplePaths.elementSet()) {
            frequencyMap.put(bestSimplePaths.count(path), path);
        }

        pathCounts = new LinkedHashMap<>();
        for (final Integer frequency : frequencyMap.keySet().descendingSet()) {
            final NavigableSet<SimplePath> pathsForFrequency = frequencyMap.get(frequency);
            for (final SimplePath pathForFrequency : pathsForFrequency) {
                pathCounts.put(pathForFrequency, frequency);
            }
        }
    } else {
        pathCounts = null;
    }
}

From source file:sadl.models.pdrta.PDRTA.java

private PDRTA(TreeMultimap<Integer, String> trans, TreeMultimap<Integer, String> stats, PDRTAInput inp) {

    input = inp;/*w  w w  .  j  a  v a 2  s  . com*/
    states = new TIntObjectHashMap<>();

    for (final Integer idxInt : trans.keySet()) {
        final int idx = idxInt.intValue();
        final StateStatistic s = StateStatistic.reconstructStat(input.getAlphSize(), getHistSizes(),
                stats.get(idxInt));
        states.put(idx, new PDRTAState(this, idx, s));
    }
    for (final Entry<Integer, String> eT : trans.entries()) {
        // 75 -> 76 [ label = "0 [3, 989] p=1.0" ];
        final String[] split = eT.getValue().split(" ");
        final int source = Integer.parseInt(split[0]);
        final int target = Integer.parseInt(split[2]);
        final String sym = split[6].substring(1);
        final int begin = Integer.parseInt(split[7].substring(1, split[7].length() - 1));
        final int end = Integer.parseInt(split[8].substring(0, split[8].length() - 1));
        double prob;
        if (split[9].endsWith("\"")) {
            prob = Double.parseDouble(split[9].substring(2, split[9].length() - 1));
        } else {
            prob = Double.parseDouble(split[9].substring(2));
        }
        final PDRTAState s = states.get(source);
        PDRTAState t;
        if (!states.containsKey(target)) {
            final StateStatistic st = StateStatistic.reconstructStat(getAlphSize(), getHistSizes(),
                    stats.get(new Integer(target)));
            t = new PDRTAState(this, target, st);
            states.put(target, t);
        } else {
            t = states.get(target);
        }
        Interval in = s.getInterval(input.getAlphIndex(sym), end);
        assert (in != null);
        assert (in.getTarget() == null);
        assert (s.getStat().getTransProb(input.getAlphIndex(sym), in) == 0.0);
        assert (in.contains(begin));
        Interval newIn;
        if (end < in.getEnd()) {
            newIn = in.split(end);
            s.getIntervals(input.getAlphIndex(sym)).put(new Integer(newIn.getEnd()), newIn);
            in = newIn;
        }
        if (begin > in.getBegin()) {
            newIn = in.split(begin - 1);
            s.getIntervals(input.getAlphIndex(sym)).put(new Integer(newIn.getEnd()), newIn);
        }
        in.setTarget(t);
        s.getStat().addInterval(input.getAlphIndex(sym), in, prob);
    }
    root = states.get(0);
}

From source file:org.apromore.similaritysearch.common.algos.GraphEditDistanceGreedy.java

public Set<TwoVertices> compute(Graph sg1, Graph sg2) {
    init(sg1, sg2);//ww  w  .  ja  va 2s  . co  m

    //INIT
    BestMapping mapping = new BestMapping();
    Set<TwoVertices> openCouples = times(sg1.getVertices(), sg2.getVertices(), ledcutoff);
    double shortestEditDistance = Double.MAX_VALUE;
    Random randomized = new Random(123456789);
    int stepn = 0;
    //STEP
    boolean doStep = true;
    while (doStep) {
        doStep = false;
        stepn++;
        Vector<TwoVertices> bestCandidates = new Vector<TwoVertices>();
        double newShortestEditDistance = shortestEditDistance;
        for (TwoVertices couple : openCouples) {
            double newEditDistance = this.editDistance(mapping, couple);
            if (newEditDistance < newShortestEditDistance) {
                bestCandidates = new Vector<TwoVertices>();
                bestCandidates.add(couple);
                newShortestEditDistance = newEditDistance;
            } else if (newEditDistance == newShortestEditDistance) {
                bestCandidates.add(couple);
            }
        }

        if (bestCandidates.size() > 0) {
            TwoVertices couple;

            // Case 1: Only one candidate pair
            if (bestCandidates.size() == 1) {
                couple = bestCandidates.firstElement();
            } else {
                //  CASE 2: Lexicographical order is enough
                TreeMultimap<String, TwoVertices> tmap = TreeMultimap.create();
                for (TwoVertices pair : bestCandidates) {
                    String label1 = sg1.getVertexLabel(pair.v1);
                    String label2 = sg2.getVertexLabel(pair.v2);
                    if (label1 != null && label2 != null && label1.compareTo(label2) > 0) {
                        String tmp = label1;
                        label1 = label2;
                        label2 = tmp;
                    }
                    tmap.put(label1 + label2, pair);
                }
                String firstkey = tmap.keySet().first();

                if (tmap.get(firstkey).size() == 1) {
                    couple = tmap.get(firstkey).first();
                } else if (tmap.get(firstkey).size() > 1) {
                    Set<TwoVertices> set = tmap.get(firstkey);
                    TreeMultimap<String, TwoVertices> tmapp = TreeMultimap.create();

                    String label1;
                    String tmpLabel;
                    TreeMultiset<String> mset = TreeMultiset.create();
                    for (TwoVertices pair : set) {
                        label1 = sg1.getVertexLabel(pair.v1);
                        mset.clear();
                        for (Vertex n : sg1.getPreset(pair.v1)) {
                            tmpLabel = sg1.getVertexLabel(n.getID());
                            if (tmpLabel != null) {
                                mset.add(tmpLabel);
                            }
                        }
                        label1 += mset.toString();
                        mset.clear();
                        for (Vertex n : sg1.getPostset(pair.v1)) {
                            tmpLabel = sg1.getVertexLabel(n.getID());
                            if (tmpLabel != null) {
                                mset.add(tmpLabel);
                            }
                        }
                        label1 += mset.toString();

                        String label2 = sg2.getVertexLabel(pair.v2);
                        mset.clear();
                        for (Vertex n : sg2.getPreset(pair.v2)) {
                            tmpLabel = sg2.getVertexLabel(n.getID());
                            if (tmpLabel != null) {
                                mset.add(tmpLabel);
                            }
                        }
                        label2 += mset.toString();
                        mset.clear();
                        for (Vertex n : sg2.getPostset(pair.v2)) {
                            tmpLabel = sg2.getVertexLabel(n.getID());
                            if (tmpLabel != null) {
                                mset.add(tmpLabel);
                            }
                        }
                        label2 += mset.toString();

                        if (label1.compareTo(label2) > 0) {
                            String tmp = label1;
                            label1 = label2;
                            label2 = tmp;
                        }
                        tmapp.put(label1 + label2, pair);
                    }
                    String contextkey = tmapp.keySet().first();
                    // CASE 3: Composite labels (concatenation of labels of nodes surrounding the target vertex)
                    if (tmapp.get(contextkey).size() == 1) {
                        couple = tmapp.get(contextkey).first();
                    } else {
                        // CASE 4: Non deterministic choice (Choose a random candidate)
                        deterministic = false;
                        couple = bestCandidates.get(randomized.nextInt(bestCandidates.size()));
                    }
                } else {
                    // CASE 5: Non deterministic choice (Choose a random candidate)
                    //                        System.out.println("oops ...");
                    deterministic = false;
                    couple = bestCandidates.get(randomized.nextInt(bestCandidates.size()));
                }
            }

            Set<TwoVertices> newOpenCouples = new HashSet<TwoVertices>();
            for (TwoVertices p : openCouples) {
                if (!p.v1.equals(couple.v1) && !p.v2.equals(couple.v2)) {
                    newOpenCouples.add(p);
                }
            }
            openCouples = newOpenCouples;

            mapping.addPair(couple);
            shortestEditDistance = newShortestEditDistance;
            doStep = true;
        }
    }

    //Return the smallest edit distance
    return mapping.mapping;
}

From source file:bio.gcat.gui.editor.display.GraphDisplay.java

private void layoutGraph() {
    if (vertices.isEmpty())
        return;/*  w w w  .  j av  a 2 s  .c  om*/
    model.beginUpdate();
    try {
        for (Object vertex : vertices.values())
            for (Object edge : graph.getEdges(vertex))
                graph.resetEdge(edge); // reset all edges of th egraph

        if (layout == null) {
            TreeMultimap<Integer, Tuple> vertices = TreeMultimap.create(Comparator.reverseOrder(),
                    Comparator.naturalOrder());
            for (Tuple vertex : this.vertices.keySet())
                vertices.put(vertex.getBases().length, vertex);

            LinkedList<Integer> lengths = new LinkedList<Integer>(vertices.keySet());
            int width = this.getWidth(), last = lengths.getLast(),
                    columns = Math.max(2, lengths.size() * 2 - 1), columnGap = width / (columns + 1),
                    rowGap = 80, left = -columnGap / 2 + 10, topInset = -50;
            for (Integer length : lengths) {
                int top;
                ArrayList<Tuple> verticesWithLength = new ArrayList<Tuple>(vertices.get(length));
                if (columns == 2 || length != last) {
                    int half = (int) Math.ceil((double) verticesWithLength.size() / 2.);
                    left += columnGap;
                    top = topInset;
                    for (Tuple vertex : verticesWithLength.subList(0, half))
                        this.positionVertexAt(vertex, left, top += rowGap);
                    top = topInset;
                    for (Tuple vertex : verticesWithLength.subList(half, verticesWithLength.size()))
                        this.positionVertexAt(vertex, width - left, top += rowGap);
                } else {
                    left = width / 2;
                    top = topInset;
                    for (Tuple vertex : verticesWithLength)
                        this.positionVertexAt(vertex, left, top += rowGap);
                }
            }
        } else {
            int width = this.getWidth();
            if (layout instanceof mxCircleLayout)
                ((mxCircleLayout) layout).setRadius(width / 2 - 50);
            else if (layout instanceof mxHierarchicalLayout)
                ((mxHierarchicalLayout) layout).setParentBorder(50);
            layout.execute(parent);
        }
    } finally {
        model.endUpdate();
    }
}

From source file:org.apromore.similaritysearch.common.algos.GraphEditDistanceGreedy.java

public double computeGED(Graph sg1, Graph sg2) {
    BestMapping mapping = new BestMapping();
    double shortestEditDistance = Double.MAX_VALUE;
    Random randomized = new Random(123456789);

    try {//w ww . j a  v  a2  s  .  c  om
        // INIT
        init(sg1, sg2);
        Set<TwoVertices> openCouples = times(sg1.getVertices(), sg2.getVertices(), ledcutoff);

        // STEP
        boolean doStep = true;
        while (doStep) {
            doStep = false;
            Vector<TwoVertices> bestCandidates = new Vector<TwoVertices>();
            double newShortestEditDistance = shortestEditDistance;
            for (TwoVertices couple : openCouples) {
                double newEditDistance = this.editDistance(mapping, couple);

                if (newEditDistance < newShortestEditDistance) {
                    bestCandidates = new Vector<TwoVertices>();
                    bestCandidates.add(couple);
                    newShortestEditDistance = newEditDistance;
                } else if (newEditDistance == newShortestEditDistance) {
                    bestCandidates.add(couple);
                }
            }

            if (bestCandidates.size() > 0) {
                TwoVertices couple;

                // Case 1: Only one candidate pair
                if (bestCandidates.size() == 1) {
                    couple = bestCandidates.firstElement();
                } else {
                    //  CASE 2: Lexicographical order is enough
                    TreeMultimap<String, TwoVertices> tmap = TreeMultimap.create();
                    for (TwoVertices pair : bestCandidates) {
                        String label1 = sg1.getVertexLabel(pair.v1);
                        String label2 = sg2.getVertexLabel(pair.v2);
                        if (label1 != null && label2 != null && label1.compareTo(label2) > 0) {
                            String tmp = label1;
                            label1 = label2;
                            label2 = tmp;
                        }
                        tmap.put(label1 + label2, pair);
                    }
                    String firstkey = tmap.keySet().first();

                    if (tmap.get(firstkey).size() == 1) {
                        couple = tmap.get(firstkey).first();
                    } else if (tmap.get(firstkey).size() > 1) {
                        Set<TwoVertices> set = tmap.get(firstkey);
                        TreeMultimap<String, TwoVertices> tmapp = TreeMultimap.create();

                        String label1;
                        String tmpLabel;
                        TreeMultiset<String> mset = TreeMultiset.create();
                        for (TwoVertices pair : set) {
                            label1 = sg1.getVertexLabel(pair.v1);
                            mset.clear();
                            for (Vertex n : sg1.getPreset(pair.v1)) {
                                tmpLabel = sg1.getVertexLabel(n.getID());
                                if (tmpLabel != null) {
                                    mset.add(tmpLabel);
                                }
                            }
                            label1 += mset.toString();
                            mset.clear();
                            for (Vertex n : sg1.getPostset(pair.v1)) {
                                tmpLabel = sg1.getVertexLabel(n.getID());
                                if (tmpLabel != null) {
                                    mset.add(tmpLabel);
                                }
                            }
                            label1 += mset.toString();

                            String label2 = sg2.getVertexLabel(pair.v2);
                            mset.clear();
                            for (Vertex n : sg2.getPreset(pair.v2)) {
                                tmpLabel = sg2.getVertexLabel(n.getID());
                                if (tmpLabel != null) {
                                    mset.add(tmpLabel);
                                }
                            }
                            label2 += mset.toString();
                            mset.clear();
                            for (Vertex n : sg2.getPostset(pair.v2)) {
                                tmpLabel = sg2.getVertexLabel(n.getID());
                                if (tmpLabel != null) {
                                    mset.add(tmpLabel);
                                }
                            }
                            label2 += mset.toString();

                            if (label1.compareTo(label2) > 0) {
                                String tmp = label1;
                                label1 = label2;
                                label2 = tmp;
                            }
                            tmapp.put(label1 + label2, pair);
                        }
                        String contextkey = tmapp.keySet().first();
                        // CASE 3: Composite labels (concatenation of labels of nodes surrounding the target vertex)
                        if (tmapp.get(contextkey).size() == 1) {
                            couple = tmapp.get(contextkey).first();
                        } else {
                            // CASE 4: Non deterministic choice (Choose a random candidate)
                            deterministic = false;
                            couple = bestCandidates.get(randomized.nextInt(bestCandidates.size()));
                        }
                    } else {
                        // CASE 5: Non deterministic choice (Choose a random candidate)
                        //                            System.out.println("oops ...");
                        deterministic = false;
                        couple = bestCandidates.get(randomized.nextInt(bestCandidates.size()));
                    }
                }

                Set<TwoVertices> newOpenCouples = new HashSet<TwoVertices>();
                for (TwoVertices p : openCouples) {
                    if (!p.v1.equals(couple.v1) && !p.v2.equals(couple.v2)) {
                        newOpenCouples.add(p);
                    }
                }
                openCouples = newOpenCouples;

                mapping.addPair(couple);
                shortestEditDistance = newShortestEditDistance;
                doStep = true;
            }
        }

        nrSubstitudedVertices = mapping.size();
    } catch (Exception e) {
        LOGGER.error("Error occured while processing Distance Greedy Similarity Search ", e);
    }

    // Return the smallest edit distance
    return shortestEditDistance;
}

From source file:common.algos.GraphEditDistanceGreedy.java

public double computeGED(Graph sg1, Graph sg2) {
    BestMapping mapping = new BestMapping();
    double shortestEditDistance = Double.MAX_VALUE;
    Random randomized = new Random(123456789);

    try {//w ww  .  j a v  a  2 s  .c o m
        // INIT
        init(sg1, sg2);
        Set<TwoVertices> openCouples = times(sg1.getVertices(), sg2.getVertices(), ledcutoff);

        // STEP
        boolean doStep = true;
        while (doStep) {
            doStep = false;
            Vector<TwoVertices> bestCandidates = new Vector<TwoVertices>();
            double newShortestEditDistance = shortestEditDistance;
            for (TwoVertices couple : openCouples) {
                double newEditDistance = this.editDistance(mapping, couple);

                if (newEditDistance < newShortestEditDistance) {
                    bestCandidates = new Vector<TwoVertices>();
                    bestCandidates.add(couple);
                    newShortestEditDistance = newEditDistance;
                } else if (newEditDistance == newShortestEditDistance) {
                    bestCandidates.add(couple);
                }
            }

            if (bestCandidates.size() > 0) {
                TwoVertices couple;

                // Case 1: Only one candidate pair
                if (bestCandidates.size() == 1) {
                    couple = bestCandidates.firstElement();
                } else {
                    //  CASE 2: Lexicographical order is enough
                    TreeMultimap<String, TwoVertices> tmap = TreeMultimap.create();
                    for (TwoVertices pair : bestCandidates) {
                        String label1 = sg1.getVertexLabel(pair.v1);
                        String label2 = sg2.getVertexLabel(pair.v2);
                        if (label1 != null && label2 != null && label1.compareTo(label2) > 0) {
                            String tmp = label1;
                            label1 = label2;
                            label2 = tmp;
                        }
                        tmap.put(label1 + label2, pair);
                    }
                    String firstkey = tmap.keySet().first();

                    if (tmap.get(firstkey).size() == 1) {
                        couple = tmap.get(firstkey).first();
                    } else if (tmap.get(firstkey).size() > 1) {
                        Set<TwoVertices> set = tmap.get(firstkey);
                        TreeMultimap<String, TwoVertices> tmapp = TreeMultimap.create();

                        String label1;
                        String tmpLabel;
                        TreeMultiset<String> mset = TreeMultiset.create();
                        for (TwoVertices pair : set) {
                            label1 = sg1.getVertexLabel(pair.v1);
                            mset.clear();
                            for (Vertex n : sg1.getPreset(pair.v1)) {
                                tmpLabel = sg1.getVertexLabel(n.getID());
                                if (tmpLabel != null) {
                                    mset.add(tmpLabel);
                                }
                            }
                            label1 += mset.toString();
                            mset.clear();
                            for (Vertex n : sg1.getPostset(pair.v1)) {
                                tmpLabel = sg1.getVertexLabel(n.getID());
                                if (tmpLabel != null) {
                                    mset.add(tmpLabel);
                                }
                            }
                            label1 += mset.toString();

                            String label2 = sg2.getVertexLabel(pair.v2);
                            mset.clear();
                            for (Vertex n : sg2.getPreset(pair.v2)) {
                                tmpLabel = sg2.getVertexLabel(n.getID());
                                if (tmpLabel != null) {
                                    mset.add(tmpLabel);
                                }
                            }
                            label2 += mset.toString();
                            mset.clear();
                            for (Vertex n : sg2.getPostset(pair.v2)) {
                                tmpLabel = sg2.getVertexLabel(n.getID());
                                if (tmpLabel != null) {
                                    mset.add(tmpLabel);
                                }
                            }
                            label2 += mset.toString();

                            if (label1.compareTo(label2) > 0) {
                                String tmp = label1;
                                label1 = label2;
                                label2 = tmp;
                            }
                            tmapp.put(label1 + label2, pair);
                        }
                        String contextkey = tmapp.keySet().first();
                        // CASE 3: Composite labels (concatenation of labels of nodes surrounding the target vertex)
                        if (tmapp.get(contextkey).size() == 1) {
                            couple = tmapp.get(contextkey).first();
                        } else {
                            // CASE 4: Non deterministic choice (Choose a random candidate)
                            deterministic = false;
                            couple = bestCandidates.get(randomized.nextInt(bestCandidates.size()));
                        }
                    } else {
                        // CASE 5: Non deterministic choice (Choose a random candidate)
                        //                            System.out.println("oops ...");
                        deterministic = false;
                        couple = bestCandidates.get(randomized.nextInt(bestCandidates.size()));
                    }
                }

                Set<TwoVertices> newOpenCouples = new HashSet<TwoVertices>();
                for (TwoVertices p : openCouples) {
                    if (!p.v1.equals(couple.v1) && !p.v2.equals(couple.v2)) {
                        newOpenCouples.add(p);
                    }
                }
                openCouples = newOpenCouples;

                mapping.addPair(couple);
                shortestEditDistance = newShortestEditDistance;
                doStep = true;
            }
        }

        nrSubstitudedVertices = mapping.size();
    } catch (Exception e) {
    }

    // Return the smallest edit distance
    return shortestEditDistance;
}