In [1]:
classpath.addPath("../jsci-1.2.jar")
classpath.addPath("../figaro_2.11-4.1.0.0.jar")



打印机模型的贝叶斯网络结构

系统诊断模型中的网络结构


In [7]:
import com.cra.figaro.language._
import com.cra.figaro.library.compound._


import com.cra.figaro.language._
import com.cra.figaro.library.compound._

In [5]:
// 打印机模型
val printerPowerButtonOn = Flip(0.95)
val tonerLevel = Select(0.7 -> 'high, 0.2 -> 'low, 0.1 -> 'out)
val tonerLowIndicatorOn = 
    If(printerPowerButtonOn,
      CPD(tonerLevel,
         'high -> Flip(0.2),
         'low -> Flip(0.6),
         'out -> Flip(0.99)),
       Constant(false))
val paperFlow = Select(0.6 -> 'smooth, 0.2 -> 'uneven, 0.2 -> 'jammed)
       
val paperJamIndicatorOn =
    If(printerPowerButtonOn, 
      CPD(paperFlow,
         'smooth -> Flip(0.1),
         'uneven -> Flip(0.3),
         'jammed -> Flip(0.99)),
      Constant(false))

val printerState = 
    Apply(printerPowerButtonOn, tonerLevel, paperFlow,
         (power: Boolean, toner: Symbol, paper: Symbol) => {
             if(power) {
                 if(toner == 'high && paper == 'smooth) 'good
                 else if(toner == 'out || paper == 'jammed) 'out
                 else 'poor
             } else 'out
         })


printerPowerButtonOn: AtomicFlip = Flip(0.95)
tonerLevel: AtomicSelect[Symbol] = Select(0.7 -> 'high, 0.2 -> 'low, 0.1 -> 'out)
tonerLowIndicatorOn: If[Boolean] = If(Flip(0.95), Chain(Select(0.7 -> 'high, 0.2 -> 'low, 0.1 -> 'out), <function1>), Constant(false))
paperFlow: AtomicSelect[Symbol] = Select(0.6 -> 'smooth, 0.2 -> 'uneven, 0.2 -> 'jammed)
paperJamIndicatorOn: If[Boolean] = If(Flip(0.95), Chain(Select(0.6 -> 'smooth, 0.2 -> 'uneven, 0.2 -> 'jammed), <function1>), Constant(false))
printerState: Apply3[Boolean, Symbol, Symbol, Symbol] = Apply(Flip(0.95), Select(0.7 -> 'high, 0.2 -> 'low, 0.1 -> 'out), Select(0.6 -> 'smooth, 0.2 -> 'uneven, 0.2 -> 'jammed), <function3>)

In [8]:
// 打印机故障模型
val softwareState = 
    Select(0.8 -> 'correct, 0.15 -> 'glitchy, 0.05 -> 'crashed)
val networkState = 
    Select(0.7 -> 'up, 0.2 -> 'intermittent, 0.1 -> 'down)
val userCommandCorrect = Flip(0.65)

val numPrintedPages = 
    RichCPD(userCommandCorrect, networkState,
           softwareState, printerState,
           (*, *, *, OneOf('out)) -> Constant('zero),
           (*, *, OneOf('crashed), *) -> Constant('zero),
           (*, OneOf('down), *, *) -> Constant('zero),
           (OneOf(false), *, *, *) -> Select(0.3 -> 'zero, 0.6 -> 'some, 0.1 -> 'all),
           (OneOf(true), *, *, *) -> Select(0.01 -> 'zero, 0.01 -> 'some, 0.98 -> 'all))

val printsQuickly = 
    Chain(networkState, softwareState,
         (network: Symbol, software: Symbol) => 
         if(network == 'down || software == 'crashed)
             Constant(false)
         else if(network == 'intermittent || software == 'glitchy)
             Flip(0.5)
         else Flip(0.9))

val goodPrintQuality =
    CPD(printerState,
        'good -> Flip(0.95),
        'poor -> Flip(0.3),
        'out -> Constant(false))

val printResultSummary = 
    Apply(numPrintedPages, printsQuickly, goodPrintQuality,
         (pages: Symbol, quickly: Boolean, quality: Boolean) =>
         if(pages == 'zero) 'none
         else if(pages == 'some || !quickly == !quality) 'poor
         else 'excellent)


softwareState: AtomicSelect[Symbol] = Select(0.8 -> 'correct, 0.15 -> 'glitchy, 0.05 -> 'crashed)
networkState: AtomicSelect[Symbol] = Select(0.7 -> 'up, 0.2 -> 'intermittent, 0.1 -> 'down)
userCommandCorrect: AtomicFlip = Flip(0.65)
numPrintedPages: RichCPD4[Boolean, Symbol, Symbol, Symbol, Symbol] = Chain(Apply(Flip(0.65), Select(0.7 -> 'up, 0.2 -> 'intermittent, 0.1 -> 'down), Select(0.8 -> 'correct, 0.15 -> 'glitchy, 0.05 -> 'crashed), Apply(Flip(0.95), Select(0.7 -> 'high, 0.2 -> 'low, 0.1 -> 'out), Select(0.6 -> 'smooth, 0.2 -> 'uneven, 0.2 -> 'jammed), <function3>), <function4>), <function1>)
printsQuickly: Chain[(Symbol, Symbol), Boolean] = Chain(Apply(Select(0.7 -> 'up, 0.2 -> 'intermittent, 0.1 -> 'down), Select(0.8 -> 'correct, 0.15 -> 'glitchy, 0.05 -> 'crashed), <function2>), <function1>)
goodPrintQuality: CPD1[Symbol, Boolean] = Chain(Apply(Flip(0.95), Select(0.7 -> 'high, 0.2 -> 'low, 0.1 -> 'out), Select(0.6 -> 'smooth, 0.2 -> 'uneven, 0.2 -> 'jammed), <function3>), <function1>)
printResultSummary: Apply3[Symbol, Boolean, Boolean, Symbol] = Apply(Chain(Apply(Flip(0.65), Select(0.7 -> 'up, 0.2 -> 'intermittent, 0.1 -> 'down), Select(0.8 -> 'correct, 0.15 -> 'glitchy, 0.05 -> 'crashed), Apply(Flip(0.95), Select(0.7 -> 'high, 0.2 -> 'low, 0.1 -> 'out), Select(0.6 -> 'smooth, 0.2 -> 'uneven, 0.2 -> 'jammed), <function3>), <function4>), <function1>), Chain(Apply(Select(0.7 -> 'up, 0.2 -> 'intermittent, 0.1 -> 'down), Select(0.8 -> 'correct, 0.15 -> 'glitchy, 0.05 -> 'crashed), <function2>), <function1>), Chain(Apply(Flip(0.95), Select(0.7 -> 'high, 0.2 -> 'low, 0.1 -> 'out), Select(0.6 -> 'smooth, 0.2 -> 'uneven, 0.2 -> 'jammed), <function3>), <function1>), <function3>)

In [9]:
import com.cra.figaro.algorithm.factored.VariableElimination


import com.cra.figaro.algorithm.factored.VariableElimination

In [10]:
// 1. 没有数据时,打印机电源按钮开启的先验概率
val answerWithNoEvidence = VariableElimination.probability(printerPowerButtonOn, true)
println("Prior probability the printer power button is on = " + answerWithNoEvidence)


Prior probability the printer power button is on = 0.95
answerWithNoEvidence: Double = 0.95

In [11]:
// 2. 如果打印结果不佳,但是不是用户想要的结果
printResultSummary.observe('poor)
val answerIfPrintResultPoor = VariableElimination.probability(printerPowerButtonOn, true)
println("Probability the printer power button is on given a poor result = " + answerIfPrintResultPoor)


Probability the printer power button is on given a poor result = 1.0
answerIfPrintResultPoor: Double = 1.0

In [12]:
// 3. 什么都没有打印进行查询
printResultSummary.observe('none)
val answerIfPrintResultNone = VariableElimination.probability(printerPowerButtonOn, true)
println("Probability the printer power button is on given empty result = " + answerIfPrintResultNone)


Probability the printer power button is on given empty result = 0.8959173432160786
answerIfPrintResultNone: Double = 0.8959173432160786

In [14]:
// 4. printer power button on --> printer state --> print result summary路径上,如果观测到printer state时被阻塞
// 已知打印机状态为停机,得知打印结果为空并没有改变打印机电源按钮开启的概率。
// 因为在Printer State给定的情况下,Print Result Summary条件独立于Printer Power Button on
printResultSummary.unobserve()
printerState.observe('out)
val answerIfPrinterStateOut = VariableElimination.probability(printerPowerButtonOn, true)
println("Probability the printer power button is on given " + "out printer state = " + answerIfPrinterStateOut)

printResultSummary.observe('none)
val answerIfPrinterStateOutAndResultNone = VariableElimination.probability(printerPowerButtonOn, true)
println("Probability the printer power button is on given out printer state and empty result = " + answerIfPrinterStateOutAndResultNone)


Probability the printer power button is on given out printer state = 0.8417721518987341
Probability the printer power button is on given out printer state and empty result = 0.841772151898734
answerIfPrinterStateOut: Double = 0.8417721518987341
answerIfPrinterStateOutAndResultNone: Double = 0.841772151898734

In [15]:
// 5. 如果观察到墨粉不足指示灯,打印机状态良好的概率下降
printResultSummary.unobserve()
printerState.unobserve()
val printerStateGoodPrior = VariableElimination.probability(printerState, 'good)
println("Prior probability the printer state is good = " + printerStateGoodPrior)

tonerLowIndicatorOn.observe(true)
val printerStateGoodGivenTonerLowIndicatorOn = VariableElimination.probability(printerState, 'good)
println("Probability printer state is good given low toner indicator = " + printerStateGoodGivenTonerLowIndicatorOn)


Prior probability the printer state is good = 0.39899999999999997
Probability printer state is good given low toner indicator = 0.23398328690807796
printerStateGoodPrior: Double = 0.39899999999999997
printerStateGoodGivenTonerLowIndicatorOn: Double = 0.23398328690807796

In [16]:
// 6. 一般来说网络正常运行和软件状态相对独立
tonerLowIndicatorOn.unobserve()
val softwareStateCorrectPrior = VariableElimination.probability(softwareState, 'correct)
println("Prior probability the software state is correct = " + softwareStateCorrectPrior)

networkState.observe('up)
val softwareStateCorrectGivenNetworkUp = VariableElimination.probability(softwareState, 'correct)
println("Probability software state is correct given network up = " + softwareStateCorrectGivenNetworkUp)


Prior probability the software state is correct = 0.8
Probability software state is correct given network up = 0.7999999999999999
softwareStateCorrectPrior: Double = 0.8
softwareStateCorrectGivenNetworkUp: Double = 0.7999999999999999

In [17]:
// 7. 如果打印机速度较慢,而得知网络正常连接,将显著降低软件状态正确的概率
// Software State和Network State是独立的,但是在Prints Quickly给定的情况下,导致了诱导依赖性,使得两者不再条件独立
networkState.unobserve()
printsQuickly.observe(false)
val softwareStateCorrectGivenPrintsSlowly = VariableElimination.probability(softwareState, 'correct)
println("Probability software state is correct given prints slowly = " + softwareStateCorrectGivenPrintsSlowly)

networkState.observe('up)
val softwareStateCorrectGivenPrintsSlowlyAndNetworkUp = VariableElimination.probability(softwareState, 'correct)
println("Probability software state is correct given prints slowly and network up = " + softwareStateCorrectGivenPrintsSlowlyAndNetworkUp)


Probability software state is correct given prints slowly = 0.6197991391678623
Probability software state is correct given prints slowly and network up = 0.39024390243902435
softwareStateCorrectGivenPrintsSlowly: Double = 0.6197991391678623
softwareStateCorrectGivenPrintsSlowlyAndNetworkUp: Double = 0.39024390243902435

In [ ]: