Open jmhorcas opened 2 years ago
I have tried again to implement the Product Distribution algorithm from UNED, but without success.
@rheradio could you please take a look to the product_derivation
and get_prod_dist
methods here.
In that branch I've updated the BDDModel to expose a clear interface to work with complemented arcs. Feel free to modify the BDDModel methods too if needed (I am not sure if I am working with complemented arc correctly).
Actually, from this feature model:
I obtain the following BDD with complement arcs:
The PD algorithm traversing the BDD gives to me this:
Node: @-105, id: -105, my_id: -105, index: 1, var: Pizza, negated: True
|- Low node: @104, id: 104, my_id: 104, index: 2, var: Topping, negated: False
|- High node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
Node: @104, id: 104, my_id: 104, index: 2, var: Topping, negated: False
|- Low node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
|- High node: @103, id: 103, my_id: 103, index: 3, var: Salami, negated: False
Node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
Node: @103, id: 103, my_id: 103, index: 3, var: Salami, negated: False
|- Low node: @102, id: 102, my_id: 102, index: 4, var: Ham, negated: False
|- High node: @100, id: 100, my_id: 100, index: 6, var: Size, negated: False
Node: @102, id: 102, my_id: 102, index: 4, var: Ham, negated: False
|- Low node: @101, id: 101, my_id: 101, index: 5, var: Mozzarella, negated: False
|- High node: @100, id: 100, my_id: 100, index: 6, var: Size, negated: False
Node: @101, id: 101, my_id: 101, index: 5, var: Mozzarella, negated: False
|- Low node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
|- High node: @100, id: 100, my_id: 100, index: 6, var: Size, negated: False
Node: @100, id: 100, my_id: 100, index: 6, var: Size, negated: False
|- Low node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
|- High node: @99, id: 99, my_id: 99, index: 7, var: Normal, negated: False
Node: @99, id: 99, my_id: 99, index: 7, var: Normal, negated: False
|- Low node: @80, id: 80, my_id: 80, index: 8, var: Big, negated: False
|- High node: @98, id: 98, my_id: 98, index: 8, var: Big, negated: False
Node: @80, id: 80, my_id: 80, index: 8, var: Big, negated: False
|- Low node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
|- High node: @79, id: 79, my_id: 79, index: 9, var: Dough, negated: False
Node: @79, id: 79, my_id: 79, index: 9, var: Dough, negated: False
|- Low node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
|- High node: @78, id: 78, my_id: 78, index: 10, var: Neapolitan, negated: False
Node: @78, id: 78, my_id: 78, index: 10, var: Neapolitan, negated: False
|- Low node: @-64, id: -64, my_id: -64, index: 11, var: Sicilian, negated: True
|- High node: @64, id: 64, my_id: 64, index: 11, var: Sicilian, negated: False
Node: @-64, id: -64, my_id: -64, index: 11, var: Sicilian, negated: True
|- Low node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
|- High node: @-1, id: -1, my_id: 0, index: 13, var: None, negated: True
Node: @-1, id: -1, my_id: 0, index: 13, var: None, negated: True
Node: @64, id: 64, my_id: 64, index: 11, var: Sicilian, negated: False
|- Low node: @-1, id: -1, my_id: 0, index: 13, var: None, negated: True
|- High node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
Node: @98, id: 98, my_id: 98, index: 8, var: Big, negated: False
|- Low node: @97, id: 97, my_id: 97, index: 9, var: Dough, negated: False
|- High node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
Node: @97, id: 97, my_id: 97, index: 9, var: Dough, negated: False
|- Low node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
|- High node: @96, id: 96, my_id: 96, index: 10, var: Neapolitan, negated: False
Node: @96, id: 96, my_id: 96, index: 10, var: Neapolitan, negated: False
|- Low node: @94, id: 94, my_id: 94, index: 11, var: Sicilian, negated: False
|- High node: @95, id: 95, my_id: 95, index: 11, var: Sicilian, negated: False
Node: @94, id: 94, my_id: 94, index: 11, var: Sicilian, negated: False
|- Low node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
|- High node: @91, id: 91, my_id: 91, index: 12, var: CheesyCrust, negated: False
Node: @91, id: 91, my_id: 91, index: 12, var: CheesyCrust, negated: False
|- Low node: @-1, id: -1, my_id: 0, index: 13, var: None, negated: True
|- High node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
Node: @95, id: 95, my_id: 95, index: 11, var: Sicilian, negated: False
|- Low node: @91, id: 91, my_id: 91, index: 12, var: CheesyCrust, negated: False
|- High node: @1, id: 1, my_id: 1, index: 13, var: None, negated: False
and I've obtaining the following product distribution:
[1, 12, 66, 220, 495, 792, 912, 774, 485, 218, 66, 12, 1]
which of course is wrong.
The correct one is (calculated with the brute force algorithm):
[0, 0, 0, 0, 0, 0, 0, 12, 18, 10, 2, 0, 0]
Here the algorithm I am based on:
Actually, those operations are implemented in a brute force way, that is, enumerating all products with the BDD. Both operations can be implement very efficiently using the algorithms provided by the UNED guys that are available in this paper:
The difficulty is that the BDD implementation uses complemented arcs and therefore the algorithms are not exactly the same. Some attempts (still uncompleted) of the "Product Distribution" algorithm can be found here.
The documentation of the library used "dd" can be found here and here.