148 lines
3.7 KiB
Plaintext
148 lines
3.7 KiB
Plaintext
import "./fmt" for Fmt
|
|
|
|
class FCNode {
|
|
construct new(name, weight, coverage) {
|
|
_name = name
|
|
_weight = weight
|
|
_coverage = coverage
|
|
_children = []
|
|
_parent = null
|
|
}
|
|
|
|
static new(name, weight) { new(name, weight, 0) }
|
|
static new(name) { new(name, 1, 0) }
|
|
|
|
name { _name }
|
|
weight { _weight }
|
|
coverage { _coverage }
|
|
|
|
coverage=(value) {
|
|
if (_coverage != value) {
|
|
_coverage = value
|
|
if (_parent) {
|
|
_parent.updateCoverage_() // update any parent's coverage
|
|
}
|
|
}
|
|
}
|
|
|
|
parent { _parent }
|
|
parent=(p) { _parent = p }
|
|
|
|
addChildren(nodes) {
|
|
_children.addAll(nodes)
|
|
for (node in nodes) node.parent = this
|
|
updateCoverage_()
|
|
}
|
|
|
|
updateCoverage_() {
|
|
var v1 = _children.reduce(0) { |acc, n| acc + n.weight * n.coverage }
|
|
var v2 = _children.reduce(0) { |acc, n| acc + n.weight }
|
|
coverage = v1 / v2
|
|
}
|
|
|
|
show(level) {
|
|
var indent = level * 4
|
|
var nl = _name.count + indent
|
|
Fmt.lprint("$*s$*s $3d | $8.6f |", [nl, _name, 32-nl, "|", _weight, _coverage])
|
|
if (_children.isEmpty) return
|
|
for (child in _children) child.show(level+1)
|
|
}
|
|
}
|
|
|
|
var houses = [
|
|
FCNode.new("house1", 40),
|
|
FCNode.new("house2", 60)
|
|
]
|
|
|
|
var house1 = [
|
|
FCNode.new("bedrooms", 1, 0.25),
|
|
FCNode.new("bathrooms"),
|
|
FCNode.new("attic", 1, 0.75),
|
|
FCNode.new("kitchen", 1, 0.1),
|
|
FCNode.new("living_rooms"),
|
|
FCNode.new("basement"),
|
|
FCNode.new("garage"),
|
|
FCNode.new("garden", 1, 0.8)
|
|
]
|
|
|
|
var house2 = [
|
|
FCNode.new("upstairs"),
|
|
FCNode.new("groundfloor"),
|
|
FCNode.new("basement")
|
|
]
|
|
|
|
var h1Bathrooms = [
|
|
FCNode.new("bathroom1", 1, 0.5),
|
|
FCNode.new("bathroom2"),
|
|
FCNode.new("outside_lavatory", 1, 1)
|
|
]
|
|
|
|
var h1LivingRooms = [
|
|
FCNode.new("lounge"),
|
|
FCNode.new("dining_room"),
|
|
FCNode.new("conservatory"),
|
|
FCNode.new("playroom", 1, 1)
|
|
]
|
|
|
|
var h2Upstairs = [
|
|
FCNode.new("bedrooms"),
|
|
FCNode.new("bathroom"),
|
|
FCNode.new("toilet"),
|
|
FCNode.new("attics", 1, 0.6)
|
|
]
|
|
|
|
var h2Groundfloor = [
|
|
FCNode.new("kitchen"),
|
|
FCNode.new("living_rooms"),
|
|
FCNode.new("wet_room_&_toilet"),
|
|
FCNode.new("garage"),
|
|
FCNode.new("garden", 1, 0.9),
|
|
FCNode.new("hot_tub_suite", 1, 1)
|
|
]
|
|
|
|
var h2Basement = [
|
|
FCNode.new("cellars", 1, 1),
|
|
FCNode.new("wine_cellar", 1, 1),
|
|
FCNode.new("cinema", 1, 0.75)
|
|
]
|
|
|
|
var h2UpstairsBedrooms = [
|
|
FCNode.new("suite_1"),
|
|
FCNode.new("suite_2"),
|
|
FCNode.new("bedroom_3"),
|
|
FCNode.new("bedroom_4")
|
|
]
|
|
|
|
var h2GroundfloorLivingRooms = [
|
|
FCNode.new("lounge"),
|
|
FCNode.new("dining_room"),
|
|
FCNode.new("conservatory"),
|
|
FCNode.new("playroom")
|
|
]
|
|
|
|
var cleaning = FCNode.new("cleaning")
|
|
|
|
house1[1].addChildren(h1Bathrooms)
|
|
house1[4].addChildren(h1LivingRooms)
|
|
houses[0].addChildren(house1)
|
|
|
|
h2Upstairs[0].addChildren(h2UpstairsBedrooms)
|
|
house2[0].addChildren(h2Upstairs)
|
|
h2Groundfloor[1].addChildren(h2GroundfloorLivingRooms)
|
|
house2[1].addChildren(h2Groundfloor)
|
|
house2[2].addChildren(h2Basement)
|
|
houses[1].addChildren(house2)
|
|
|
|
cleaning.addChildren(houses)
|
|
var topCoverage = cleaning.coverage
|
|
Fmt.print("TOP COVERAGE = $8.6f\n", topCoverage)
|
|
System.print("NAME HIERARCHY | WEIGHT | COVERAGE |")
|
|
cleaning.show(0)
|
|
|
|
h2Basement[2].coverage = 1 // change Cinema node coverage to 1
|
|
var diff = cleaning.coverage - topCoverage
|
|
System.print("\nIf the coverage of the Cinema node were increased from 0.75 to 1")
|
|
System.write("the top level coverage would increase by ")
|
|
Fmt.print("$8.6f to $8.6f", diff, topCoverage + diff)
|
|
h2Basement[2].coverage = 0.75 // restore to original value if required
|