|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Object
|
+--org.pealfactory.bronze.Tracker
|
+--org.pealfactory.compose.halfleadspliced.Composer
The Composer is the heart of Elf, and contains the inner Search Loops which
find and score compositions. It works closely with a delegate Composition
instance to handle composition statistics counting and truth and music checking.
It is designed for asynchronous use by a hosting application or applet, and
so subclasses Tracker to provide abort and pause functions as well as
progress and status information.
Note that the base class Composer only handles the half-lead no-calls search.
The subclasses ComposerCalls and ComposerLH contain half-lead
calls and leadhead-only searches. To create the correct Composer class, it is
essential to use the static factory method create(org.pealfactory.compose.halfleadspliced.Tables, int, int, boolean, boolean, boolean, boolean, int).
Here's how to use a Composer to perform a search:
Tables instance must be created with the methods and music
definitions required for the search; however, the table builds do not have
to be performed yet.
ComposerHost interface - this
is effectively a callback which the Composer will use to output compositions found.
Whilst composing is underway, the following methods can be called asynchronously to follow the progress of the search:
| isComposing() | returns true if the search is underway |
| isFinished() | returns true when the search is complete |
| getProgress() | returns % complete to 3 decimal places |
| estimateTimeLeft() | returns an estimate of the time till completion |
| getNComps() | the number of true compositions found so far |
| getNNodes() | the number of leads generated so far |
| getCompsPerSec() | the number of compositions checked in the last second |
| getNodesPerSec() | the number of leads generated in the last second |
| getBestScore() | the best score found from a composition so far |
| getBestMusic() | the best music found from a composition so far |
| getBestCOM() | the maximum number of COM found so far |
| getBestBalance() | the best method balance found in a composition so far |
| setMinScore | sets minimum score a composition must achieve before being accepted; can be called during composing to tighten search |
| setMinBalance | set minimum method balance allowed, 0-100; call this during composing to tighten search |
| setMinCOM | set minimum COM allowed; call this during composing to tighten search |
| abort() | to abort a search |
| pause() | to pause a search |
| resume() | to resume a paused search |
Once the search has finished, the following methods can also be used:
| getSearchTime() | total time spent in search |
| isError() | returns true if an internal error (exception) occurred, other than abort. |
| getErrorMsg() | if an error terminated the search, this returns a descriptive error message. |
Much of the Composer code has been heavily tuned for performance, and should not be modified without extensive benchmarking on a range of searches. The inner composing loop doCompose() is triplicated - see ComposerCalls and ComposerLH classes for versions of doCompose() which are optimised for half-lead with-calls and leadhead-only with-calls searches.
A description of the rotationally-sorted search algorithm used by Elf is contained in the Elf White Paper.
| Field Summary | |
(package private) int[] |
f1stHalfMethodCounts
For each method, the number of times it has appeared in the first half-leads of the composition |
(package private) int[] |
f1stHalfMethodIndices
For HL searches, the first-half method index for each lead in the current search comp |
(package private) int[] |
f2ndHalfMethodCounts
For each method, the number of times it has appeared in the second half-leads of the composition |
(package private) int[] |
f2ndHalfMethodIndices
For HL searches, the second-half method index for each lead in the current search comp |
(package private) int |
fAllowCalls
=0 for no calls, 1 for bobs-only and 2 for bobs and singles |
(package private) int |
fBalanceScore
The balance weighting - how many points a composition is awarded for each method balance percentage point 0-100 |
(package private) int |
fBestBalance
|
(package private) int |
fBestCOM
|
(package private) int |
fBestMusic
|
(package private) int |
fBestScore
|
(package private) int[] |
fCalls
The current state of calls in each lead of the search (0=plain) |
(package private) Composition |
fComp
One Composition reference is held for the entire search |
(package private) boolean |
fComposing
|
(package private) Method[] |
fCompositeMethods
Composite methods - size is fNMethods squared - these DO have tables/perms built |
(package private) long |
fCompsChecked
|
(package private) int |
fCompsPerSec
|
(package private) int |
fCOMScore
The COM weighting - how many points a composition is awarded for each COM per part |
(package private) int |
fCounter
|
(package private) ComposerHost |
fHost
The ComposerHost is where output compositions get sent |
(package private) double |
fInitialProgress
|
(package private) long |
fInitialTime
|
(package private) long |
fLastComps
|
(package private) long |
fLastNodes
|
(package private) long |
fLastTime
|
(package private) int |
fLeadsPerPart
Number of leads per part of composition |
(package private) Method[] |
fLHOnlyMethods
Pointers into fCompositeMethods for LH-only search - size = fNMethods |
(package private) boolean |
fLHSpliced
Set to true if doing LH-only spliced |
(package private) int |
fMaxMethodsAtRepeatLimit
The maximum number of methods that are allowed to reach fMaxMethodRepeat occurrences |
private int |
fMaxPartLength
Maximum part length to be produced by search. |
(package private) int[] |
fMethodCounts
Temporary use by method balance calculator |
(package private) int[] |
fMethodIndices
The current state of the composition during the search; one composite method index per lead |
(package private) int |
fMethodRepeatLimit
The maximum number of allowed repeated occurrences of a method (for HL spliced, in each half) |
(package private) Method[] |
fMethods
The original list of methods to splice; note these do NOT have tables/perms built for them. |
(package private) int |
fMinBalance
Current minimum method balance (0-100) a composition must achieve before being output |
(package private) int |
fMinCOM
Current minimum changes of method (per part) a composition must achieve before being output |
private int |
fMinPartLength
Minimum part length to be produced by search. |
(package private) int |
fMinScore
Current minimum score a composition must achieve before being output |
(package private) int |
fN1stHalfAtMaxRepeat
The number of methods that have occurred fMaxMethodRepeat times in the first half-leads of the composition |
(package private) int |
fN2ndHalfAtMaxRepeat
The number of methods that have occurred fMaxMethodRepeat times in the second half-leads of the composition |
(package private) int |
fNCompMethods
Number of composite methods - equals fNMethods squared for HL search |
(package private) int |
fNComps
|
(package private) boolean |
fNicePartEnds
Set to true if only "nice" part ends are allowed |
(package private) int |
fNMethods
The number of methods to splice, equals fMethods.length |
(package private) int |
fNodesPerSec
|
(package private) long |
fNodesSearched
|
(package private) int |
fNParts
Desired number of parts for composition |
(package private) double[] |
fProgressCumulatives
|
(package private) double[] |
fProgressRatios
Progress scale values for each possible value of the first node (not inc calls) |
(package private) int |
fRegenPtr
|
(package private) RowNode |
fRounds
This is kept as a fast way to reference the rounds RowNode |
(package private) long |
fSearchTime
Only set when search finished |
(package private) long |
fStartTime
|
(package private) Tables |
fTables
|
(package private) boolean |
fTenorsTogether
Set to true if tenors must be together at every leadhead |
(package private) boolean[] |
fTruthTable
Used for quick check of leadhead proof during search |
static int |
kCHECK_FREQ
Number of nodes between time/abort checks |
static java.lang.String |
kCOPYRIGHT
|
private static long |
kDISPLAY_INTERVAL
|
static int |
kNBELLS
|
private static int |
kTOTAL_DURATION
|
static java.lang.String |
kVERSION
|
| Fields inherited from class org.pealfactory.bronze.Tracker |
fAbort, fDelegateDuration, fDelegateJob, fError, fErrorMsg, fJobName, fPause, fProgress, fTask, fTotalDuration, fWorker, kDEFAULT_JOB_NAME, kRESPONSE_TIME |
| Fields inherited from interface org.pealfactory.compose.halfleadspliced.StandardMethods |
kASHTEAD, kBELFAST, kBRISTOL, kCAMBRIDGE, kCASSIOBURY, kGLASGOW, kLINCOLNSHIRE, kLONDON, kPUDSEY, kRUTLAND, kSUPERLATIVE, kUXBRIDGE, kYORKSHIRE |
| Fields inherited from interface org.pealfactory.bronze.Trackable |
kERROR_NONE |
| Constructor Summary | |
(package private) |
Composer(Tables tables,
int leadsPerPart,
int nParts,
boolean tenorsTogether,
boolean nicePartEnds,
boolean ATW)
This constructor should not be used by client code - instead see the create(org.pealfactory.compose.halfleadspliced.Tables, int, int, boolean, boolean, boolean, boolean, int) static factory method. |
| Method Summary | |
(package private) int |
backtrack(int i)
This method doesn't do calls! |
(package private) int |
calcMethodBalance()
Calculates a percentage score (as an integer 0-100) representing the method balance of the current composition. |
(package private) int |
calcMethodDistribution(int[] methodCounts,
double maxMethods)
Provides an overall measure of method distribution, by finding the mean deviation of method counts from the optimum. |
private void |
calcProgressRatios()
For the rotational sort, progress through the search space speeds up exponentially as the possibilities for the initial node are exhausted. |
(package private) int |
calcUnbalance(int[] counts,
int minRep)
Returns an "unbalance" value based on the method counts in the counts[] array. |
(package private) int |
checkComp()
Checks composition for music and truth; if it also meets the current minimum scores, it gets outputted. |
(package private) boolean |
checkStats()
Should be called every few centiseconds by the main composing loop. |
void |
compose(ComposerHost host)
Starts the search. |
static Composer |
create(Tables tables,
int leadsPerPart,
int nParts,
boolean tenorsTogether,
boolean nicePartEnds,
boolean ATW,
boolean LHonly,
int calls)
This is a factory method which must be used by client code to construct Composer instances - the individual constructors should not be used. |
(package private) void |
doCompose()
This one doesn't do calls! |
java.lang.String |
estimateTimeLeft()
Returns (as a String) an estimate of the time left till search completion, in hours and minutes. |
private int |
findMethod(java.lang.String abbrev)
Used privately by setStartComp() - looks up a Method reference from its abbreviation String. |
int |
getBestBalance()
Returns the best method balance of any composition found so far. |
int |
getBestCOM()
Returns the highest number of changes of method (in one part) of any composition found so far. |
int |
getBestMusic()
Returns the music count of the most musical composition found so far. |
int |
getBestScore()
Returns the score of the best composition found so far. |
private double |
getComposingProgress()
|
int |
getCompsPerSec()
Returns an instantaneous measure of the number of compositions being checked (for music and proof) per second. |
int |
getNComps()
Returns the number of true compositions found so far. |
long |
getNNodes()
Total number of leads searched. |
int |
getNodesPerSec()
Returns an instantaneous measure of the number of leads being processed per second. |
java.lang.String |
getSearchTime()
Only valid if isFinished() - returns the total search time, in hours, minutes and seconds, as a String. |
void |
initRepeatLimits(boolean atw)
Initialises method repeat-count limits; if "atw" set, enforces perfect method balance in both first and second half-leads. |
boolean |
isComposing()
Returns true if composing is underway, or is paused. |
(package private) boolean |
isLengthGood()
Check length of part is between min and max constraints - must only call this if comp has reached part end. |
boolean |
isLHSpliced()
Returns true if the LH-only flag is set. |
(package private) void |
reduceMethodCounts(int one,
int two)
|
void |
setAllowCalls(int allowCalls)
Determines whether calls will be allowed; the parameter should be set to 0 for no calls (the default), 1 for bobs, and 2 for bobs and singles. |
void |
setBalanceScore(int balanceScore)
Determines the score weighting given to method balance. |
void |
setCOMScore(int COMScore)
Determines the score weighting given to changes of method. |
void |
setMaxPartLength(int maxLength)
Allows a maximum composition length to be set. |
void |
setMinBalance(int min)
Sets the minimum method balance that a composition must achieve before being considered for checking. |
void |
setMinCOM(int min)
Sets the minimum number of changes of method that a composition must achieve before being considered for checking. |
void |
setMinPartLength(int minLength)
Allows a minimum composition length to be set. |
void |
setMinScore(int min)
Sets the minimum score that a composition must achieve before being output by the Composer. |
void |
setRepeatLimits(int unbalance)
Given an "unbalance" count, sets the repeat limits for methods to prune compositions where methods occur too many times. |
void |
setStartComp(java.lang.String comp)
The composing engine can be seeded with a "start" composition. |
| Methods inherited from class org.pealfactory.bronze.Tracker |
abort, abortWorker, endDelegateJob, getErrorMsg, getJobName, getProgress, getProgress, isAborted, isError, isFinished, isPaused, pause, reset, resume, run, setErrorMsg, setJobName, setProgress, setTotalDuration, startDelegateJob, startWorker, test, waitForResume |
| Methods inherited from class java.lang.Object |
|
| Field Detail |
public static final java.lang.String kVERSION
public static final java.lang.String kCOPYRIGHT
public static final int kNBELLS
private static final long kDISPLAY_INTERVAL
private static final int kTOTAL_DURATION
public static final int kCHECK_FREQ
Tables fTables
boolean fComposing
Method[] fMethods
int fNMethods
Method[] fCompositeMethods
Method[] fLHOnlyMethods
int fNCompMethods
int fLeadsPerPart
int fNParts
boolean fLHSpliced
boolean fTenorsTogether
boolean fNicePartEnds
int fAllowCalls
private int fMinPartLength
private int fMaxPartLength
int fMinScore
int fMinBalance
int fMinCOM
int fCOMScore
int fBalanceScore
int fMethodRepeatLimit
int fMaxMethodsAtRepeatLimit
Composition fComp
ComposerHost fHost
RowNode fRounds
int[] fMethodIndices
int[] fCalls
int[] f1stHalfMethodIndices
int[] f2ndHalfMethodIndices
int[] f1stHalfMethodCounts
int[] f2ndHalfMethodCounts
int fN1stHalfAtMaxRepeat
int fN2ndHalfAtMaxRepeat
int[] fMethodCounts
double[] fProgressRatios
double[] fProgressCumulatives
double fInitialProgress
long fSearchTime
long fInitialTime
long fNodesSearched
int fNComps
int fNodesPerSec
int fCompsPerSec
int fBestScore
int fBestMusic
int fBestCOM
int fBestBalance
int fRegenPtr
long fStartTime
long fLastTime
long fLastNodes
long fCompsChecked
long fLastComps
int fCounter
boolean[] fTruthTable
| Constructor Detail |
Composer(Tables tables,
int leadsPerPart,
int nParts,
boolean tenorsTogether,
boolean nicePartEnds,
boolean ATW)
create(org.pealfactory.compose.halfleadspliced.Tables, int, int, boolean, boolean, boolean, boolean, int) static factory method.| Method Detail |
public static Composer create(Tables tables,
int leadsPerPart,
int nParts,
boolean tenorsTogether,
boolean nicePartEnds,
boolean ATW,
boolean LHonly,
int calls)
The constructors initialise a number of private fields, but do not perform any lengthy or error-prone operations, so this method is appropriate for synchronous use before the search begins.
public void setAllowCalls(int allowCalls)
public void setCOMScore(int COMScore)
public void setBalanceScore(int balanceScore)
public void setMinPartLength(int minLength)
minLength - public void setMaxPartLength(int maxLength)
maxLength - public void initRepeatLimits(boolean atw)
public void setRepeatLimits(int unbalance)
public boolean isComposing()
public int getNComps()
public int getNodesPerSec()
public int getCompsPerSec()
public int getBestScore()
public int getBestMusic()
public int getBestCOM()
public int getBestBalance()
Note that the best balance number may not be achieved by the highest-scoring compositions, because the total composition score also includes factors such as music and COM.
Suitable for asynchronous use.
public long getNNodes()
public boolean isLHSpliced()
public void setMinScore(int min)
public void setMinBalance(int min)
setRepeatLimits(int)public void setMinCOM(int min)
public java.lang.String estimateTimeLeft()
public java.lang.String getSearchTime()
public void setStartComp(java.lang.String comp)
CY NB RS ...or for LH-only spliced:
C Y B- C ...The string does not have to be as many leads as the part; missing leads are padded. Remember however that the start comp should be rotationally sorted, i.e. if X represents the entire start comp, it must not contain any infix Y such that X>Y.
private int findMethod(java.lang.String abbrev)
public void compose(ComposerHost host)
void doCompose()
int backtrack(int i)
void reduceMethodCounts(int one,
int two)
boolean isLengthGood()
int calcMethodBalance()
This method must call setBalance() on the Composition instance to ensure the composition knows the current method balance values.
int calcMethodDistribution(int[] methodCounts,
double maxMethods)
int calcUnbalance(int[] counts,
int minRep)
final int checkComp()
Final for speed.
final boolean checkStats()
private double getComposingProgress()
private void calcProgressRatios()
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||