mirror of https://github.com/zlatinb/muwire
wip on Markov chain
parent
315f29c668
commit
8798e83ab7
|
@ -2,7 +2,7 @@ package com.muwire.core.hostcache
|
||||||
|
|
||||||
import java.math.RoundingMode
|
import java.math.RoundingMode
|
||||||
|
|
||||||
import static com.muwire.core.connection.ConnectionAttemptStatus.*
|
import com.muwire.core.connection.ConnectionAttemptStatus
|
||||||
|
|
||||||
import groovy.sql.GroovyRowResult
|
import groovy.sql.GroovyRowResult
|
||||||
|
|
||||||
|
@ -19,6 +19,9 @@ class HostMCProfile {
|
||||||
private final BigDecimal RS, RR, RF
|
private final BigDecimal RS, RR, RF
|
||||||
private final BigDecimal FS, FR, FF
|
private final BigDecimal FS, FR, FF
|
||||||
|
|
||||||
|
// start with S
|
||||||
|
ConnectionAttemptStatus state = ConnectionAttemptStatus.SUCCESSFUL
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructs an "optimistic" predictor for newly discovered hosts.
|
* constructs an "optimistic" predictor for newly discovered hosts.
|
||||||
*/
|
*/
|
||||||
|
@ -62,52 +65,50 @@ class HostMCProfile {
|
||||||
FF.setScale(SCALE, MODE)
|
FF.setScale(SCALE, MODE)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
ConnectionAttemptStatus transition() {
|
||||||
* @param current status of this host
|
|
||||||
* @param nextStatus the next status of this host
|
SortedMap<BigDecimal, ConnectionAttemptStatus> ignitionMap = new TreeMap<>()
|
||||||
* @return probability of such status
|
switch(state) {
|
||||||
*/
|
case ConnectionAttemptStatus.SUCCESSFUL :
|
||||||
private BigDecimal transition(def currentStatus, def nextStatus) {
|
ignitionMap.put(SS, ConnectionAttemptStatus.SUCCESSFUL)
|
||||||
switch(currentStatus) {
|
ignitionMap.put(SR, ConnectionAttemptStatus.REJECTED)
|
||||||
case SUCCESSFUL :
|
ignitionMap.put(SF, ConnectionAttemptStatus.FAILED)
|
||||||
switch(nextStatus) {
|
break
|
||||||
case SUCCESSFUL : return SS
|
case ConnectionAttemptStatus.REJECTED :
|
||||||
case REJECTED : return SR
|
ignitionMap.put(RS, ConnectionAttemptStatus.SUCCESSFUL)
|
||||||
case FAILED : return SF
|
ignitionMap.put(RR, ConnectionAttemptStatus.REJECTED)
|
||||||
}
|
ignitionMap.put(RF, ConnectionAttemptStatus.FAILED)
|
||||||
case REJECTED :
|
break
|
||||||
switch(nextStatus) {
|
case ConnectionAttemptStatus.FAILED:
|
||||||
case SUCCESSFUL : return RS
|
ignitionMap.put(FS, ConnectionAttemptStatus.SUCCESSFUL)
|
||||||
case REJECTED : return RR
|
ignitionMap.put(FR, ConnectionAttemptStatus.REJECTED)
|
||||||
case FAILED : return RF
|
ignitionMap.put(FF, ConnectionAttemptStatus.FAILED)
|
||||||
}
|
break
|
||||||
case FAILED :
|
|
||||||
switch(nextStatus) {
|
|
||||||
case SUCCESSFUL : return FS
|
|
||||||
case REJECTED : return FR
|
|
||||||
case FAILED : return FF
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BigDecimal[] probs = new BigDecimal[3]
|
||||||
|
ConnectionAttemptStatus[] states = new ConnectionAttemptStatus[3]
|
||||||
|
|
||||||
|
Iterator<BigDecimal> iter = ignitionMap.keySet().iterator()
|
||||||
|
probs[0] = iter.next()
|
||||||
|
states[0] = ignitionMap.get(probs[0])
|
||||||
|
probs[1] = iter.next()
|
||||||
|
states[1] = ignitionMap.get(probs[1])
|
||||||
|
probs[2] = iter.next()
|
||||||
|
states[2] = ignitionMap.get(probs[2])
|
||||||
|
|
||||||
|
probs[1] += probs[0]
|
||||||
|
probs[2] += probs[1]
|
||||||
|
|
||||||
|
final double random = Math.random()
|
||||||
|
if (random < probs[0])
|
||||||
|
state = states[0]
|
||||||
|
else if (random < probs[1])
|
||||||
|
state = states[1]
|
||||||
|
else
|
||||||
|
state = states[2]
|
||||||
|
|
||||||
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param lastStatus last observed status
|
|
||||||
* @param periods how many periods ago
|
|
||||||
* @return probability of next status being SUCCESSFUL
|
|
||||||
*/
|
|
||||||
public BigDecimal connectSuccessProbability(def lastStatus, int periods) {
|
|
||||||
if (periods == 0) {
|
|
||||||
return transition(lastStatus, SUCCESSFUL)
|
|
||||||
} else {
|
|
||||||
def toSuccess = transition(lastStatus, SUCCESSFUL)
|
|
||||||
def toReject = transition(lastStatus, REJECTED)
|
|
||||||
def toFail = transition(lastStatus, FAILED)
|
|
||||||
final newPeriods = periods - 1
|
|
||||||
BigDecimal rv = toSuccess * connectSuccessProbability(SUCCESSFUL, newPeriods) +
|
|
||||||
toReject * connectSuccessProbability(REJECTED, newPeriods) +
|
|
||||||
toFail * connectSuccessProbability(FAILED, newPeriods)
|
|
||||||
rv.setScale(SCALE, MODE)
|
|
||||||
return rv
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue