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 }