    001    package org.maltparser.parser.history.kbest;
    002
    003    import java.util.ArrayList;
    004
    005    import org.maltparser.core.exception.MaltChainedException;
    006    import org.maltparser.parser.history.action.SingleDecision;
    007    /**
    008    *
    009    * @author Johan Hall
    010    **/
    011    public class KBestList {
    012            protected final ArrayList<Candidate> kBestList;
    013            protected int k = -1;
    014            protected int topCandidateIndex;
    015            protected int addCandidateIndex;
    016            protected SingleDecision decision;
    017
    018            /**
    019             * Creates a unrestricted k-best list
    020             *
    021             * @param decision a reference to the single decision that uses the k-best list
    022             */
    023            public KBestList(SingleDecision decision) {
    024                    this(-1, decision);
    025            }
    026
    027            /**
    028             * Creates a k-best list
    029             *
    030             * @param k     the k-best list size
    031             * @param decision      a reference to the single decision that uses the k-best list.
    032             */
    033            public KBestList(Integer k, SingleDecision decision) {
    034                    setK(k.intValue());
    035                    this.decision = decision;
    036                    if (this.k > 0) {
    037                            kBestList = new ArrayList<Candidate>(this.k);
    038                            initKBestList();
    039                    } else {
    040                            kBestList = new ArrayList<Candidate>();
    041                    }
    042
    043            }
    044
    045            protected void initKBestList() {
    046                    for (int i=0; i < this.k; i++) {
    047                            kBestList.add(new Candidate());
    048                    }
    049            }
    050
    051            /**
    052             * Resets the k-best list
    053             */
    054            public void reset() {
    055                    this.topCandidateIndex = 0;
    056                    this.addCandidateIndex = 0;
    057            }
    058
    059            /**
    060             * Adds a candidate to the k-best list
    061             *
    062             * @param actionCode the integer representation  of candidate action
    063             * @throws MaltChainedException
    064             */
    065            public void add(int actionCode) throws MaltChainedException {
    066                    if (k != -1 && addCandidateIndex >= k) { return; }
    067                    if (addCandidateIndex >= kBestList.size()) { kBestList.add(new Candidate()); }
    068                    kBestList.get(addCandidateIndex).setActionCode(actionCode);
    069                    if (addCandidateIndex == 0) {
    070    //                      if (decision instanceof SingleDecision) {
    071    //                              ((SingleDecision)decision).addDecision(actionCode);
    072    //                      }
    073                            decision.addDecision(actionCode);
    074                            topCandidateIndex++;
    075                    }
    076                    addCandidateIndex++;
    077            }
    078
    079            public void addList(int[] predictionList) throws MaltChainedException {
    080                    int n = (k != -1 && k <= predictionList.length-1)?k:predictionList.length - 1;
    081                    for (int i=0; i<n; i++) {
    082                            add(predictionList[i]);
    083                    }
    084            }
    085
    086            /**
    087             * Adds a candidate to the k-best list
    088             *
    089             * @param symbol the string representation of candidate action
    090             * @throws MaltChainedException
    091             */
    092            public void add(String symbol) throws MaltChainedException {
    093    //              if (decision instanceof SingleDecision) {
    094    //                      this.add(((SingleDecision)decision).getDecisionCode(symbol));
    095    //              }
    096                    this.add(decision.getDecisionCode(symbol));
    097            }
    098
    099
    100            /**
    101             * Updates the corresponding single decision with the next value in the k-best list.
    102             *
    103             * @return true if decision has been updated, otherwise false
    104             * @throws MaltChainedException
    105             */
    106            public boolean updateActionWithNextKBest() throws MaltChainedException {
    107                    if (addCandidateIndex != 0 && topCandidateIndex < addCandidateIndex && topCandidateIndex < kBestList.size()) {
    108                            int actionCode = kBestList.get(topCandidateIndex).getActionCode();
    109                            if (decision instanceof SingleDecision) {
    110                                    ((SingleDecision)decision).addDecision(actionCode);
    111                            }
    112                            topCandidateIndex++;
    113                            return true;
    114                    }
    115                    return false;
    116            }
    117
    118            public int peekNextKBest() {
    119                    if (addCandidateIndex != 0 && topCandidateIndex < addCandidateIndex && topCandidateIndex < kBestList.size()) {
    120                            return kBestList.get(topCandidateIndex).getActionCode();
    121                    }
    122                    return -1;
    123            }
    124
    125            /**
    126             * Returns the current size of the k-best list
    127             *
    128             * @return the current size of the k-best list
    129             */
    130            public int getCurrentSize() {
    131                    return addCandidateIndex;
    132                    //return kBestList.size();
    133            }
    134
    135            /**
    136             * Returns the maximum number of candidates in the k-best list.
    137             *
    138             * @return the maximum number of candidates in the k-best list
    139             */
    140            public int getK() {
    141                    return k;
    142            }
    143            /**
    144             * Sets the maximum number of candidates in the k-best list
    145             *
    146             * @param k the maximum number of candidates
    147             */
    148            protected void setK(int k) {
    149                    if (k == 0) {
    150                            this.k = 1; // the k-best list must contain at least one candidate
    151                    } if (k < 0) {
    152                            this.k = -1; // this means that the k-best list is unrestricted.
    153                    } else {
    154                            this.k = k;
    155                    }
    156            }
    157
    158            protected int getTopCandidateIndex() {
    159                    return topCandidateIndex;
    160            }
    161
    162            protected int getAddCandidateIndex() {
    163                    return addCandidateIndex;
    164            }
    165
    166            /**
    167             * Returns a single decision object
    168             *
    169             * @return a single decision object
    170             */
    171            public SingleDecision getDecision() {
    172                    return decision;
    173            }
    174
    175            public int getKBestListSize() {
    176                    return kBestList.size();
    177            }
    178
    179            public ScoredCandidate getCandidate(int i) {
    180                    if (i >= kBestList.size()) {
    181                            return null;
    182                    }
    183                    return (ScoredCandidate)kBestList.get(i);
    184            }
    185
    186            /* (non-Javadoc)
    187             * @see java.lang.Object#toString()
    188             */
    189            public String toString() {
    190                    final StringBuilder sb = new StringBuilder();
    191                    sb.append("[ ");
    192                    for (int i = 0; i < addCandidateIndex; i++) {
    193                            sb.append(kBestList.get(i));
    194                            sb.append(' ');
    195                    }
    196                    sb.append("] ");
    197                    return sb.toString();
    198            }
    199    }