Choosing a method
Decision tables: start from the question, read off the type or method, then follow
the link to the guide page. "Why" is the one-line reason; the guide pages give the
formulas.
Which number type?
| Your information looks like |
Use |
Why |
| "about 5, between 3 and 8" |
TFN |
One most-plausible value and a left and right spread: the simplest model of a vague quantity. Supports full arithmetic (+ - * /, powers, reciprocals). |
| "roughly between 4 and 6, never below 2 or above 9" |
TrFN |
A plateau of full membership instead of a single peak. |
| An expert gives a degree of support and a degree of opposition, and the two sum to at most 1 |
IFN |
Membership \(\mu\) and non-membership \(\nu\) with \(\mu + \nu \le 1\); the rest is hesitancy. |
| Support and opposition may sum to more than 1, but their squares sum to at most 1 |
PFN |
\(\mu^2 + \nu^2 \le 1\) admits more pairs than the intuitionistic constraint, for example \((0.8, 0.5)\). |
| Even less restricted |
FFN, then QROFN |
\(\mu^3 + \nu^3 \le 1\), or any rung \(q\): the larger the rung, the larger the set of admissible pairs. |
| Three separate degrees: positive, neutral, negative (with refusal as the remainder) |
PictureFN |
Models a voting-like opinion with an abstention. |
| Support and opposition, but each only known as an interval |
IVIFN, IVPFN, IVFFN, IVQROFN |
The orthopair constraint on the upper pair with the rung of your choice, and a membership and a non-membership interval. See Interval-valued numbers. |
| Truth, indeterminacy and falsity, each only known as an interval |
IVNeutrosophicFN |
Three intervals in \([0, 1]\) with no joint constraint. Its only score is "average". |
| A linguistic term that is vague about its own shape (an upper and a lower trapezoid) |
IT2TrFN |
Interval type-2 trapezoid with a footprint of uncertainty; scored by "dtrat" by default. See Interval type-2 trapezoids. |
| Three degrees whose squares sum to at most 1 |
SphericalFN |
Membership, non-membership and hesitancy on the unit sphere. |
| Truth, indeterminacy and falsity that are independent of each other |
NeutrosophicFN |
Each part is in \([0, 1]\) with no joint constraint. |
For the orthopair family the smallest rung that admits a given pair is easy to
compute. This block runs when the site is built:
from bulanik import QROFN
for mu, nu in [(0.6, 0.3), (0.8, 0.5), (0.9, 0.5), (0.95, 0.6)]:
q = next(q for q in range(1, 50) if mu**q + nu**q <= 1)
print(f"(mu={mu}, nu={nu}) needs q >= {q}: {QROFN(mu, nu, q)}")
(mu=0.6, nu=0.3) needs q >= 1: QROFN(mu=0.6, nu=0.3, q=1)
(mu=0.8, nu=0.5) needs q >= 2: QROFN(mu=0.8, nu=0.5, q=2)
(mu=0.9, nu=0.5) needs q >= 3: QROFN(mu=0.9, nu=0.5, q=3)
(mu=0.95, nu=0.6) needs q >= 4: QROFN(mu=0.95, nu=0.6, q=4)
Rule of thumb: pick the simplest type that can hold your data. TFN for
numerical vagueness; an orthopair type when experts express support and
opposition; and choose the rung by what the elicitation allows, not by what
makes the numbers fit.
Which inference system?
| You need |
Use |
Why |
| A rule base whose consequents are fuzzy sets, readable by experts |
MamdaniFIS |
The classic: clip or scale each consequent, aggregate, defuzzify. Cost grows with resolution. |
| A crisp, fast output; control or regression; something you can tune |
SugenoFIS |
Constant or linear consequents; the output is a weighted average, no defuzzification step. |
| Outputs defined by monotonic membership functions |
TsukamotoFIS |
Each rule gives a crisp value by inverting its consequent; needs linear_increasing, linear_decreasing or sigmoid terms. |
| Membership functions you are not sure about (uncertain mean or width) |
IT2MamdaniFIS, IT2SugenoFIS |
Interval type-2 sets carry a footprint of uncertainty, and type reduction turns it into an output interval. |
| A Sugeno system learned from input-output data |
ANFIS |
Grid partition, trained by hybrid (least squares plus gradient) or gradient steps; to_sugeno exports a plain SugenoFIS. |
| To tune a Sugeno system or ANFIS with a metaheuristic |
the sezgi bridge |
ANFISProblem and train_anfis pose training as a sezgi problem. |
Which type-reduction method? (interval type-2)
| Method |
Use when |
Why |
km (default) |
You want the exact interval |
Karnik-Mendel iteration to the exact switch points. |
ekm |
You want the exact interval from the enhanced algorithm |
Enhanced KM: returns the same interval as km. |
nie_tan |
You need speed and a closed form |
\(\sum y(\underline\mu + \overline\mu)/\sum(\underline\mu + \overline\mu)\), with no iteration. |
bmm |
You want a weighted blend of the lower and upper averages |
\(m\cdot\text{avg}_{lower} + n\cdot\text{avg}_{upper}\) (default \(m = n = 0.5\)); needs some positive lower weight, else NoLowerFiringError. |
Which defuzzification? (Mamdani)
| Method |
Output |
Why |
centroid (default) |
The centre of gravity of the aggregate |
Smooth: every active rule moves the output. |
bisector |
The point that halves the area under the aggregate |
Splits the aggregate into two equal halves instead of balancing it. |
mom, som, lom |
Mean, smallest or largest of the maxima |
Pick the plateau of the winning rule; the output jumps when the winner changes. |
Which weighting method?
| You have |
Use |
Why |
| A full pairwise-comparison matrix from one decision maker |
ahp |
Principal eigenvector plus a consistency ratio to check the judgments. |
| A pairwise matrix with vague judgments (triangular numbers) |
fuzzy_ahp |
Keeps the vagueness in the weights (fuzzy_weights) as well as the crisp scores. |
| A ranking of the criteria and "how much less important is each than the one before" |
swara |
Only \(n - 1\) judgments, no matrix; crisp or fuzzy importances. |
| Data but no opinions |
entropy |
Objective: a criterion whose values differ more between alternatives gets more weight. |
| Data but no opinions, and you want conflicting criteria to count more |
critic |
Objective: weight grows with the spread of a criterion and with its negative correlation to the others. |
| Relative importances of criteria listed in any order, optionally judged again backwards |
piprecia |
Like SWARA without sorting; crisp or triangular judgements and an optional inverse pass. |
| A pairwise matrix of interval-valued orthopair judgments (IVIFN, IVPFN, IVFFN), as in the IVPF-, IVIF- and Fermatean AHP literature |
ahp_interval_valued |
Works on the interval endpoints: "multiplicative" for any rung spreads the weights widely, "possibility" for IVIFN also gives interval weights. |
| A pairwise matrix of interval-valued, orthopair, neutrosophic or interval type-2 judgments |
ahp_fuzzy_numbers |
AHP over any one number kind: aggregate the rows, score them, normalise. |
| The criteria influence each other and you want causes, effects and weights from that network |
dematel |
Total-relation matrix, prominence and relation of each factor; as_weights() gives a WeightingResult. See More weighting methods. |
| Few comparisons and a consistency check, and a solver is installed |
the best-worst method: bwm_linear (lumix), BWMProblem and FuzzyBWMProblem (sezgi) |
Two vectors of \(n - 1\) comparisons each (best against the others, the others against the worst), more consistent than a full matrix. The linear model is an LP; the nonlinear and the fuzzy model are searched with sezgi. |
The consistency_ratio of a BWM result is not the same quantity in every
bridge; see the warning on sezgi before comparing them.
Which ranking method?
| Situation |
Use |
Why |
| Crisp scores; a general-purpose default |
topsis |
Closeness to the ideal and distance from the anti-ideal; compensatory and intuitive. |
| You want a compromise solution and to see group utility against individual regret |
vikor |
Ranks by \(Q\) built from the weighted sum \(S\) and the worst single criterion \(R\) (v balances them). Lower is better. |
| You want the weighted-sum and the weighted-product models combined |
waspas |
Blends the two with the weight lam; entries must be positive. |
| Criteria where distance from the average solution is meaningful |
edas |
Positive and negative distances from the average; the average of each criterion must be positive. |
| A distance-based score from the negative-ideal point |
codas |
Euclidean and taxicab distances; psi chooses between the paper's equation and its tables. |
| Shares of benefit and cost sums, as a percentage utility |
copras |
Proportional assessment; the utility degree is relative to the best. |
| Utility relative to both an ideal and an anti-ideal alternative |
marcos |
Entries must be strictly positive. |
Three compromise scores combined; a parameter lam for sum against power |
cocoso |
Fails, with a clear error, if one alternative is worst on every criterion. |
| Both weighted sums and weighted products, with benefit and cost measured against each other |
wisp |
Four measures averaged; entries must be strictly positive. |
| Pairwise dominance, not a single score (outranking) |
electre |
Concordance and discordance between pairs; extras["outranks"] is the partial relation, ranking comes from the net indices. See More ranking methods. |
| Triangular fuzzy ratings and weights, with fuzziness kept to the end |
fuzzy_topsis |
Chen's (2000) TOPSIS on triangular numbers: normalise, weight, compare to fixed fuzzy ideals by vertex distance. |
| Several experts, any number type |
rank_fuzzy with a DecisionMatrix |
Aggregates the experts (wa or wg, any operator family), scores each fuzzy number, then ranks with any of ten methods (topsis, vikor, waspas, edas, codas, copras, marcos, cocoso, wisp, electre). |
| CODAS on orthopair or neutrosophic ratings, with distances taken between the numbers |
fuzzy_codas |
Score-last: distances of the weighted numbers from the negative-ideal numbers; a cost criterion uses complement(). |
| WASPAS with the weighted sum and product kept as fuzzy numbers |
fuzzy_waspas |
Score-last; combine="fuzzy" mixes the numbers and scores once, combine="scores" scores first. |
| CoCoSo with the weighted sum and product kept as fuzzy numbers |
fuzzy_cocoso |
Score-last sums and products, then CoCoSo's appraisal scores; "normalized" score by default. |
Different methods may disagree; that is information about how robust the ranking is,
not a bug. When it matters, rank with two methods and compare.
from bulanik.mcdm import edas, topsis, vikor, waspas
data = [[250, 16, 12], [200, 16, 8], [300, 32, 16], [275, 32, 8]] # price, memory, camera
weights, types = [0.4, 0.35, 0.25], ["cost", "benefit", "benefit"]
names = ["P1", "P2", "P3", "P4"]
for method in (topsis, vikor, waspas, edas):
result = method(data, weights, types, alternatives=names)
print(f"{method.__name__:7s}", result.ranking)
topsis ('P3', 'P4', 'P2', 'P1')
vikor ('P4', 'P3', 'P2', 'P1')
waspas ('P3', 'P4', 'P2', 'P1')
edas ('P3', 'P4', 'P1', 'P2')