org.pealfactory.compose.halfleadspliced
Class Composer

java.lang.Object
  extended by org.pealfactory.bronze.Tracker
      extended by org.pealfactory.compose.halfleadspliced.Composer
All Implemented Interfaces:
java.lang.Runnable, Trackable, StandardMethods
Direct Known Subclasses:
ComposerCalls, ComposerLH

public class Composer
extends Tracker
implements StandardMethods

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:

  1. First a 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.
  2. Next construct a Composer instance using the factory method Composer.create(), passing the Tables instance together with parameters specifying the number of leads and parts for the search, four boolean composing options (tenors-together, nice part-ends, optimum HL balance and LH-only spliced), and an integer indicating whether calls are to be used (0 = no calls, 1 = bobs only, 2 = bobs and singles).
  3. Appropriate setter methods can now be used to set other options - e.g. setMinScore(), setStartComp() etc.
  4. Up to this point execution can proceed synchronously. However it is now best to spawn a worker Thread to perform the slow build and search operations, and use the Tracker interface to monitor progress of the Composer and if necessary ask it to pause or abort.
  5. If necessary, the table build passes should now be performed. The tables instance must be fully populated before composing can begin!
  6. Finally, the compose() method can be called to begin the search. Note that you must supply an object implementing the 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
setMinScoresets minimum score a composition must achieve before being accepted; can be called during composing to tighten search
setMinBalanceset minimum method balance allowed, 0-100; call this during composing to tighten search
setMinCOMset 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
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
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, waitForResume
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

kVERSION

public static final java.lang.String kVERSION
See Also:
Constant Field Values

kCOPYRIGHT

public static final java.lang.String kCOPYRIGHT
See Also:
Constant Field Values

kNBELLS

public static final int kNBELLS
See Also:
Constant Field Values

kDISPLAY_INTERVAL

private static final long kDISPLAY_INTERVAL
See Also:
Constant Field Values

kTOTAL_DURATION

private static final int kTOTAL_DURATION
See Also:
Constant Field Values

kCHECK_FREQ

public static final int kCHECK_FREQ
Number of nodes between time/abort checks

See Also:
Constant Field Values

fTables

Tables fTables

fComposing

boolean fComposing

fMethods

Method[] fMethods
The original list of methods to splice; note these do NOT have tables/perms built for them.


fNMethods

int fNMethods
The number of methods to splice, equals fMethods.length


fCompositeMethods

Method[] fCompositeMethods
Composite methods - size is fNMethods squared - these DO have tables/perms built


fLHOnlyMethods

Method[] fLHOnlyMethods
Pointers into fCompositeMethods for LH-only search - size = fNMethods


fNCompMethods

int fNCompMethods
Number of composite methods - equals fNMethods squared for HL search


fLeadsPerPart

int fLeadsPerPart
Number of leads per part of composition


fNParts

int fNParts
Desired number of parts for composition


fLHSpliced

boolean fLHSpliced
Set to true if doing LH-only spliced


fTenorsTogether

boolean fTenorsTogether
Set to true if tenors must be together at every leadhead


fNicePartEnds

boolean fNicePartEnds
Set to true if only "nice" part ends are allowed


fAllowCalls

int fAllowCalls
=0 for no calls, 1 for bobs-only and 2 for bobs and singles


fMinPartLength

private int fMinPartLength
Minimum part length to be produced by search.

Since:
Undomiel-B

fMaxPartLength

private int fMaxPartLength
Maximum part length to be produced by search.

Since:
Undomiel-B

fMinScore

int fMinScore
Current minimum score a composition must achieve before being output


fMinBalance

int fMinBalance
Current minimum method balance (0-100) a composition must achieve before being output


fMinCOM

int fMinCOM
Current minimum changes of method (per part) a composition must achieve before being output


fCOMScore

int fCOMScore
The COM weighting - how many points a composition is awarded for each COM per part


fBalanceScore

int fBalanceScore
The balance weighting - how many points a composition is awarded for each method balance percentage point 0-100


fMethodRepeatLimit

int fMethodRepeatLimit
The maximum number of allowed repeated occurrences of a method (for HL spliced, in each half)


fMaxMethodsAtRepeatLimit

int fMaxMethodsAtRepeatLimit
The maximum number of methods that are allowed to reach fMaxMethodRepeat occurrences


fComp

Composition fComp
One Composition reference is held for the entire search


fHost

ComposerHost fHost
The ComposerHost is where output compositions get sent


fRounds

RowNode fRounds
This is kept as a fast way to reference the rounds RowNode


fMethodIndices

int[] fMethodIndices
The current state of the composition during the search; one composite method index per lead


fCalls

int[] fCalls
The current state of calls in each lead of the search (0=plain)


f1stHalfMethodIndices

int[] f1stHalfMethodIndices
For HL searches, the first-half method index for each lead in the current search comp


