/
Score.java
193 lines (162 loc) · 5.31 KB
/
Score.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/******************************************************************************
* Copyright (c) 2004-2008 Whirlwind Match Limited. All rights reserved.
*
* This is open source software; you can use, redistribute and/or modify
* it under the terms of the Open Software Licence v 3.0 as published by the
* Open Source Initiative.
*
* You should have received a copy of the Open Software Licence along with this
* application. if not, contact the Open Source Initiative (www.opensource.org)
*****************************************************************************/
package com.wwm.attrs;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
/**Abstract class representing a score, derived classes calculate a linearised score based on any number of supplied
* component scores.
* @author ac
*
*/
public abstract class Score implements com.wwm.model.attributes.Score, Comparable<Score>, Serializable {
static final long serialVersionUID = 5484270146323132L;
protected float linear;
protected float forwardsLinear;
protected float reverseLinear;
private boolean linearKnown;
/** Number of scores added that didn't match */
protected int nonMatches = 0;
/**
* The direction to manipulate the score in.
*/
public enum Direction {
forwards, reverse
}
public Score() {
super();
linear = 1.0f;
linearKnown = false;
}
public Score(Score rhs) {
super();
linear = rhs.linear;
linearKnown = rhs.linearKnown;
}
/**Calculates a linear score from a nonlinear product and component count
* @param product The nonlinear product to process
* @param count The number of component scores that went into the product
* @return the linearised score
*/
protected float linearise(float product, float count) {
if (count > 1) {
product = (float) Math.pow(product, 1.0 / count);
}
// final float precision = 0.00001f; // round up to next multiple of this
// return precision * (int)( 1 + product / precision );
return product;
}
/**
* Make sure this instance is updated BEFORE serialisation occurs as the
* data that calculates the results may not be serialised.
* @param out
* @throws IOException
*/
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
total();
out.defaultWriteObject();
}
/**Calculates the linearised score product
* @return The linear score total
*/
public float total() {
if (!linearKnown) {
update();
linearKnown = true;
}
return linear;
}
public float forwardsTotal() {
if (!linearKnown) {
update();
linearKnown = true;
}
return forwardsLinear;
}
public float reverseTotal() {
if (!linearKnown) {
update();
linearKnown = true;
}
return reverseLinear;
}
/**Add a component score
* @param s The scorer generating the component score
* @param score The component score
* @param d The direction the scorer is being run in
*/
public abstract void add(Scorer s, float score, Direction d);
public void addNull(Scorer s, Direction d) {
if (s.isScoreNull()) {
add(s,s.getScoreOnNull(), d);
}
}
protected void update() {
linearKnown = true;
}
protected void invalidate() {
linearKnown = false;
}
public int getNonMatches() {
if (!linearKnown) {
update();
linearKnown = true;
}
return nonMatches;
}
/**
* Result of comparing two scores is that first they must score according
* to the lowest number of nonMatches, and then according to the
* score.
* @param o
* @return
*/
public int compareTo(Score rhs) {
if ( getNonMatches() < rhs.getNonMatches() ) {
return 1; // lower value is earlier in sort order
}
if ( getNonMatches() > rhs.getNonMatches() ) {
return -1;
}
if (total() > rhs.total()) {
return 1;
}
if (total() < rhs.total()) {
return -1;
}
return 0;
}
@Override
public String toString() {
if (getNonMatches() == 0) {
return String.valueOf( total() );
} else {
return total() + "(" + getNonMatches() + " non-matches)";
}
}
/**
* Set an attribute. This is to be used for at least, Distance, but, in
* something like PathDeviationScorer, could be used to record:
* DriverDistance, TotalDetour
*/
public void setScorerAttribute(Direction d, String name, float value){
throw new UnsupportedOperationException();
}
public Float getForwardsScore(String name) {
throw new UnsupportedOperationException();
}
public Float getReverseScore(String name) {
throw new UnsupportedOperationException();
}
public Collection<String> getScorerAttrNames() {
throw new UnsupportedOperationException();
}
}