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 }