001package org.maltparser.parser.history.kbest; 002 003import java.util.ArrayList; 004 005import org.maltparser.core.exception.MaltChainedException; 006import org.maltparser.parser.history.action.SingleDecision; 007/** 008* 009* @author Johan Hall 010**/ 011public class KBestList { 012 protected final ArrayList<Candidate> kBestList; 013 protected int k = -1; 014 protected int topCandidateIndex; 015 protected int addCandidateIndex; 016 protected final 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}