f2ndHalfMethodIndices

int[] f2ndHalfMethodIndices
For HL searches, the second-half method index for each lead in the current search comp


f1stHalfMethodCounts

int[] f1stHalfMethodCounts
For each method, the number of times it has appeared in the first half-leads of the composition


f2ndHalfMethodCounts

int[] f2ndHalfMethodCounts
For each method, the number of times it has appeared in the second half-leads of the composition


fN1stHalfAtMaxRepeat

int fN1stHalfAtMaxRepeat
The number of methods that have occurred fMaxMethodRepeat times in the first half-leads of the composition


fN2ndHalfAtMaxRepeat

int fN2ndHalfAtMaxRepeat
The number of methods that have occurred fMaxMethodRepeat times in the second half-leads of the composition


fMethodCounts

int[] fMethodCounts
Temporary use by method balance calculator


fProgressRatios

double[] fProgressRatios
Progress scale values for each possible value of the first node (not inc calls)


fProgressCumulatives

double[] fProgressCumulatives

fInitialProgress

double fInitialProgress

fSearchTime

long fSearchTime
Only set when search finished


fInitialTime

long fInitialTime

fNodesSearched

long fNodesSearched

fNComps

int fNComps

fNodesPerSec

int fNodesPerSec

fCompsPerSec

int fCompsPerSec

fBestScore

int fBestScore

fBestMusic

int fBestMusic

fBestCOM

int fBestCOM

fBestBalance

int fBestBalance

fRegenPtr

int fRegenPtr

fStartTime

long fStartTime

fLastTime

long fLastTime

fLastNodes

long fLastNodes

fCompsChecked

long fCompsChecked

fLastComps

long fLastComps

fCounter

int fCounter

fTruthTable

boolean[] fTruthTable
Used for quick check of leadhead proof during search

Constructor Detail

Composer

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 Detail

create

public 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. To use, you must supply an initialised Tables instance (methods and music must be specified, but the tables do not have to be built yet) together with the following search parameters.

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.

Since:
Tinuviel

setAllowCalls

public 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. Note that 4th's place bobs and 1234 singles are assumed. This method should be called immediately after construction. If LH-only spliced has been specified, an implicit setAllowCalls(1) is made.


setCOMScore

public void setCOMScore(int COMScore)
Determines the score weighting given to changes of method. For example, if a composition has 10 changes of method (per part), points worth 10*COMScore will be added to its overall score.

Since:
Tinuviel

setBalanceScore

public void setBalanceScore(int balanceScore)
Determines the score weighting given to method balance. For example, if a composition has a method balance of 85%, points worth 85*BalanceScore will be added to its overall score.

Since:
Tinuviel

setMinPartLength

public void setMinPartLength(int minLength)
Allows a minimum composition length to be set. Only makes sense if varying-length compositions can be produced, which requires methods of different lead lengths to be present.

Parameters:
minLength -

setMaxPartLength

public void setMaxPartLength(int maxLength)
Allows a maximum composition length to be set. Only makes sense if varying-length compositions can be produced, which requires methods of different lead lengths to be present.

Parameters:
maxLength -

initRepeatLimits

public void initRepeatLimits(boolean atw)
Initialises method repeat-count limits; if "atw" set, enforces perfect method balance in both first and second half-leads.


setRepeatLimits

public void setRepeatLimits(int unbalance)
Given an "unbalance" count, sets the repeat limits for methods to prune compositions where methods occur too many times. This method can be called asynchronously whilst composing is in progress to tighten down the search. It is used by Elf as part of the heuristic pruning system: the repeat limits are kept set so that compositions are only considered if they have a method balance sufficient to place them in the current top ten.

Since:
Tinuviel

isComposing

public boolean isComposing()
Returns true if composing is underway, or is paused. Suitable for asynchronous use. See also isFinished().


getNComps

public int getNComps()
Returns the number of true compositions found so far. Suitable for asynchronous use.


getNodesPerSec

public int getNodesPerSec()
Returns an instantaneous measure of the number of leads being processed per second. Suitable for asynchronous use.


getCompsPerSec

public int getCompsPerSec()
Returns an instantaneous measure of the number of compositions being checked (for music and proof) per second. Note that only compositions with good part-ends and who meet the minimum COM and balance criteria are checked. Suitable for asynchronous use.


getBestScore

public int getBestScore()
Returns the score of the best composition found so far. Suitable for asynchronous use.


getBestMusic

public int getBestMusic()
Returns the music count of the most musical composition found so far. Note that this may not be the highest-scoring composition, or even in the top ten, because the total composition score also includes factors such as method balance and COM. Suitable for asynchronous use.


getBestCOM

