A DEX multi-criteria decision making methodology implementation in java programming language. It is aimed at extending the DEX methodology with numerical attributes, full hierarchies, probabilistic and fuzzy values, general aggregation functions and relational models. Project is codenamed DEXx.

The implementation is a part of PhD studies of Nejc Trdin.


DEX (Decision EXpert) is a qualitative multi-criteria decision making methodology. Its main feature is that it uses attribute scales with qualitative values, for example "bad", "medium", "good", and not numerical scales. It is preferred that scales are ordinal, but nominal scales are also supported.

Attributes in the methodology are logically connected into higher level concepts (that form a hierarchy of attributes). The lowest attributes are basic (input) attributes, which do not have any inputs. All other attributes are called aggregated attributes, this means, that they have an aggregation function. Attributes without output attributes are called root attributes - values in these attributes represent the final evaluation of an alternative.

Aggregation functions in DEX methodology are specified with decision tables, or with if-then rules. A decision maker needs to specify an output value of aggregation function, for each combination of the input attribute values.

An alternative is evaluated by filling its basic values into model input attributes. Then aggregation functions progressively compute aggregated attribute values from bottom-up. The final evaluation of the alternative are the values in the root attributes.


You can fork the repository via BitBucket, or just download the DEXx_library.jar file which includes all classes used in the library. You can also download the whole source.


If you have any suggestions for the functionality of the implementation, please send your suggestions directly to the authors.

