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