public int getBestCOM()
Returns the highest number of changes of method (in one part) of any composition found so far. Note that this may not be from the highest-scoring compositions, because the total composition score also includes factors such as method balance and music. Suitable for asynchronous use.


getBestBalance

public int getBestBalance()
Returns the best method balance of any composition found so far. Method balance is a measure of how evenly the number of half-leads of each method are distributed. A balance of 0% means not every method is present - such compositions are automatically rejected. A balance of 100% would mean that every method has equal numbers of half-leads in the part. Note that for half-lead spliced this also takes into account the distribution of methods between first and second half-leads.

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.


getNNodes

public long getNNodes()
Total number of leads searched. Suitable for asynchronous use.


isLHSpliced

public boolean isLHSpliced()
Returns true if the LH-only flag is set.

Since:
Indis

setMinScore

public void setMinScore(int min)
Sets the minimum score that a composition must achieve before being output by the Composer. This method can be called asynchronously whilst composing is in progress to tighten down a search.


setMinBalance

public void setMinBalance(int min)
Sets the minimum method balance that a composition must achieve before being considered for checking. This method can be called asynchronously whilst composing is in progress to tighten down the search. It is used by Elf as part of the heuristic pruning system: the minimum balance is kept set so that compositions are only considered if they have a method balance sufficient to place them in the current top ten.

See Also:
setRepeatLimits(int)

setMinCOM

public void setMinCOM(int min)
Sets the minimum number of changes of method that a composition must achieve before being considered for checking. This method can be called asynchronously whilst composing is in progress to tighten down the search. It is used by Elf as part of the heuristic pruning system: the minimum COM is kept set so that compositions are only considered if they have a COM sufficient to place them in the current top ten.


estimateTimeLeft

public java.lang.String estimateTimeLeft()
Returns (as a String) an estimate of the time left till search completion, in hours and minutes. If a search has made no measurable progress, returns "forever". If the search is paused, returns ">paused<".


getSearchTime

public java.lang.String getSearchTime()
Only valid if isFinished() - returns the total search time, in hours, minutes and seconds, as a String.


setStartComp

public void setStartComp(java.lang.String comp)
The composing engine can be seeded with a "start" composition. This could be used to implement checkpointed searches. The composition is passed as a String, and should be in a form such as:
  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.


findMethod

private int findMethod(java.lang.String abbrev)
Used privately by setStartComp() - looks up a Method reference from its abbreviation String.


compose

public void compose(ComposerHost host)
Starts the search. Note that the inner search loop is contained within the doCompose() method; there are three different implementations of this method, depending on whether the Composer, ComposerCalls or ComposerLH classes are in use. Tables MUST be fully-populated with current methods!


doCompose

void doCompose()
This one doesn't do calls!


backtrack

int backtrack(int i)
This method doesn't do calls!


reduceMethodCounts

void reduceMethodCounts(int one,
                        int two)

isLengthGood

boolean isLengthGood()
Check length of part is between min and max constraints - must only call this if comp has reached part end.

Returns:

calcMethodBalance

int calcMethodBalance()
Calculates a percentage score (as an integer 0-100) representing the method balance of the current composition. For half-lead compositions, the balance figure is a combination (in a ratio 2:1) of the overall method distribution plus the distribution of methods between the first and second half-leads. A balance of 0% is always awarded if there are any methods missing. A 100% balance means each method occurs the same number of times in both the first and second half-leads.

This method must call setBalance() on the Composition instance to ensure the composition knows the current method balance values.


calcMethodDistribution

int calcMethodDistribution(int[] methodCounts,
                           double maxMethods)
Provides an overall measure of method distribution, by finding the mean deviation of method counts from the optimum.


calcUnbalance

int calcUnbalance(int[] counts,
                  int minRep)
Returns an "unbalance" value based on the method counts in the counts[] array. The higher the count value, the WORSE the balance. The count is based on the number of occurrences of the most-repeated method, as follows:
  1. If no method occurs more than the minimum possible number of times (minRep), the count value is equal to the number of methods which occur minRep times.
  2. If one or more methods occur more than minRep times, the count value is equal to fNMethods plus the repeat count of the most common method(s). Because fNMethods is added to this value, it will always be more than the value from (1) above.


checkComp

final int checkComp()
Checks composition for music and truth; if it also meets the current minimum scores, it gets outputted. The return value is the lead number to backtrack to - normally this is nLeadsInPart-1, but if the composition was found to be false in the first part, we can force the engine to backtrack further.

Final for speed.


checkStats

final boolean checkStats()
Should be called every few centiseconds by the main composing loop. Updates stats, checks for pause and abort. Final for speed


getComposingProgress

private double getComposingProgress()

calcProgressRatios

private void calcProgressRatios()
For the rotational sort, progress through the search space speeds up exponentially as the possibilities for the initial node are exhausted. This method calculates a table of ratios for the initial node in order to produce a constant progress value.