Small example

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Map.Entry;

    import main.java.GlobalProperties;
    import main.java.Q.QAggregationFunction;
    import main.java.Q.QAlternative;
    import main.java.Q.QModel;
    import main.java.Q.QScale;
    import main.java.Q.QValue;
    import main.java.Q.QVariable;
    import main.java.Q.functions.QQualitativeToQualitativeFunction;
    import main.java.exceptions.GeneralModelException;
    public class Example {

        public static void main(String[] args) {
            QModel model = new QModel("Car evaluation");

            QVariable car, price, tech;

            //creating alternatives
            QAlternative alt = model.addEmptyAlternative("Car1");
            QAlternative alt1 = model.addEmptyAlternative("Car2");
            alt.setDescription("This is the first car!");
            alt1.setDescription("This is the second car!");

            try {
                //creating attributes and hierarchy
                car = model.createVariable("CAR");
                car.setScale(new QScale(car));
                car.setDescription("This is the main variable.");

                price = model.createVariable();
                price.setScale(new QScale(price));
                price.setDescription("This is the input attribute price.");
                model.createLink(price, car);

                tech = model.createVariableWithParent("TECH.CHAR", car);
                tech.setScale(new QScale(tech));
                tech.setDescription("This is the input attribute tech.");

                //define the function
                car.setAggregationFunction(new QQualitativeToQualitativeFunction(car));
                QQualitativeToQualitativeFunction fun = (QQualitativeToQualitativeFunction) car.getAggregationFunction();
                fun.defineValueWithValues(new QValue[]{price.getScale().getValues().get(0), tech.getScale().getValues().get(0)}, car.getScale().getValues().get(0));
                fun.defineValueWithValues(new QValue[]{price.getScale().getValues().get(0), tech.getScale().getValues().get(1)}, car.getScale().getValues().get(0));
                fun.defineValueWithValues(new QValue[]{price.getScale().getValues().get(0), tech.getScale().getValues().get(2)}, car.getScale().getValues().get(0));
                fun.defineValueWithValues(new QValue[]{price.getScale().getValues().get(0), tech.getScale().getValues().get(3)}, car.getScale().getValues().get(0));
                fun.defineValueWithValues(new QValue[]{price.getScale().getValues().get(1), tech.getScale().getValues().get(0)}, car.getScale().getValues().get(0));
                fun.defineValueWithValues(new QValue[]{price.getScale().getValues().get(1), tech.getScale().getValues().get(1)}, car.getScale().getValues().get(1));
                fun.defineValueWithValues(new QValue[]{price.getScale().getValues().get(1), tech.getScale().getValues().get(2)}, car.getScale().getValues().get(2));
                fun.defineValueWithValues(new QValue[]{price.getScale().getValues().get(1), tech.getScale().getValues().get(3)}, car.getScale().getValues().get(3));
                fun.defineValueWithValues(new QValue[]{price.getScale().getValues().get(2), tech.getScale().getValues().get(0)}, car.getScale().getValues().get(0));
                fun.defineValueWithValues(new QValue[]{price.getScale().getValues().get(2), tech.getScale().getValues().get(1)}, car.getScale().getValues().get(2));
                fun.defineValueWithValues(new QValue[]{price.getScale().getValues().get(2), tech.getScale().getValues().get(2)}, car.getScale().getValues().get(3));
                fun.defineValueWithValues(new QValue[]{price.getScale().getValues().get(2), tech.getScale().getValues().get(3)}, car.getScale().getValues().get(3));

                ArrayList<QQualitativeValue> arr = new ArrayList<QQualitativeValue>();

                QDistributionValue<QQualitativeValue> distr = new QDistributionValue<QQualitativeValue>(arr, price.getScale(),0);

                //setting alternative values
                alt.setBasicValue(price, distr);
                alt.setBasicValue(tech, 2);

                alt1.setBasicValue(price, 2);
                alt1.setBasicValue(tech, 3);

                //alternative evaluation
                HashMap<QAlternative, ArrayList<QValue>> out = model.evaluate();            
                for(Entry<QAlternative, ArrayList<QValue>> ent : out.entrySet())
                    for(QValue val: ent.getValue())
                        System.out.println(ent.getKey().getName()+": "+val);    
            } catch (GeneralModelException e) {         


For examples of relational models and other function types, please see source files located in scr/test/java


Copyright (C) 2012-2015  Nejc Trdin; Marko Bohanec

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.


DEXx is primarily developed in Java. For it to compile fully, you also require CUP and jFlex (in order to use custom aggregation functions).

While exporting models and evaluations into web-pages, the underlying Bootstrap framework is required.


  • TRDIN, Nejc, BOHANEC, Marko. Extending the multi-criteria decision making method DEX. In: PETELIN, Dejan (ed.), TAVČAR, Aleš (ed.), KALUŽA, Boštjan (ed.). 4. študentska konferenca Mednarodne podiplomske šole Jožefa Stefana = 4th Jožef Stefan International Postgraduate School Students Conference, 25. maj 2012, Ljubljana, Slovenija. Zbornik. Ljubljana: Mednarodna podiplomska šola Jožefa Stefana, 2012, pp. 182-187.
  • TRDIN, Nejc, BOHANEC, Marko. Relational multi-attribute models in DEX methodology. In: 22nd International Conference on Multiple Criteria Decision Making, 17-21 June 2013, Málaga, Spain. MCDM Málaga 2013. 2013, pp. 317. http://www.mcdm2013.decytec.ccee.uma.es/downloads/Final-Program.pdf.
  • TRDIN, Nejc, BOHANEC, Marko. New generation platform for multi-criteria decision making with method DEX. In: PHILLIPS-WREN, Gloria (ed.). DSS 2.0 - supporting decision making with new technologies : supplemental proceedings. IFIP, 2014, pp. 12.
  • TRDIN, Nejc, BOHANEC, Marko. Numerical relational multi-attribute models in qualitative multi-attribute method DEX. In: 20th Conference of the International Federation of Operational Research, Societies, 13th-15th July 2014, Barcelona, Spain. IFORS. pp. 240. http://www.ifors2014.org/files2/program-ifors2014.pdf
  • BOHANEC, Marko, TRDIN, Nejc. Qualitative multi-attribute decision method DEX : theory and practice. In: 20th Conference of the International Federation of Operational Research, Societies, 13th-15th July 2014, Barcelona, Spain. IFORS. pp. 239. http://www.ifors2014.org/files2/program-ifors2014.pdf


  • Nejc Trdin
  • Marko Bohanec


  • Vladimir Kuzmankovski