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 }