I encountered a problem while I was trying to match images with their correlation coefficient.
Say we have 5 thumbnails (a, b, c, d, e) and we need to find the best corresponding thumbnail for each one of them on another set of thumbnails (f, g, h, i, j). (One item cannot be re-used.)
For each possible pair, we compute the correlation coefficient (measurement of similarity).
f g h i j
|-----|-----|-----|-----|-----|
a | 0.5 | 0.7 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
b | 0.7 | 0.8 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
c | 0 | 0 | 0 | 0 | 0.8 |
|-----|-----|-----|-----|-----|
d | 0 | 0 | 0.5 | 0.6 | 0.7 |
|-----|-----|-----|-----|-----|
e | 0 | 0.6 | 0.7 | 0.5 | 0 |
|-----|-----|-----|-----|-----|
What I do :
Find the max for each raw
f g h i j
|-----|-----|-----|-----|-----|
a | 0 | 0.7 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
b | 0 | 0.8 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
c | 0 | 0 | 0 | 0 | 0.8 |
|-----|-----|-----|-----|-----|
d | 0 | 0 | 0 | 0 | 0.7 |
|-----|-----|-----|-----|-----|
e | 0 | 0 | 0.7 | 0 | 0 |
|-----|-----|-----|-----|-----|
Find the max for each column
f g h i j
|-----|-----|-----|-----|-----|
a | 0 | 0 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
b | 0 | 0.8 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
c | 0 | 0 | 0 | 0 | 0.8 |
|-----|-----|-----|-----|-----|
d | 0 | 0 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
e | 0 | 0 | 0.7 | 0 | 0 |
|-----|-----|-----|-----|-----|
Save those pairs in a table
Create a mask where the raw and the column of each number in this last table are equal to zero
f g h i j
|-----|-----|-----|-----|-----|
a | 1 | 0 | 0 | 1 | 0 |
|-----|-----|-----|-----|-----|
b | 0 | 0 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
c | 0 | 0 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
d | 1 | 0 | 0 | 1 | 0 |
|-----|-----|-----|-----|-----|
e | 0 | 0 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
Multiply the mask with the first table
f g h i j
|-----|-----|-----|-----|-----|
a | 0.5 | 0 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
b | 0 | 0 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
c | 0 | 0 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
d | 0 | 0 | 0 | 0.6 | 0 |
|-----|-----|-----|-----|-----|
e | 0 | 0 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
Repeat the process until the matrix obtained at the second step is equal to zero
So at the end, the matching table looks like that :
f g h i j
|-----|-----|-----|-----|-----|
a | 1 | 0 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
b | 0 | 1 | 0 | 0 | 0 |
|-----|-----|-----|-----|-----|
c | 0 | 0 | 0 | 0 | 1 |
|-----|-----|-----|-----|-----|
d | 0 | 0 | 0 | 1 | 0 |
|-----|-----|-----|-----|-----|
e | 0 | 0 | 1 | 0 | 0 |
|-----|-----|-----|-----|-----|
According the this method, the best pairs possible are :
(a,f), (b,g), (c,j), (d,i) and (e,h)
Now the question is :
Is there a better method?
Like for (a,b) and (f,g), wouldn't be better to add up their scores to find the best match?
Ex :
(a,f) (b,g)
0.5 + 0.7 = 1.2
(a,g) (b,f)
0.7 + 0.7 = 1.4
1.4 > 1.2 => best pairs are (a,g) and (b,f)
(As opposed to (a,f), (b,g) with the first method.)
If so, how to make it generalizable?
I hope that I've been clear enough to make you understand the problem.
Thanks in advance for your help.
EDIT :
I found out that the Hungarian algorithm is much faster than the ILP solution provided by AirSquid.
I compared the Hungarian implementation of Scipy (https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.linear_sum_assignment.html) with the ILP based solution.
After 1000 one-to-one matching iterations of a random 20x20 matrix I got :
Method
ite/s
ILP solution
4.06e-2
Hungarian algorithm
1.808e-5
From tests, I haven't seen any differences between those two methods.
This is a trivial pairing model for most any math solver and can be formulated as an ILP. If you wish to go this route in python, you have several choices (after learning a bit about LP/ILP formulation :) ). I'm partial to pyomo but pulp and or-tools are also viable. You will also need a solver engine. There are several freebies out there, some are easier to install than others. I believe pulp has a built-in solver, which is nice.
There is probably a dynamic programming solution to consider as well, but this is fast & easy. For the examples I note in the problem below (a replica of the counter-example above and a random 20x20 matrix), optimal solutions are almost instantaneous.
# pairing
import pyomo.environ as pyo
import numpy as np
data = [[.99, .98, .97, .96, .95],
[.98, .97, .96, .95, 0],
[.97, .96, .95, 0, 0],
[.96, .95, 0, 0, 0],
[.95, 0, 0, 0, 0]]
#data = np.random.rand(20, 20) #alternate random data for testing...
model = pyo.ConcreteModel('r-c pairings')
#re-label the data and push into a dictionary
labels = list('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
data = {(labels[r], labels[len(data) + c]) : data[r][c]
for r in range(len(data)) for c in range(len(data[0]))}
# pyomo components
model.R = pyo.Set(initialize = [k[0] for k in data.keys()])
model.C = pyo.Set(initialize = [k[1] for k in data.keys()])
model.corr = pyo.Param(model.R, model.C, initialize=data)
model.X = pyo.Var(model.R, model.C, within=pyo.Binary) # select pairing (r, c)
# objective: maximize overall value
model.obj = pyo.Objective(expr=pyo.summation(model.corr, model.X), sense=pyo.maximize) #shortcut to ∑cX
# constraint: only use each column value once
def single_use(m, c):
return sum(model.X[r,c] for r in model.R) <= 1
model.C1 = pyo.Constraint(model.C, rule=single_use)
# constraint: only use each row value once
def single_use_row(m, r):
return sum(model.X[r,c] for c in model.C) <= 1
model.C2 = pyo.Constraint(model.R, rule=single_use_row)
# solve it...
solver = pyo.SolverFactory('glpk') # <-- need to have this solver installed
result = solver.solve(model)
print(result)
pyo.display(model)
Output (from the smaller data run):
Problem:
- Name: unknown
Lower bound: 4.75
Upper bound: 4.75
Number of objectives: 1
Number of constraints: 11
Number of variables: 26
Number of nonzeros: 51
Sense: maximize
Solver:
- Status: ok
Termination condition: optimal
Statistics:
Branch and bound:
Number of bounded subproblems: 1
Number of created subproblems: 1
Error rc: 0
Time: 0.010313272476196289
Solution:
- number of solutions: 0
number of solutions displayed: 0
Model r-c pairings
Variables:
X : Size=25, Index=X_index
Key : Lower : Value : Upper : Fixed : Stale : Domain
('a', 'f') : 0 : 0.0 : 1 : False : False : Binary
('a', 'g') : 0 : 0.0 : 1 : False : False : Binary
('a', 'h') : 0 : 0.0 : 1 : False : False : Binary
('a', 'i') : 0 : 0.0 : 1 : False : False : Binary
('a', 'j') : 0 : 1.0 : 1 : False : False : Binary
('b', 'f') : 0 : 0.0 : 1 : False : False : Binary
('b', 'g') : 0 : 0.0 : 1 : False : False : Binary
('b', 'h') : 0 : 0.0 : 1 : False : False : Binary
('b', 'i') : 0 : 1.0 : 1 : False : False : Binary
('b', 'j') : 0 : 0.0 : 1 : False : False : Binary
('c', 'f') : 0 : 0.0 : 1 : False : False : Binary
('c', 'g') : 0 : 0.0 : 1 : False : False : Binary
('c', 'h') : 0 : 1.0 : 1 : False : False : Binary
('c', 'i') : 0 : 0.0 : 1 : False : False : Binary
('c', 'j') : 0 : 0.0 : 1 : False : False : Binary
('d', 'f') : 0 : 0.0 : 1 : False : False : Binary
('d', 'g') : 0 : 1.0 : 1 : False : False : Binary
('d', 'h') : 0 : 0.0 : 1 : False : False : Binary
('d', 'i') : 0 : 0.0 : 1 : False : False : Binary
('d', 'j') : 0 : 0.0 : 1 : False : False : Binary
('e', 'f') : 0 : 1.0 : 1 : False : False : Binary
('e', 'g') : 0 : 0.0 : 1 : False : False : Binary
('e', 'h') : 0 : 0.0 : 1 : False : False : Binary
('e', 'i') : 0 : 0.0 : 1 : False : False : Binary
('e', 'j') : 0 : 0.0 : 1 : False : False : Binary
Objectives:
obj : Size=1, Index=None, Active=True
Key : Active : Value
None : True : 4.75
Constraints:
C1 : Size=5
Key : Lower : Body : Upper
f : None : 1.0 : 1.0
g : None : 1.0 : 1.0
h : None : 1.0 : 1.0
i : None : 1.0 : 1.0
j : None : 1.0 : 1.0
C2 : Size=5
Key : Lower : Body : Upper
a : None : 1.0 : 1.0
b : None : 1.0 : 1.0
c : None : 1.0 : 1.0
d : None : 1.0 : 1.0
e : None : 1.0 : 1.0
I think your method is broken for some cases.
For an example consider:
f g
|-----|-----|
a | 0.9 | 0.8 |
|-----|-----|
b | 0.8 | 0 |
|-----|-----|
For this case, the best solution is ag and bf, where the total score is "0.8 + 0.8 = 1.6". If you choose the maximum score first (af) you're forced to use bg as the second pair (as there's no other choice left), and that gives you a total score of "0.9 + 0 = 0.9", which is much worse.
Note that the same problem exists (and can be much worse) for 5 pairs. E.g. for an extreme case:
f g h i j
|------|------|------|------|------|
a | 0.99 | 0.98 | 0.97 | 0.96 | 0.95 |
|------|------|------|------|------|
b | 0.98 | 0.97 | 0.96 | 0.95 | 0 |
|------|------|------|------|------|
c | 0.97 | 0.96 | 0.95 | 0 | 0 |
|------|------|------|------|------|
d | 0.96 | 0.95 | 0 | 0 | 0 |
|------|------|------|------|------|
e | 0.95 | 0 | 0 | 0 | 0 |
|------|------|------|------|------|
Here, "maximum first" leads to af, bg, ch, di, ej with a total score of 2.91; but the best solution is ef, dg, ch, bi, aj with a total score of 4.75.
To find the best pairings; you want to calculate the total for each possibility, then find the highest total. The simplest way to do that is with a brute force approach (literally, calculate a total for every possibility) but that has relatively high overhead.
Assuming a "nested loops" approach (e.g. where you have an outer loop iterating through the possibilities for a, an inner loop iterating through possibilities for b, ...; and where each inner loop can create a new "partial total" so that the inner-most loop can use the partial total rather than calculating the full total itself); I don't think there's a practical way to improve performance (without creating a risk of failing to find the best solution).
Related
I need to design Programmable Logic Array (PLA) circuit with given functions. How can I design circuit with POS form functions. Can someone explain that? enter image description here
Below is the design process completed for F, the other two outputs, G and H, can done in a similar fashon.
F Truth Table
A B C D # F G H
0 0 0 0 0 1
0 0 0 1 1 0
0 0 1 0 2 0
0 0 1 1 3 1
0 1 0 0 4 1
0 1 0 1 5 1
0 1 1 0 6 0
0 1 1 1 7 0
1 0 0 0 8 0
1 0 0 1 9 0
1 0 1 0 10 1
1 0 1 1 11 1
1 1 0 0 12 0
1 1 0 1 13 0
1 1 1 0 14 1
1 1 1 1 15 1
F Karnaugh Map:
AB\CD 00 01 11 10
\
----------
00 0 | 1 x 1 | 0
----------
--------
01 | 1 y 1 | 0 0
--------
----------
11 0 0 | 1 1 |
| z |
| |
10 0 0 | 1 1 |
----------
F Sum Of Product Boolean:
(A'B'D)+(A'BC')+(AC)
x y z ==>(for ref):
x=(A'B'D)
y=(A'BC')
z=(AC)
F Logic Circuit:
------- ------
A---NOT---| | ------- | |
| AND |---| | | |
B---NOT---| | | AND | x | |
------- | |--------------| |
D---------------------------| | | |
------- | |
| | F
------- | OR |---
A---NOT---| | ------- ------ | |
| AND |---| | y | | | |
C---NOT---| | | AND |---| | | |
------- | | | | y+z | |
B---------------------------| | | |-----| |
------- | OR | | |
------- | | | |
A---NOT---| | z | | | |
| AND |---------------------| | ------
C---NOT---| | | |
------- | |
------
I am to implement an 8-to-1 multiplexer using the variables m(1,3,5,6,8,13). The function is:
F(A,B,C,D) = A′B′C′D + A′B′CD + A′BC′D + A′BCD′ + AB′C′D′ + ABC′D
I feel I have a basic idea of how multiplexers work, however I'm not entirely sure what to do with the numbers given. I created a truth table with ABCD and plugged it into the function. Then I created the multiplexer based upon the output. (Which I got to be: D', D', D', D, D, 0, D', 0) The only thing I haven't done, and I can't figure out how to do, is the variables. How do they relate to the function and multiplexer?
A multiplexer works as a switch. It selects one of the available inputs I and based on the given address bits S sends the selected input's value on the output Z.
For example:
–––––––––––
| MUX | +-------++-----+-----++-----+
| | | index || a_1 | a_0 || f |
D_0 –––| I_0 | |---------------------------|
D_1 –––| I_1 Z |––– f | 0 || 0 | 0 || D_0 |
D_2 –––| I_2 | | 1 || 0 | 1 || D_1 |
D_3 –––| I_3 | | 2 || 1 | 0 || D_2 |
| | | 3 || 1 | 1 || D_3 |
| S | +-------++-----+-----++-----+
–––––––––––
| |
a_1 a_0
In the example the output function is defined:
f = ¬a_1⋅¬a_0⋅D_0 + ¬a_1⋅a_0⋅D_1 + a_1⋅¬a_0⋅D_2 + a_1⋅a_0⋅D_3
In your case, the output is described by the given function of four variables and the multiplexer is supposed to be an 8:1, so there will be three variables used as the address bits (a, b and c) and the fourth (d) as the partitioned off input signal – parameter of the function f(d) representing the output value.
f(a,b,c,d)=¬a⋅¬b⋅¬c⋅d + ¬a⋅¬b⋅c⋅d + ¬a⋅b⋅¬c⋅d + ¬a⋅b⋅c⋅¬d + a⋅¬b⋅¬c⋅¬d + a⋅b⋅¬c⋅d
index || a | b | c | d || f(a,b,c,d) | f(d)
---------------------------------------------
0 || 0 | 0 | 0 | 0 || 0 | d
1 || 0 | 0 | 0 | 1 || 1 | d
2 || 0 | 0 | 1 | 0 || 0 | d
3 || 0 | 0 | 1 | 1 || 1 | d
---------------------------------------------
4 || 0 | 1 | 0 | 0 || 0 | d
5 || 0 | 1 | 0 | 1 || 1 | d
6 || 0 | 1 | 1 | 0 || 1 | ¬d
7 || 0 | 1 | 1 | 1 || 0 | ¬d
---------------------------------------------
8 || 1 | 0 | 0 | 0 || 1 | ¬d
9 || 1 | 0 | 0 | 1 || 0 | ¬d
10 || 1 | 0 | 1 | 0 || 0 | 0
11 || 1 | 0 | 1 | 1 || 0 | 0
---------------------------------------------
12 || 1 | 1 | 0 | 0 || 0 | d
13 || 1 | 1 | 0 | 1 || 1 | d
14 || 1 | 1 | 1 | 0 || 0 | 0
15 || 1 | 1 | 1 | 1 || 0 | 0
The truth table has been reduced to 8 lines by partitioning the input signal d off. Now the number of rows matches the number of multiplexer's inputs.
index || a | b | c || f(d)
-----------------------------
0 || 0 | 0 | 0 || d
1 || 0 | 0 | 1 || d
2 || 0 | 1 | 0 || d
3 || 0 | 1 | 1 || ¬d
-----------------------------
4 || 1 | 0 | 0 || ¬d
5 || 1 | 0 | 1 || 0
6 || 1 | 1 | 0 || d
7 || 1 | 1 | 1 || 0
In the following picture is a graphical representation of the multiplex.
Multiplexer (MUX)
MUX is a data selector
It allows digital information from several sources be routed into one single line for transmission over the line to a destination
A B C D are the sources and Q is the output. a b are the data selectors
Here is the truth table for 4:1 multiplexer
a | b | Q
0 | 0 | A
0 | 1 | B
1 | 0 | C
1 | 1 | D
The output Q is
Q = A+B+C+B
A=a'b' , B = a'b , C=ab' , D= ab
Q = a'b' + a'b + ab' + ab
So my state diagram has seven states (000 to 110), an input B button, and four outputs P, Q, R, and S.
I've made the truth table, which has 16 rows (two of which have Xs). I'm supposed to make 7 K-Maps out of this, S2' S1' S0' P Q R and S. I understand that the input B (0, 1) will be on the column side (or row), but I'm having trouble with the rows. S2 is most significant digit, S0 least.
I've never seen a K-Map with 3 bits (S2/S1/S0) on one side, but I don't know how to represent it in any other way. And if it is three bits, what order do those numbers go in? For two, I know it's 00/01/11/10.
If it's two, which seems like the right idea, then how do you decide between two of the three (S2/S1/S0)? Does the input B side get an additional variable next to it (so it would be S2/S1 on the column and B/S0 on the rows?). How do you decide which of the S2/S1/S0 is put on the other side, does it even matter?
One big help for me would be to see an example of a truth table/k-maps for a S2/S1/S0 state diagram. I've only ever seen examples of S1/S0, so no more than 4 states (00/01/10/11).
Thank you for any help you can provide. I'm sorry if my question is confusing. Please let me know if I can be any clearer about my problem.
First there are the answers to your questions:
Number of cells in every Karnaugh map matches the number of all possible input combinations. The way how the map's cells are indexed has to correspond to the truth table. In the following picture are examples of the different sizes of Karnaugh maps, where the visualisation of neighbouring cells is still pretty easy.
As you can see, the point is, that two neighbouring cells differ only in one variable's value, four neighbouring cells differ in two variables' values and so on. That is why you should look for groups that have the size of the 2^n. Map's indexing could look a bit mixed up, but that is for the purpose of displaying all the relationships between each and every row in the truth table.
If you index a K-map, but do not know, which lines are for which variables and in which order they should go in, then you can check it like this:
index 0 = where not a single variable is true
index 1 = where only the least significant bit is true (for a truth table ordered abcd that would be the d)
index 2 = where only the second least significant bit is true (for the same truth table that would be the c)
index 4 = where only the third least significant bit is true (for the same truth table that would be the b)
index 8 = where only the fourth least significant bit is true (for the same truth table that would be the a)
As for an example: Here you can see a state diagram of a 01364 sequence generator implemented as a Moore machine. All edges of the machine are labelled by an input value of a reset button.
The machine's desired behaviour and the output values matching the states can be described by this transition table:
state || output (decimal) | reset || next state
-------------------------------------------------
S_0 || 0 | 0 || S_1
|| | 1 || S_0
-------------------------------------------------
S_1 || 1 | 0 || S_2
|| | 1 || S_0
-------------------------------------------------
S_2 || 3 | 0 || S_3
|| | 1 || S_0
-------------------------------------------------
S_3 || 6 | 0 || S_4
|| | 1 || S_0
-------------------------------------------------
S_4 || 4 | 0 || S_0
|| | 1 || S_0
After encoding the states' representation to match the decimal outputs in binary (q_2, q_1 and q_0; d_2, d_1 and d_0), the transition table looks like this:
state || q_2 | q_1 | q_0 | reset || d_2 | d_1 | d_0 || next state
-------------------------------------------------------------------
S_0 || 0 | 0 | 0 | 0 || 0 | 0 | 1 || S_1
|| | | | 1 || 0 | 0 | 0 || S_0
-------------------------------------------------------------------
S_1 || 0 | 0 | 1 | 0 || 0 | 1 | 1 || S_2
|| | | | 1 || 0 | 0 | 0 || S_0
-------------------------------------------------------------------
S_2 || 0 | 1 | 1 | 0 || 1 | 1 | 0 || S_3
|| | | | 1 || 0 | 0 | 0 || S_0
-------------------------------------------------------------------
S_3 || 1 | 1 | 0 | 0 || 1 | 0 | 0 || S_4
|| | | | 1 || 0 | 0 | 0 || S_0
-------------------------------------------------------------------
S_4 || 1 | 0 | 0 | 0 || 0 | 0 | 0 || S_0
|| | | | 1 || 0 | 0 | 0 || S_0
It is useful to study the transition table for every possible combination of inputs, because there are some 'do not care' (x) output values (for the states, that are not present in the sequence), which can be used for minimisation by Karnaugh maps.
index | state || q_2 | q_1 | q_0 | reset || d_2 | d_1 | d_0 || next state
---------------------------------------------------------------------------
0 | S_0 || 0 | 0 | 0 | 0 || 0 | 0 | 1 || S_1
1 | S_0 || 0 | 0 | 0 | 1 || 0 | 0 | 0 || S_0
---------------------------------------------------------------------------
2 | S_1 || 0 | 0 | 1 | 0 || 0 | 1 | 1 || S_2
3 | S_1 || 0 | 0 | 1 | 1 || 0 | 0 | 0 || S_0
---------------------------------------------------------------------------
4 | - || 0 | 1 | 0 | 0 || x | x | x || -
5 | - || 0 | 1 | 0 | 1 || 0 | 0 | 0 || S_0
---------------------------------------------------------------------------
6 | S_2 || 0 | 1 | 1 | 0 || 1 | 1 | 0 || S_3
7 | S_2 || 0 | 1 | 1 | 1 || 0 | 0 | 0 || S_0
---------------------------------------------------------------------------
8 | S_4 || 1 | 0 | 0 | 0 || 0 | 0 | 0 || S_0
9 | S_4 || 1 | 0 | 0 | 1 || 0 | 0 | 0 || S_0
---------------------------------------------------------------------------
10 | - || 1 | 0 | 1 | 0 || x | x | x || -
11 | - || 1 | 0 | 1 | 1 || 0 | 0 | 0 || S_0
---------------------------------------------------------------------------
12 | S_3 || 1 | 1 | 0 | 0 || 1 | 0 | 0 || S_4
13 | S_3 || 1 | 1 | 0 | 1 || 0 | 0 | 0 || S_0
---------------------------------------------------------------------------
14 | - || 1 | 1 | 1 | 0 || x | x | x || -
15 | - || 1 | 1 | 1 | 1 || 0 | 0 | 0 || S_0
Finally you can see, that the functions defining the d_2, d_1 and d_0 (that is the binary encoded state/output matching the number in the 01364 sequence) can be simply marked out in the following K-maps.
f(d_2) = q_1 ⋅ ¬(reset)
f(d_1) = q_0 ⋅ ¬(reset)
f(d_0) = ¬(q_2) ⋅ ¬(q_1) ⋅ ¬(reset)
(All images were generated using latex.)
I have seen a different style of Karnaugh Map for logic design. This is the style they used:
Anyone knows how this K-Map done? How to comprehend with this kind of map? Or how they derived from that equation from that map. The map is quite different from the common map like this:
The maps relate to each other this way, the only difference is the cells' (terms') indexes corresponding to the variables or the order of the variables.
The exclamation mark is only an alternative to the negation of a variable. !A is the same as ¬A, also sometimes noted A'.
!A A A !A ↓CD\AB → 00 01 11 10
+----+----+----+----+ +----+----+----+----+
!B | 1 | 0 | 1 | 0 | !D 00 | 1 | 1 | 1 | 0 |
+----+----+----+----+ +----+----+----+----+
B | 1 | 1 | 1 | 1 | !D ~ 01 | 1 | x | x | 1 |
+----+----+----+----+ +----+----+----+----+
B | x | x | x | x | D 11 | x | x | x | x |
+----+----+----+----+ +----+----+----+----+
!B | 1 | 1 | x | x | D 10 | 0 | 1 | 1 | 1 |
+----+----+----+----+ +----+----+----+----+
!C !C C C
If you are unsure, of the indexes in the given K-map, you can always check that by writing the corresponding truth-table.
For example the output value of the first cell in the "strange" K-map is equal to 1 if !A·!B·!C·!D (all variables in its negation), that corresponds with the first line of the truth-table, so the index is 0. And so on.
index | A B C D | y
=======+=========+===
0 | 0 0 0 0 | 1
1 | 0 0 0 1 | 1
2 | 0 0 1 0 | 0
3 | 0 0 1 1 | x ~ 'do not care' state/output
-------+---------+---
4 | 0 1 0 0 | 1
5 | 0 1 0 1 | x
6 | 0 1 1 0 | 1
7 | 0 1 1 1 | x
-------+---------+---
8 | 1 0 0 0 | 0
9 | 1 0 0 1 | 1
10 | 1 0 1 0 | 1
11 | 1 0 1 1 | x
-------+---------+---
12 | 1 1 0 0 | 1
13 | 1 1 0 1 | x
14 | 1 1 1 0 | 1
15 | 1 1 1 1 | x
You can use the map the same way you would use the "normal" K-map to find the implicants (groups), because all K-maps indexing needs to conform to the Gray's code.
You can see the simplified boolean expression is the same in both styles of these K-maps:
f(A,B,C,D) = !A·!C + A·C + B + D = ¬A·¬C + A·C + B + D
!A·!C is marked red,
A·C blue,
B orange
and D green.
The K-maps were generated using latex's \karnaughmap command and tikz library.
it's the same in principle just the rows and columns (or the variables) are in a different order
The red labels are for when the variable is true, the blue for when it's false
It's actually the same map, but instead of A they have C and instead of B they have A and instead of C they have D and instead of D they have B
How do you represent an OR-relation in a Bayesian Network? For example, P(A | B OR C).
I also wonder how you can calculate the probability for such an expression?
Thank you in advance!
This is not particularly well-posed, because one cannot sum over the conditioned variables in a conditional distribution. However, an example may help. If we assume that B and C are binary variables and introduce a variable Z = A or B. Let's define the following joint distribution on P(A,B,C)
A B C | Z | P(A,B,C)
------+---+----------
0 0 0 | 0 | 0.02
0 0 1 | 1 | 0.22
0 1 0 | 1 | 0.06
0 1 1 | 1 | 0.08
1 0 0 | 0 | 0.18
1 0 1 | 1 | 0.24
1 1 0 | 1 | 0.17
1 1 1 | 1 | 0.03
Now, by the definition of a conditional distribution, P(A|Z) = P(A,Z)/P(Z). So, summing up terms
P(Z = 0) = 0.02 + 0.18 = 0.20
P(Z = 1) = 0.22 + 0.06 + 0.08 + 0.24 + 0.17 + 0.03 = 0.80
and P(A,Z)
A | Z | P(A, Z) | P(A | Z)
--+---+---------+---------
0 | 0 | 0.02 | 0.10
1 | 0 | 0.18 | 0.90
0 | 1 | 0.36 | 0.45
1 | 1 | 0.44 | 0.55
Notice that once we condition on Z that the two sets of terms with Z held constant both sum to 1.0.
So, in short, there isn't a generic way of calculating P(A|B or C), you need to look at the joint distribution in order to calculate the appropriate probabilities.