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 topCandidateIndex++;
074 }
075 addCandidateIndex++;
076 }
077
078 public void addList(int[] predictionList) throws MaltChainedException {
079 int n = (k != -1 && k <= predictionList.length-1)?k:predictionList.length - 1;
080 for (int i=0; i<n; i++) {
081 add(predictionList[i]);
082 }
083 }
084
085 /**
086 * Adds a candidate to the k-best list
087 *
088 * @param symbol the string representation of candidate action
089 * @throws MaltChainedException
090 */
091 public void add(String symbol) throws MaltChainedException {
092 if (decision instanceof SingleDecision) {
093 this.add(((SingleDecision)decision).getDecisionCode(symbol));
094 }
095 }
096
097
098 /**
099 * Updates the corresponding single decision with the next value in the k-best list.
100 *
101 * @return true if decision has been updated, otherwise false
102 * @throws MaltChainedException
103 */
104 public boolean updateActionWithNextKBest() throws MaltChainedException {
105 if (addCandidateIndex != 0 && topCandidateIndex < addCandidateIndex && topCandidateIndex < kBestList.size()) {
106 int actionCode = kBestList.get(topCandidateIndex).getActionCode();
107 if (decision instanceof SingleDecision) {
108 ((SingleDecision)decision).addDecision(actionCode);
109 }
110 topCandidateIndex++;
111 return true;
112 }
113 return false;
114 }
115
116 public int peekNextKBest() {
117 if (addCandidateIndex != 0 && topCandidateIndex < addCandidateIndex && topCandidateIndex < kBestList.size()) {
118 return kBestList.get(topCandidateIndex).getActionCode();
119 }
120 return -1;
121 }
122
123 /**
124 * Returns the current size of the k-best list
125 *
126 * @return the current size of the k-best list
127 */
128 public int getCurrentSize() {
129 return addCandidateIndex;
130 //return kBestList.size();
131 }
132
133 /**
134 * Returns the maximum number of candidates in the k-best list.
135 *
136 * @return the maximum number of candidates in the k-best list
137 */
138 public int getK() {
139 return k;
140 }
141 /**
142 * Sets the maximum number of candidates in the k-best list
143 *
144 * @param k the maximum number of candidates
145 */
146 protected void setK(int k) {
147 if (k == 0) {
148 this.k = 1; // the k-best list must contain at least one candidate
149 } if (k < 0) {
150 this.k = -1; // this means that the k-best list is unrestricted.
151 } else {
152 this.k = k;
153 }
154 }
155
156 protected int getTopCandidateIndex() {
157 return topCandidateIndex;
158 }
159
160 protected int getAddCandidateIndex() {
161 return addCandidateIndex;
162 }
163
164 /**
165 * Returns a single decision object
166 *
167 * @return a single decision object
168 */
169 public SingleDecision getDecision() {
170 return decision;
171 }
172
173 public int getKBestListSize() {
174 return kBestList.size();
175 }
176
177 public ScoredCandidate getCandidate(int i) {
178 if (i >= kBestList.size()) {
179 return null;
180 }
181 return (ScoredCandidate)kBestList.get(i);
182 }
183
184 /* (non-Javadoc)
185 * @see java.lang.Object#toString()
186 */
187 public String toString() {
188 StringBuilder sb = new StringBuilder();
189 sb.append("[ ");
190 for (int i = 0; i < addCandidateIndex; i++) {
191 sb.append(kBestList.get(i));
192 sb.append(' ');
193 }
194 sb.append("] ");
195 return sb.toString();
196 }
197 }