Пример #1
0
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'performanceTable.xml',
        'categoriesProfiles.xml',
        'criteria.xml',
        'profilesPerformanceTable.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    criteria = px.getCriteriaID(trees['criteria'])
    pref_directions = px.getCriteriaPreferenceDirections(
        trees['criteria'], criteria)
    thresholds = px.getConstantThresholds(trees['criteria'], criteria)
    performances = px.getPerformanceTable(trees['performanceTable'], None,
                                          None)
    profiles_performance_table = px.getPerformanceTable(
        trees['profilesPerformanceTable'], None, None)
    cp_tree = trees['categoriesProfiles']
    # we need only categories profiles' names
    categories_profiles = [
        p for p in cp_tree.xpath('//categoriesProfiles//alternativeID/text()')
    ]

    ret = {
        'alternatives': alternatives,
        'categories_profiles': categories_profiles,
        'criteria': criteria,
        'performances': performances,
        'pref_directions': pref_directions,
        'profiles_performance_table': profiles_performance_table,
        'thresholds': thresholds,
    }
    return ret
Пример #2
0
def parse_xmcda_files(in_weights, in_hierarchy, in_concorlevel, in_criteria, in_alternatives, in_performances):
    xml_crit = px.parseValidate(in_criteria)
    xml_alt = px.parseValidate(in_alternatives)
    xml_pt = px.parseValidate(in_performances)
    xml_weight = px.parseValidate(in_weights)
    xml_hierarchy = px.parseValidate(in_hierarchy)
    xml_concordance = px.parseValidate(in_concorlevel)
    if xml_crit == None:
        raise ValueError, ["Invalid criteria file"]
    if xml_alt == None:
        raise ValueError, ["Invalid alternative file"]
    if xml_pt == None:
        raise ValueError, ["Invalid performance table file"]
    if xml_weight == None:
        raise ValueError, ["Invalid weight file"]
    if xml_hierarchy == None:
        raise ValueError, ["Invalid assignment file"]
    if xml_concordance == None:
        raise ValueError, ["Invalid concordance file"]

    try:
        alternatives_ids = px.getAlternativesID(xml_alt)
        criteria_ids = px.getCriteriaID(xml_crit)
        performance_table = px.getPerformanceTable(xml_pt, alternatives_ids, criteria_ids)
        criteriaWeight = px.getCriterionValue(xml_weight, criteria_ids, 'Importance')
        preferenceDirections = px.getCriteriaPreferenceDirections(xml_crit, criteria_ids)
        hierarchyArray = get_hierarchy_array(xml_hierarchy)
        criteria_thresholds = px.getConstantThresholds(xml_crit, criteria_ids)
        concordanceCutLev = get_criterion_concordance_cutting_level_value(xml_concordance, 'Concordance')
    except:
        raise ValueError, ["Failed to parse one or more file"]
        return

    return alternatives_ids, criteria_ids, performance_table, criteriaWeight, preferenceDirections, hierarchyArray, criteria_thresholds, concordanceCutLev
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'method_parameters.xml',
        'outranking.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    alternatives.sort()
    outranking = get_intersection_distillation(trees['outranking'],
                                               alternatives)
    if outranking == None:
        outranking = px.getAlternativesComparisons(trees['outranking'],
                                                   alternatives)
    eliminate_cycles_method = px.getParameterByName(trees['method_parameters'],
                                                    'eliminate_cycles_method')
    if eliminate_cycles_method not in ['aggregate', 'cut_weakest']:
        raise RuntimeError("Invalid/missing method for cycle elimination.")
    cut_threshold = px.getParameterByName(trees['method_parameters'],
                                          'cut_threshold')
    check_cut_threshold(cut_threshold)

    ret = {
        'alternatives': alternatives,
        'cut_threshold': cut_threshold,
        'eliminate_cycles_method': eliminate_cycles_method,
        'outranking': outranking,
    }
    return ret
Пример #4
0
 def get_credibility(*args, **kwargs):
     alternatives = px.getAlternativesID(trees['alternatives'])
     comparison_with = kwargs.get('comparison_with')
     if not comparison_with:
         comparison_with = px.getParameterByName(
             trees['method_parameters'],
             'comparison_with',
         )
     if comparison_with in ('boundary_profiles', 'central_profiles'):
         categories_profiles = _get_categories_profiles(
             trees['categories_profiles'],
             comparison_with,
         )
     else:
         categories_profiles = None
     eliminate_cycles_method = px.getParameterByName(
         trees.get('method_parameters'),
         'eliminate_cycles_method',
     )
     tree = trees.get('credibility')
     if eliminate_cycles_method == 'cut_weakest' and tree is None:
         raise InputDataError(
             "'cut_weakest' option requires credibility as an additional "
             "input (apart from outranking)."
         )
     credibility = _get_alternatives_comparisons(
         tree,
         alternatives,
         categories_profiles=categories_profiles,
     )
     return credibility  # NoneType, Vividict
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'categoriesProfiles.xml',
        'credibility.xml',
        'method_parameters.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    cp_tree = trees['categoriesProfiles']
    categories = list(
        set(cp_tree.xpath('//categoriesProfiles//limits//categoryID/text()')))
    categories_profiles = px.getCategoriesProfiles(trees['categoriesProfiles'],
                                                   categories)
    profiles_names = [
        p for p in cp_tree.xpath('//categoriesProfiles//alternativeID/text()')
    ]
    credibility = getAlternativesComparisons(trees['credibility'],
                                             alternatives, profiles_names)
    cut_threshold = px.getParameterByName(trees['method_parameters'],
                                          'cut_threshold')
    check_cut_threshold(cut_threshold)

    ret = {
        'alternatives': alternatives,
        'categories_profiles': categories_profiles,
        'credibility': credibility,
        'cut_threshold': cut_threshold,
    }
    return ret
Пример #6
0
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'categoriesProfiles.xml',
        'concordance.xml',
        'discordances.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    categories_profiles = get_categories_profiles_central(
        trees['categoriesProfiles'])
    concordance = getAlternativesComparisons(trees['concordance'],
                                             alternatives, categories_profiles)
    discordances = getAlternativesComparisons(trees['discordances'],
                                              alternatives,
                                              categories_profiles,
                                              partials=True)

    ret = {
        'alternatives': alternatives,
        'categories_profiles': categories_profiles,
        'concordance': concordance,
        'discordances': discordances,
    }
    return ret
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'categories.xml',
        'categoriesProfiles.xml',
        'credibility.xml',
        'method_parameters.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    categories = px.getCategoriesID(trees['categories'])
    categories_rank = px.getCategoriesRank(trees['categories'], categories)
    categories_profiles = get_categories_profiles_central(trees['categoriesProfiles'])
    credibility = getAlternativesComparisons(trees['credibility'], alternatives,
                                             categories_profiles)
    cut_threshold = px.getParameterByName(trees['method_parameters'], 'cut_threshold')
    check_cut_threshold(cut_threshold)

    ret = {
        'alternatives': alternatives,
        'categories_rank': categories_rank,
        'categories_profiles': categories_profiles,
        'credibility': credibility,
        'cut_threshold': cut_threshold,
    }
    return ret
Пример #8
0
def makeDistilation(in_selected, in_alternatives, in_credibility,
                    out_descending, out_ascending, out_medianPreorder,
                    out_final):
    xml_alternatives = px.parseValidate(in_alternatives)
    xml_selected = px.parseValidate(in_selected)
    xml_alternatives = px.parseValidate(in_alternatives)
    xml_credibility = px.parseValidate(in_credibility)
    if xml_selected == None:
        raise ValueError, "Invalid selected file"
    if xml_alternatives == None:
        raise ValueError, "Invalid alternative file"
    if xml_credibility == None:
        raise ValueError, "Invalid credibility file"

    onCriterion = px.getParameterByName(xml_selected, 'selectedCriterion')
    alternativesID = px.getAlternativesID(xml_alternatives)
    alternativesComparisions = getAlternativesComparisonsAtCriteria(
        xml_credibility, alternativesID)

    if not alternativesComparisions.has_key(onCriterion):
        raise ValueError, 'Invalid selected criterion'

    distillation = Distillation(alternativesID,
                                alternativesComparisions[onCriterion])

    output_distillation(out_ascending, distillation.downwards(),
                        'downward distillation', onCriterion)
    output_distillation(out_descending, distillation.upwards(),
                        'upward distillation', onCriterion)
    output_distillation(out_medianPreorder, distillation.medianPreorder(),
                        'median Preorder', onCriterion)

    writeAlternativeComparision(out_final, distillation.intersectionUpDowns,
                                'outranks', onCriterion)
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'criteria.xml',
        'interactions.xml',
        'method_parameters.xml',
        'performance_table.xml',
        'weights.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    criteria = px.getCriteriaID(trees['criteria'])
    pref_directions = px.getCriteriaPreferenceDirections(trees['criteria'], criteria)
    thresholds = px.getConstantThresholds(trees['criteria'], criteria)
    weights = px.getCriterionValue(trees['weights'], criteria)
    performances = px.getPerformanceTable(trees['performance_table'], 1, 1)
    interactions = get_criteria_interactions(trees['interactions'], criteria)

    check_net_balance(interactions, weights)
    z_function = px.getParameterByName(trees['method_parameters'], 'z_function')

    ret = {
        'alternatives': alternatives,
        'criteria': criteria,
        'interactions': interactions,
        'performances': performances,
        'pref_directions': pref_directions,
        'thresholds': thresholds,
        'weights': weights,
        'z_function': z_function,
    }
    return ret
Пример #10
0
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'method_parameters.xml',
        'outranking.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    alternatives.sort()
    outranking = get_intersection_distillation(trees['outranking'], alternatives)
    if outranking == None:
        outranking = px.getAlternativesComparisons(trees['outranking'], alternatives)
    eliminate_cycles_method = px.getParameterByName(trees['method_parameters'],
                                                    'eliminate_cycles_method')
    if eliminate_cycles_method not in ['aggregate', 'cut_weakest']:
        raise RuntimeError("Invalid/missing method for cycle elimination.")
    cut_threshold = px.getParameterByName(trees['method_parameters'], 'cut_threshold')
    check_cut_threshold(cut_threshold)

    ret = {
        'alternatives': alternatives,
        'cut_threshold': cut_threshold,
        'eliminate_cycles_method': eliminate_cycles_method,
        'outranking': outranking,
    }
    return ret
Пример #11
0
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'criteria.xml',
        'interactions.xml',
        'method_parameters.xml',
        'performance_table.xml',
        'weights.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    criteria = px.getCriteriaID(trees['criteria'])
    pref_directions = px.getCriteriaPreferenceDirections(
        trees['criteria'], criteria)
    thresholds = px.getConstantThresholds(trees['criteria'], criteria)
    weights = px.getCriterionValue(trees['weights'], criteria)
    performances = px.getPerformanceTable(trees['performance_table'], 1, 1)
    interactions = get_criteria_interactions(trees['interactions'], criteria)

    check_net_balance(interactions, weights)
    z_function = px.getParameterByName(trees['method_parameters'],
                                       'z_function')

    ret = {
        'alternatives': alternatives,
        'criteria': criteria,
        'interactions': interactions,
        'performances': performances,
        'pref_directions': pref_directions,
        'thresholds': thresholds,
        'weights': weights,
        'z_function': z_function,
    }
    return ret
Пример #12
0
 def get_discordance(*args, **kwargs):
     alternatives = px.getAlternativesID(trees['alternatives'])
     comparison_with = px.getParameterByName(
         trees['method_parameters'],
         'comparison_with',
     )
     if kwargs.get('use_partials') is not None:
         use_partials = kwargs.get('use_partials')
     else:
         parameter = px.getParameterByName(
             trees['method_parameters'],
             'use_partials',
         )
         use_partials = True if parameter == 'true' else False
     if comparison_with in ('boundary_profiles', 'central_profiles'):
         categories_profiles = _get_categories_profiles(
             trees['categories_profiles'],
             comparison_with,
         )
     else:
         categories_profiles = None
     discordance = _get_alternatives_comparisons(
         trees['discordance'],
         alternatives,
         categories_profiles=categories_profiles,
         use_partials=use_partials,
     )
     return discordance  # Vividict
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'concordance.xml',
        'method_parameters.xml',
        'discordance_binary.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    # we can also get alternatives from 'concordance.xml', therefore 'alternatives.xml'
    # can be optional - like here:
    # alternatives = list(set([i.text for i in trees['concordance'].findall(".//alternativeID")]))
    concordance = px.getAlternativesComparisons(trees['concordance'],
                                                alternatives)
    discordance_binary = px.getAlternativesComparisons(
        trees['discordance_binary'], alternatives)
    cut_threshold = px.getParameterByName(trees['method_parameters'],
                                          'cut_threshold')
    check_cut_threshold(cut_threshold)

    ret = {
        'alternatives': alternatives,
        'concordance': concordance,
        'cut_threshold': cut_threshold,
        'discordance_binary': discordance_binary,
    }
    return ret
Пример #14
0
 def get_credibility(*args, **kwargs):
     alternatives = px.getAlternativesID(trees['alternatives'])
     comparison_with = kwargs.get('comparison_with')
     if not comparison_with:
         comparison_with = px.getParameterByName(
             trees['method_parameters'],
             'comparison_with',
         )
     if comparison_with in ('boundary_profiles', 'central_profiles'):
         categories_profiles = _get_categories_profiles(
             trees['categories_profiles'],
             comparison_with,
         )
     else:
         categories_profiles = None
     eliminate_cycles_method = px.getParameterByName(
         trees.get('method_parameters'),
         'eliminate_cycles_method',
     )
     tree = trees.get('credibility')
     if eliminate_cycles_method == 'cut_weakest' and tree is None:
         raise InputDataError(
             "'cut_weakest' option requires credibility as an additional "
             "input (apart from outranking)."
         )
     credibility = _get_alternatives_comparisons(
         tree,
         alternatives,
         categories_profiles=categories_profiles,
     )
     return credibility  # NoneType, Vividict
Пример #15
0
 def get_discordance(*args, **kwargs):
     alternatives = px.getAlternativesID(trees['alternatives'])
     comparison_with = px.getParameterByName(
         trees['method_parameters'],
         'comparison_with',
     )
     if kwargs.get('use_partials') is not None:
         use_partials = kwargs.get('use_partials')
     else:
         parameter = px.getParameterByName(
             trees['method_parameters'],
             'use_partials',
         )
         use_partials = True if parameter == 'true' else False
     if comparison_with in ('boundary_profiles', 'central_profiles'):
         categories_profiles = _get_categories_profiles(
             trees['categories_profiles'],
             comparison_with,
         )
     else:
         categories_profiles = None
     discordance = _get_alternatives_comparisons(
         trees['discordance'],
         alternatives,
         categories_profiles=categories_profiles,
         use_partials=use_partials,
     )
     return discordance  # Vividict
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'performanceTable.xml',
        'categoriesProfiles.xml',
        'criteria.xml',
        'profilesPerformanceTable.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    criteria = px.getCriteriaID(trees['criteria'])
    pref_directions = px.getCriteriaPreferenceDirections(trees['criteria'], criteria)
    thresholds = px.getConstantThresholds(trees['criteria'], criteria)
    performances = px.getPerformanceTable(trees['performanceTable'], None, None)
    profiles_performance_table = px.getPerformanceTable(trees['profilesPerformanceTable'], None, None)
    cp_tree = trees['categoriesProfiles']
    # we need only categories profiles' names
    categories_profiles = [p for p in cp_tree.xpath('//categoriesProfiles//alternativeID/text()')]

    ret = {
        'alternatives': alternatives,
        'categories_profiles': categories_profiles,
        'criteria': criteria,
        'performances': performances,
        'pref_directions': pref_directions,
        'profiles_performance_table': profiles_performance_table,
        'thresholds': thresholds,
    }
    return ret
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'categoriesProfiles.xml',
        'criteria.xml',
        'performanceTable.xml',
        'profilesPerformanceTable.xml',
        'weights.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    criteria = px.getCriteriaID(trees['criteria'])
    pref_directions = px.getCriteriaPreferenceDirections(trees['criteria'], criteria)
    thresholds = px.getConstantThresholds(trees['criteria'], criteria)
    weights = px.getCriterionValue(trees['weights'], criteria)
    performances = px.getPerformanceTable(trees['performanceTable'], None, None)
    categories_profiles = get_categories_profiles_central(trees['categoriesProfiles'])
    profiles_performance_table = px.getPerformanceTable(trees['profilesPerformanceTable'],
                                                        None, None)

    ret = {
        'alternatives': alternatives,
        'categories_profiles': categories_profiles,
        'criteria': criteria,
        'performances': performances,
        'pref_directions': pref_directions,
        'profiles_performance_table': profiles_performance_table,
        'thresholds': thresholds,
        'weights': weights,
    }
    return ret
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'categoriesProfiles.xml',
        'concordance.xml',
        'discordances.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    cp_tree = trees['categoriesProfiles']
    # we need only categories profiles' names
    categories_profiles = [
        p for p in cp_tree.xpath('//categoriesProfiles//alternativeID/text()')
    ]
    concordance = getAlternativesComparisons(trees['concordance'],
                                             alternatives, categories_profiles)
    discordances = getAlternativesComparisons(trees['discordances'],
                                              alternatives,
                                              categories_profiles,
                                              partials=True)

    ret = {
        'alternatives': alternatives,
        'categories_profiles': categories_profiles,
        'concordance': concordance,
        'discordances': discordances,
    }
    return ret
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'categoriesProfiles.xml',
        'criteria.xml',
        'performanceTable.xml',
        'profilesPerformanceTable.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    criteria = px.getCriteriaID(trees['criteria'])
    pref_directions = px.getCriteriaPreferenceDirections(trees['criteria'], criteria)
    thresholds = px.getConstantThresholds(trees['criteria'], criteria)
    performances = px.getPerformanceTable(trees['performanceTable'], None, None)
    categories_profiles = get_categories_profiles_central(trees['categoriesProfiles'])
    profiles_performance_table = px.getPerformanceTable(
        trees['profilesPerformanceTable'], None, None
    )

    ret = {
        'alternatives': alternatives,
        'categories_profiles': categories_profiles,
        'criteria': criteria,
        'performances': performances,
        'pref_directions': pref_directions,
        'profiles_performance_table': profiles_performance_table,
        'thresholds': thresholds,
    }
    return ret
Пример #20
0
def makeDistilation(
    in_selected, in_alternatives, in_credibility, out_descending, out_ascending, out_medianPreorder, out_final
):
    xml_alternatives = px.parseValidate(in_alternatives)
    xml_selected = px.parseValidate(in_selected)
    xml_alternatives = px.parseValidate(in_alternatives)
    xml_credibility = px.parseValidate(in_credibility)
    if xml_selected == None:
        raise ValueError, "Invalid selected file"
    if xml_alternatives == None:
        raise ValueError, "Invalid alternative file"
    if xml_credibility == None:
        raise ValueError, "Invalid credibility file"

    onCriterion = px.getParameterByName(xml_selected, "selectedCriterion")
    alternativesID = px.getAlternativesID(xml_alternatives)
    alternativesComparisions = getAlternativesComparisonsAtCriteria(xml_credibility, alternativesID)

    if not alternativesComparisions.has_key(onCriterion):
        raise ValueError, "Invalid selected criterion"

    distillation = Distillation(alternativesID, alternativesComparisions[onCriterion])

    output_distillation(out_ascending, distillation.downwards(), "downward distillation", onCriterion)
    output_distillation(out_descending, distillation.upwards(), "upward distillation", onCriterion)
    output_distillation(out_medianPreorder, distillation.medianPreorder(), "median Preorder", onCriterion)

    writeAlternativeComparision(out_final, distillation.intersectionUpDowns, "outranks", onCriterion)
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'concordance.xml',
        'method_parameters.xml',
        'discordance_binary.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    # we can also get alternatives from 'concordance.xml', therefore 'alternatives.xml'
    # can be optional - like here:
    # alternatives = list(set([i.text for i in trees['concordance'].findall(".//alternativeID")]))
    concordance = px.getAlternativesComparisons(trees['concordance'], alternatives)
    discordance_binary = px.getAlternativesComparisons(trees['discordance_binary'], alternatives)
    cut_threshold = px.getParameterByName(trees['method_parameters'], 'cut_threshold')
    check_cut_threshold(cut_threshold)

    ret = {
        'alternatives': alternatives,
        'concordance': concordance,
        'cut_threshold': cut_threshold,
        'discordance_binary': discordance_binary,
    }
    return ret
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'performanceTable.xml',
        'categoriesProfiles.xml',
        'criteria.xml',
        'profilesPerformanceTable.xml',
        'weights.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    criteria = px.getCriteriaID(trees['criteria'])
    pref_directions = px.getCriteriaPreferenceDirections(
        trees['criteria'], criteria)
    thresholds = px.getConstantThresholds(trees['criteria'], criteria)
    weights = px.getCriterionValue(trees['weights'], criteria)
    performances = px.getPerformanceTable(trees['performanceTable'], 1, 1)

    # we can't assume that categories will be always available as a separate
    # input file, therefore it's better to extract them from categoriesProfiles
    cp_tree = trees['categoriesProfiles']
    categories = list(
        set(cp_tree.xpath('//categoriesProfiles//limits//categoryID/text()')))
    # since we just need names of categories profiles, it's better to get them like below
    # - otherwise, to get 'full' categories profiles, we should use this:
    # categories_profiles = px.getCategoriesProfiles(trees['categoriesProfiles'], categories)
    categories_profiles = [
        p for p in cp_tree.xpath('//categoriesProfiles//alternativeID/text()')
    ]
    # last two args to getPerformanceTable are not used at all anyway...
    profiles_performance_table = px.getPerformanceTable(
        trees['profilesPerformanceTable'], None, None)

    ret = {
        'alternatives': alternatives,
        'categories_profiles': categories_profiles,
        'criteria': criteria,
        'performances': performances,
        'pref_directions': pref_directions,
        'profiles_performance_table': profiles_performance_table,
        'thresholds': thresholds,
        'weights': weights,
    }
    return ret
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'performanceTable.xml',
        'categoriesProfiles.xml',
        'criteria.xml',
        'profilesPerformanceTable.xml',
        'weights.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    criteria = px.getCriteriaID(trees['criteria'])
    pref_directions = px.getCriteriaPreferenceDirections(trees['criteria'], criteria)
    thresholds = px.getConstantThresholds(trees['criteria'], criteria)
    weights = px.getCriterionValue(trees['weights'], criteria)
    performances = px.getPerformanceTable(trees['performanceTable'], 1, 1)

    # we can't assume that categories will be always available as a separate
    # input file, therefore it's better to extract them from categoriesProfiles
    cp_tree = trees['categoriesProfiles']
    categories = list(set(cp_tree.xpath('//categoriesProfiles//limits//categoryID/text()')))
    # since we just need names of categories profiles, it's better to get them like below
    # - otherwise, to get 'full' categories profiles, we should use this:
    # categories_profiles = px.getCategoriesProfiles(trees['categoriesProfiles'], categories)
    categories_profiles = [p for p in cp_tree.xpath('//categoriesProfiles//alternativeID/text()')]
    # last two args to getPerformanceTable are not used at all anyway...
    profiles_performance_table = px.getPerformanceTable(trees['profilesPerformanceTable'], None, None)

    ret = {
        'alternatives': alternatives,
        'categories_profiles': categories_profiles,
        'criteria': criteria,
        'performances': performances,
        'pref_directions': pref_directions,
        'profiles_performance_table': profiles_performance_table,
        'thresholds': thresholds,
        'weights': weights,
    }
    return ret
Пример #24
0
 def get_cv_crossed(*args, **kwargs):
     # 'cv_crossed' stands for 'counter-veto crossed'
     alternatives = px.getAlternativesID(trees['alternatives'])
     comparison_with = px.getParameterByName(
         trees['method_parameters'],
         'comparison_with',
     )
     if comparison_with in ('boundary_profiles', 'central_profiles'):
         categories_profiles = _get_categories_profiles(
             trees['categories_profiles'],
             comparison_with,
         )
     else:
         categories_profiles = None
     cv_crossed = _get_alternatives_comparisons(
         trees['counter_veto_crossed'],
         alternatives,
         categories_profiles=categories_profiles,
         use_partials=True,
         mcda_concept='counterVetoCrossed',
     )
     return cv_crossed  # Vividict
Пример #25
0
 def get_concordance(*args, **kwargs):
     alternatives = px.getAlternativesID(trees['alternatives'])
     comparison_with = px.getParameterByName(
         trees['method_parameters'],
         'comparison_with',
     )
     if comparison_with in ('boundary_profiles', 'central_profiles'):
         categories_profiles = _get_categories_profiles(
             trees['categories_profiles'],
             comparison_with,
         )
         concordance = _get_alternatives_comparisons(
             trees['concordance'],
             alternatives,
             categories_profiles,
         )
     else:
         concordance = px.getAlternativesComparisons(
             trees['concordance'],
             alternatives,
         )
     return concordance  # Vividict, dict
Пример #26
0
 def get_cv_crossed(*args, **kwargs):
     # 'cv_crossed' stands for 'counter-veto crossed'
     alternatives = px.getAlternativesID(trees['alternatives'])
     comparison_with = px.getParameterByName(
         trees['method_parameters'],
         'comparison_with',
     )
     if comparison_with in ('boundary_profiles', 'central_profiles'):
         categories_profiles = _get_categories_profiles(
             trees['categories_profiles'],
             comparison_with,
         )
     else:
         categories_profiles = None
     cv_crossed = _get_alternatives_comparisons(
         trees['counter_veto_crossed'],
         alternatives,
         categories_profiles=categories_profiles,
         use_partials=True,
         mcda_concept='counterVetoCrossed',
     )
     return cv_crossed  # Vividict
Пример #27
0
 def get_concordance(*args, **kwargs):
     alternatives = px.getAlternativesID(trees['alternatives'])
     comparison_with = px.getParameterByName(
         trees['method_parameters'],
         'comparison_with',
     )
     if comparison_with in ('boundary_profiles', 'central_profiles'):
         categories_profiles = _get_categories_profiles(
             trees['categories_profiles'],
             comparison_with,
         )
         concordance = _get_alternatives_comparisons(
             trees['concordance'],
             alternatives,
             categories_profiles,
         )
     else:
         concordance = px.getAlternativesComparisons(
             trees['concordance'],
             alternatives,
         )
     return concordance  # Vividict, dict
Пример #28
0
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'criteria.xml',
        'performanceTable.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    criteria = px.getCriteriaID(trees['criteria'])
    pref_directions = px.getCriteriaPreferenceDirections(trees['criteria'], criteria)
    thresholds = px.getConstantThresholds(trees['criteria'], criteria)
    performances = px.getPerformanceTable(trees['performanceTable'], None, None)

    ret = {
        'alternatives': alternatives,
        'criteria': criteria,
        'performances': performances,
        'pref_directions': pref_directions,
        'thresholds': thresholds,
    }
    return ret
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'categoriesProfiles.xml',
        'concordance.xml',
        'discordances.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    cp_tree = trees['categoriesProfiles']
    # we need only categories profiles' names
    categories_profiles = [p for p in cp_tree.xpath('//categoriesProfiles//alternativeID/text()')]
    concordance = getAlternativesComparisons(trees['concordance'], alternatives, categories_profiles)
    discordances = getAlternativesComparisons(trees['discordances'], alternatives, categories_profiles, partials=True)

    ret = {
        'alternatives': alternatives,
        'categories_profiles': categories_profiles,
        'concordance': concordance,
        'discordances': discordances,
    }
    return ret
def get_input_data(input_dir):
    file_names = (
        'alternatives.xml',
        'categoriesProfiles.xml',
        'concordance.xml',
        'discordances.xml',
    )
    trees = get_trees(input_dir, file_names)

    alternatives = px.getAlternativesID(trees['alternatives'])
    categories_profiles = get_categories_profiles_central(trees['categoriesProfiles'])
    concordance = getAlternativesComparisons(trees['concordance'], alternatives,
                                             categories_profiles)
    discordances = getAlternativesComparisons(trees['discordances'], alternatives,
                                              categories_profiles, partials=True)

    ret = {
        'alternatives': alternatives,
        'categories_profiles': categories_profiles,
        'concordance': concordance,
        'discordances': discordances,
    }
    return ret
Пример #31
0
def parse_xmcda_files(in_dir):
    xml_crit = PyXMCDA.parseValidate(in_dir+"/criteria.xml")
    xml_alt = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
    xml_pt = PyXMCDA.parseValidate(in_dir+"/perfs_table.xml")
    xml_assign = PyXMCDA.parseValidate(in_dir+"/assign.xml")
    xml_cat = PyXMCDA.parseValidate(in_dir+"/categories.xml")

    if xml_crit == None:
        error_list.append("Invalid criteria file")
        return
    if xml_alt == None:
        error_list.append("Invalid alternative file")
        return
    if xml_pt == None:
        error_list.append("Invalid performance table file")
        return
    if xml_assign == None:
        error_list.append("Invalid assignment file")
        return
    if xml_cat == None:
        error_list.append("Invalid categories file")
        return

    try:
        alt_id = PyXMCDA.getAlternativesID(xml_alt)
        crit_id = PyXMCDA.getCriteriaID(xml_crit)
        pt = PyXMCDA.getPerformanceTable(xml_pt, alt_id, crit_id)
        cat_id = PyXMCDA.getCategoriesID(xml_cat)
        cat_rank = PyXMCDA.getCategoriesRank(xml_cat, cat_id)
        assign = PyXMCDA.getAlternativesAffectations(xml_assign)
        pref_dir = PyXMCDA.getCriteriaPreferenceDirections(xml_crit, crit_id)
    except:
        error_list.append("Failed to parse one or more file")
        return

    return (alt_id, crit_id, pt, cat_id, cat_rank, assign, pref_dir)
Пример #32
0
def main(argv=None):
    
    if argv is None:
        argv = sys.argv
        
    parser = OptionParser()

    parser.add_option("-i", "--in", dest="in_dir")
    parser.add_option("-o", "--out", dest="out_dir")

    (options, args) = parser.parse_args(argv[1:])

    in_dir = options.in_dir
    out_dir = options.out_dir

    # Creating a list for error messages
    errorList = []

    if not os.path.isfile (in_dir+"/alternatives.xml"):
        errorList.append("alternatives.xml is missing")
    if not os.path.isfile (in_dir+"/relation.xml"):
        errorList.append("relation.xml is missing")
    if not os.path.isfile (in_dir+"/parameters.xml"):
        errorList.append("parameters.xml is missing")

    if not errorList:
        # We parse all the mandatory input files
        xmltree_alternatives = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
        xmltree_relation = PyXMCDA.parseValidate(in_dir+"/relation.xml")
        xmltree_parameters = PyXMCDA.parseValidate(in_dir+"/parameters.xml")
        
        # We check if all madatory input files are valid
        if xmltree_alternatives == None :
            errorList.append("alternatives.xml can't be validated.")
        if xmltree_relation == None :
            errorList.append("relation.xml can't be validated.")
        if xmltree_parameters == None :
            errorList.append("parameters.xml can't be validated.")
            
        if not errorList :

            alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
            alternativesRel = PyXMCDA.getAlternativesComparisons (xmltree_relation, alternativesId)
            relationMin = PyXMCDA.getParameterByName (xmltree_parameters, "min")
            relationMax = PyXMCDA.getParameterByName (xmltree_parameters, "max")
            relationCut = PyXMCDA.getParameterByName (xmltree_parameters, "cut")
            relationBipolar = PyXMCDA.getParameterByName (xmltree_parameters, "bipolar")

            if not alternativesId :
                errorList.append("No active alternatives found.")
            if not alternativesRel :
                errorList.append("Problems between relation and alternatives.")
            if relationMin is None:
                errorList.append("No \'min\' method parameter found")
            if relationMax is None:
                errorList.append("No \'max\' method parameter found")
            if relationCut is None:
                errorList.append("No \'cut\' method parameter found")
            if relationBipolar is None:
                errorList.append("No \'bipolar\' method parameter found")

        if not errorList :
            
            alg = algMccP(alternativesId, alternativesRel, relationMin, relationMax, relationCut, relationBipolar)
            results = alg.Run()
            
            fo = open(out_dir+"/output.xml",'w')
            PyXMCDA.writeHeader(fo)
            fo.write('<alternativesAffectations>\n')
            for o in results:
                fo.write('\t<alternativeAffectation>\n\t\t<alternativeID>'+o+'</alternativeID>\n\t\t\t<categoryID>'+results[o]+'</categoryID>\n\t</alternativeAffectation>\n')
            fo.write('</alternativesAffectations>')
            PyXMCDA.writeFooter(fo)
            fo.close()
            
        # Creating log and error file, messages.xml
        fileMessages = open(out_dir+"/messages.xml", 'w')
        PyXMCDA.writeHeader (fileMessages)

        if not errorList :
            PyXMCDA.writeLogMessages (fileMessages, ["Execution ok"])
        else :
            PyXMCDA.writeErrorMessages (fileMessages, errorList)

        PyXMCDA.writeFooter(fileMessages)
        fileMessages.close()
Пример #33
0
def main(argv=None):
    if argv is None:
        argv = sys.argv

    parser = OptionParser()

    parser.add_option("-i", "--in", dest="in_dir")
    parser.add_option("-o", "--out", dest="out_dir")

    (options, args) = parser.parse_args(argv[1:])

    in_dir = options.in_dir
    out_dir = options.out_dir

    # Creating a list for error messages
    errorList = []

    # If some mandatory input files are missing
    if (
        not os.path.isfile(in_dir + "/alternatives.xml")
        or not os.path.isfile(in_dir + "/criteria.xml")
        or not os.path.isfile(in_dir + "/criteriaWeights.xml")
        or not os.path.isfile(in_dir + "/performanceTable.xml")
    ):
        errorList.append("Some input files are missing")

    else:

        # We parse all the mandatory input files
        xmltree_alternatives = PyXMCDA.parseValidate(in_dir + "/alternatives.xml")
        xmltree_criteria = PyXMCDA.parseValidate(in_dir + "/criteria.xml")
        xmltree_weights = PyXMCDA.parseValidate(in_dir + "/criteriaWeights.xml")
        xmltree_perfTable = PyXMCDA.parseValidate(in_dir + "/performanceTable.xml")

        # We check if all madatory input files are valid
        if xmltree_alternatives == None:
            errorList.append("The alternatives file can't be validated.")
        if xmltree_criteria == None:
            errorList.append("The criteria file can't be validated.")
        if xmltree_perfTable == None:
            errorList.append("The performance table file can't be validated.")
        if xmltree_weights == None:
            errorList.append("The criteria weights file can't be validated.")

            # By default, the valuation domain is fixed to [0,1]
        minValDomain = 0
        maxValDomain = 1

        # If a valuation domain input file has been provided
        if os.path.isfile(in_dir + "/valuationDomain.xml"):

            xmltree_valuation = PyXMCDA.parseValidate(in_dir + "/valuationDomain.xml")
            if xmltree_valuation == None:
                errorList.append("valuationDomain file can't be validated.")

            else:

                minValDomain = PyXMCDA.getParameterByName(xmltree_valuation, "min", "valuationDomain")
                maxValDomain = PyXMCDA.getParameterByName(xmltree_valuation, "max", "valuationDomain")

                # We check the validity of the parameters
                if not isinstance(minValDomain, float) and not isinstance(minValDomain, int):
                    errorList.append("min value should be an integer or a real")
                if not isinstance(maxValDomain, float) and not isinstance(maxValDomain, int):
                    errorList.append("max value should be an integer or a real")

                if not errorList:
                    if minValDomain >= maxValDomain:
                        errorList.append("The max value should be strictly greater than the min value")

        if not errorList:

            alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
            criteriaId = PyXMCDA.getCriteriaID(xmltree_criteria)
            perfTable = PyXMCDA.getPerformanceTable(xmltree_perfTable, alternativesId, criteriaId)
            thresholds = PyXMCDA.getConstantThresholds(xmltree_criteria, criteriaId)
            weights = PyXMCDA.getCriterionValue(xmltree_weights, criteriaId)

            if not alternativesId:
                errorList.append("No alternatives found. Is your alternatives file correct ?")
            if not criteriaId:
                errorList.append("No criteria found. Is your criteria file correct ?")
            if not perfTable:
                errorList.append("No performance table found. Is your performance table file correct ?")
            if not weights:
                errorList.append("No weights found. Is your weights file correct ?")

    if not errorList:

        # We compute the weight sum (only the weights associated to active criteria)
        sumWeights = 0.0

        for crit in criteriaId:
            try:
                sumWeights = sumWeights + weights[crit]
            except:
                errorList.append("There is no defined weight for criterion " + crit + ".")

    if not errorList:

        # We recover the criteria preference directions
        # criteriaDir = PyXMCDA.getCriteriaPreferenceDirections (xmltree_criteria, criteriaId)
        # Plus necessaire

        # We compute the alternative comparisons values
        fileAltValues = open(out_dir + "/alternativesComparisons.xml", "w")
        PyXMCDA.writeHeader(fileAltValues)

        # We write some information about the generated file
        fileAltValues.write(
            "\t<projectReference>\n\t\t<title>Rubis outranking relation</title>\n\t\t<version>"
            + VERSION
            + "</version>\n\t\t<author>ws_PyXMCDA suite (TV)</author>\n\t</projectReference>\n\n"
        )

        fileAltValues.write("\t<alternativesComparisons>\n\t\t<pairs>\n")

        # ATTENTION Solution rustine
        # On retourne ici le tableau de perf pour les criteres a minimiser
        # Devra etre fait par le getRubisElementaryOutranking
        criteriaDir = PyXMCDA.getCriteriaPreferenceDirections(xmltree_criteria, criteriaId)
        for crit in criteriaId:
            if criteriaDir[crit] == "min":
                for alt in alternativesId:
                    perfTable[alt][crit] = -perfTable[alt][crit]

        ElemOut = PyXMCDA.getRubisElementaryOutranking(alternativesId, criteriaId, perfTable, thresholds)

        tabVetos = PyXMCDA.getVetos(alternativesId, criteriaId, perfTable, thresholds)

        for alt1 in alternativesId:
            for alt2 in alternativesId:

                fileAltValues.write(
                    "\t\t\t<pair>\n\t\t\t\t<initial><alternativeID>"
                    + alt1
                    + "</alternativeID></initial>\n\t\t\t\t<terminal><alternativeID>"
                    + alt2
                    + "</alternativeID></terminal>\n"
                )

                # Verifier s'il manque des valeurs !!! try expect
                # fileAltValues.write ("\t\t\t\t<value><NA>not available</NA></value>\n\t\t\t</pair>\n")
                sum = 0.0
                isVeto = 0
                isWeakVeto = 0

                for crit in criteriaId:

                    sum += ElemOut[alt1][alt2][crit] * weights[crit]

                    # On verifie si un veto est leve
                    if (
                        tabVetos.has_key(alt1)
                        and tabVetos[alt1].has_key(alt2)
                        and tabVetos[alt1][alt2].has_key(crit)
                        and tabVetos[alt1][alt2][crit] == 1
                    ):
                        isVeto = 1

                        # On verifie si un veto faible est leve
                    if (
                        tabVetos.has_key(alt1)
                        and tabVetos[alt1].has_key(alt2)
                        and tabVetos[alt1][alt2].has_key(crit)
                        and tabVetos[alt1][alt2][crit] == 0.5
                    ):
                        isWeakVeto = 1

                sum = sum / sumWeights

                if isVeto == 1:
                    # On utilise le veto classique, qui met la valeur minimale
                    sum = 0.0
                elif isWeakVeto == 1 and sum > 0.5:
                    # Un veto faible est leve
                    sum = 0.5

                    # La valeur est entre 0 et 1, on la met dans le bon intervalle
                sum = (maxValDomain - minValDomain) * sum + minValDomain

                fileAltValues.write("\t\t\t\t<value><real>" + str(sum) + "</real></value>\n\t\t\t</pair>\n")

        fileAltValues.write("\t\t</pairs>\n\t</alternativesComparisons>\n")

        PyXMCDA.writeFooter(fileAltValues)
        fileAltValues.close()

        # Creating log and error file, messages.xml
    fileMessages = open(out_dir + "/messages.xml", "w")
    PyXMCDA.writeHeader(fileMessages)

    if not errorList:

        PyXMCDA.writeLogMessages(fileMessages, ["Execution ok"])
    else:
        PyXMCDA.writeErrorMessages(fileMessages, errorList)

    PyXMCDA.writeFooter(fileMessages)
    fileMessages.close()
Пример #34
0
def main(argv=None):
    
    if argv is None:
        argv = sys.argv
        
    parser = OptionParser()

    parser.add_option("-i", "--in", dest="in_dir")
    parser.add_option("-o", "--out", dest="out_dir")

    (options, args) = parser.parse_args(argv[1:])

    in_dir = options.in_dir
    out_dir = options.out_dir

    # Creating a list for error messages
    errorList = []
    
    if not in_dir:
        errorList.append("option --in is missing")
    if not out_dir:
        errorList.append("option --out is missing")
    
    if not errorList:
        if not os.path.isfile (in_dir+"/alternatives.xml"):
            errorList.append("alternatives.xml is missing")
        if not os.path.isfile (in_dir+"/preferenceRelation.xml"):
            errorList.append("preferenceRelation.xml is missing")
        if not os.path.isfile (in_dir+"/methodParameters.xml"):
            errorList.append("methodParameters.xml is missing")

    if not errorList:
        # We parse all the mandatory input files
        xmltree_alternatives = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
        xmltree_preferenceRelation = PyXMCDA.parseValidate(in_dir+"/preferenceRelation.xml")
        xmltree_methodParameters = PyXMCDA.parseValidate(in_dir+"/methodParameters.xml")
        
        # We check if all mandatory input files are valid
        if xmltree_alternatives == None :
            errorList.append("alternatives.xml can't be validated.")
        if xmltree_preferenceRelation == None :
            errorList.append("preferenceRelation.xml can't be validated.")
        if xmltree_methodParameters == None :
            errorList.append("methodParameters.xml can't be validated.")
            
        if not errorList :

            alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
            alternativesRel = PyXMCDA.getAlternativesComparisonsValues(xmltree_preferenceRelation, alternativesId)
            method_type = PyXMCDA.getParameterByName(xmltree_methodParameters, "type")

            if not alternativesId :
                errorList.append("No active alternatives found.")
            if not alternativesRel :
                errorList.append("Problems between relation and alternatives.")
            if not method_type:
                errorList.append("No method type found.")
            missing_eval = False
            for o in alternativesId:
                if not (o in alternativesRel):
                    missing_eval = True
                    break
                else:
                    for p in alternativesId:
                        if not (p in alternativesRel[o]):
                            missing_eval = True
                            break
                        else:
                            if not ('i' in alternativesRel[o][p]):
                                missing_eval = True
                                break
                            if not ('p+' in alternativesRel[o][p]):
                                missing_eval = True
                                break
                            if not ('p-' in alternativesRel[o][p]):
                                missing_eval = True
                                break
                            if not ('j' in alternativesRel[o][p]):
                                missing_eval = True
                                break
            if missing_eval:
                errorList.append("Not all alternatives from alternatives.xml contain evaluations in preferenceRelation.xml, or evaluations are incomplete. Possible inputs from different sources")

            if not errorList :
                alg = Mcc(alternativesId, alternativesRel, method_type)
                K, RK = alg.Run()
                
                fo = open(out_dir+"/alternativesAffectations.xml",'w')
                PyXMCDA.writeHeader(fo)
                fo.write('<alternativesAffectations>\n')
                for i in range(len(K)):
                    for o in K[i]:
                        fo.write('\t<alternativeAffectation>\n\t\t<alternativeID>'+o+'</alternativeID>\n\t\t<categoryID>'+'K'+str(i+1)+'</categoryID>\n\t</alternativeAffectation>\n')
                fo.write('</alternativesAffectations>')
                PyXMCDA.writeFooter(fo)
                fo.close()
                
                fo = open(out_dir+"/clustersRelations.xml",'w')
                PyXMCDA.writeHeader(fo)
                fo.write('<categoriesComparisons>\n')
                fo.write('\t<pairs>\n')
                for i in range(len(K)):
                    for j in range(len(K)):                        
                        fo.write('\t\t<pair>\n')
                        fo.write('\t\t\t<initial>\n')
                        fo.write('\t\t\t\t<categoryID>'+'K'+str(i+1)+'</categoryID>\n')
                        fo.write('\t\t\t</initial>\n')
                        fo.write('\t\t\t<terminal>\n')
                        fo.write('\t\t\t\t<categoryID>'+'K'+str(j+1)+'</categoryID>\n')
                        fo.write('\t\t\t</terminal>\n')
                        fo.write('\t\t\t<value>\n')
                        fo.write('\t\t\t\t<label>'+RK[i][j]+'</label>\n')
                        fo.write('\t\t\t</value>\n')
                        fo.write('\t\t</pair>\n')
                fo.write('\t</pairs>\n')
                fo.write('</categoriesComparisons>')
                PyXMCDA.writeFooter(fo)
                fo.close()                
            
        # Creating log and error file, messages.xml
        fileMessages = open(out_dir+"/messages.xml", 'w')
        PyXMCDA.writeHeader (fileMessages)

        if not errorList :
            PyXMCDA.writeLogMessages (fileMessages, ["Execution ok"])
        else :
            PyXMCDA.writeErrorMessages (fileMessages, errorList)

        PyXMCDA.writeFooter(fileMessages)
        fileMessages.close()
Пример #35
0
def main(argv=None):
    
    if argv is None:
        argv = sys.argv
        
    parser = OptionParser()

    parser.add_option("-i", "--in", dest="in_dir")
    parser.add_option("-o", "--out", dest="out_dir")

    (options, args) = parser.parse_args(argv[1:])

    in_dir = options.in_dir
    out_dir = options.out_dir
    
    # Creating a list for error messages
    errorList = []
    
    if not in_dir:
        errorList.append("option --in is missing")
    if not out_dir:
        errorList.append("option --out is missing")
    
    if not errorList:
        if not os.path.isfile (in_dir+"/alternatives.xml"):
            errorList.append("alternatives.xml is missing")
        if not os.path.isfile (in_dir+"/alternativesComparisons.xml"):
            errorList.append("alternativesComparisons.xml is missing")
        if not os.path.isfile (in_dir+"/methodParameters.xml"):
            errorList.append("methodParameters.xml is missing")

    if not errorList:
        # We parse all the mandatory input files
        xmltree_alternatives = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
        xmltree_alternativesComparisons = PyXMCDA.parseValidate(in_dir+"/alternativesComparisons.xml")
        xmltree_methodParameters = PyXMCDA.parseValidate(in_dir+"/methodParameters.xml")
        
        # We check if all mandatory input files are valid
        if xmltree_alternatives == None :
            errorList.append("alternatives.xml can't be validated.")
        if xmltree_alternativesComparisons == None :
            errorList.append("alternativesComparisons.xml can't be validated.")
        if xmltree_methodParameters == None :
            errorList.append("methodParameters.xml can't be validated.")
            
        if not errorList :

            alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
            alternativesRel = PyXMCDA.getAlternativesComparisons (xmltree_alternativesComparisons, alternativesId)
            bipolar = PyXMCDA.getParameterByName(xmltree_methodParameters, "bipolar")
            cutlvl = PyXMCDA.getParameterByName(xmltree_methodParameters, "cutlvl")

            if not alternativesId :
                errorList.append("No active alternatives found.")
            if not alternativesRel :
                errorList.append("Problems between relation and alternatives.")
            if not bipolar:
                errorList.append("No bipolar parameter found.")
            if not cutlvl:
                errorList.append("No cutlvl parameter found.")
            missing_eval = False
            for o in alternativesId:
                if not (o in alternativesRel):
                    missing_eval = True
                    break
                else:
                    for p in alternativesId:
                        if not (p in alternativesRel[o]):
                            missing_eval = True
                            break
            if missing_eval:
                errorList.append("Not all alternatives from alternatives.xml contain evaluations in alternativesComparisons.xml. Possible inputs from different sources.")

        if not errorList :
            
            PR = PreferenceRelation(alternativesId, alternativesRel, bipolar, cutlvl)
            R = PR.ExtractR()
            L = ['i','p+','p-','j']
            
            fo = open(out_dir+"/preferenceRelation.xml",'w')
            PyXMCDA.writeHeader(fo)
            fo.write('<alternativesComparisons>\n')
            fo.write('\t<pairs>\n')
            for o in alternativesId:
                for p in alternativesId:
                    fo.write('\t\t<pair>\n')
                    fo.write('\t\t\t<initial>\n')
                    fo.write('\t\t\t\t<alternativeID>'+o+'</alternativeID>\n')
                    fo.write('\t\t\t</initial>\n')
                    fo.write('\t\t\t<terminal>\n')
                    fo.write('\t\t\t\t<alternativeID>'+p+'</alternativeID>\n')
                    fo.write('\t\t\t</terminal>\n')
                    fo.write('\t\t\t<values>\n')
                    for i in range(4):
                        fo.write('\t\t\t\t<value id="'+ L[i] +'">\n')
                        fo.write('\t\t\t\t\t<real>'+str(R[o][p][i])+'</real>\n')
                        fo.write('\t\t\t\t</value>\n')
                    fo.write('\t\t\t</values>\n')
                    fo.write('\t\t</pair>\n')
            fo.write('\t</pairs>\n')
            fo.write('</alternativesComparisons>\n')
            PyXMCDA.writeFooter(fo)
            fo.close()                
            
        # Creating log and error file, messages.xml
        fileMessages = open(out_dir+"/messages.xml", 'w')
        PyXMCDA.writeHeader (fileMessages)

        if not errorList :
            PyXMCDA.writeLogMessages (fileMessages, ["Execution ok"])
        else :
            PyXMCDA.writeErrorMessages (fileMessages, errorList)

        PyXMCDA.writeFooter(fileMessages)
        fileMessages.close()
Пример #36
0
 def get_alternatives_positive_flows(*args, **kwargs):
     alternativesID = px.getAlternativesID(trees['alternatives']) 
     flows = px.getAlternativeValue(trees['positive_flows'], alternativesID,)
     return flows
Пример #37
0
def get_input_data(input_dir, filenames, params, **kwargs):
    trees = _get_trees(input_dir, filenames)
    d = _create_data_object(params)
    for p in params:
        if p == 'alternatives':
            d.alternatives = px.getAlternativesID(trees['alternatives'])

        elif p == 'categories_profiles':
            comparison_with = kwargs.get('comparison_with')
            if comparison_with is None:
                comparison_with = px.getParameterByName(trees['method_parameters'], 'comparison_with')
            d.categories_profiles = _get_categories_profiles(trees.get('categories_profiles'),
                                                             comparison_with)

        elif p == 'categories_rank':
            categories = px.getCategoriesID(trees['categories'])
            d.categories_rank = px.getCategoriesRank(trees['categories'], categories)

        elif p == 'comparison_with':
            d.comparison_with = px.getParameterByName(trees['method_parameters'], 'comparison_with')

        elif p == 'concordance':
            alternatives = px.getAlternativesID(trees['alternatives'])
            comparison_with = px.getParameterByName(trees['method_parameters'], 'comparison_with')
            if comparison_with in ('boundary_profiles', 'central_profiles'):
                categories_profiles = _get_categories_profiles(trees['categories_profiles'],
                                                               comparison_with)
                d.concordance = _get_alternatives_comparisons(trees['concordance'], alternatives,
                                                              categories_profiles)
            else:
                d.concordance = px.getAlternativesComparisons(trees['concordance'], alternatives)

        elif p == 'credibility':
            alternatives = px.getAlternativesID(trees['alternatives'])
            comparison_with = kwargs.get('comparison_with')
            if not comparison_with:
                comparison_with = px.getParameterByName(trees['method_parameters'], 'comparison_with')
            if comparison_with in ('boundary_profiles', 'central_profiles'):
                categories_profiles = _get_categories_profiles(trees['categories_profiles'],
                                                               comparison_with)
            else:
                categories_profiles = None
            eliminate_cycles_method = px.getParameterByName(trees.get('method_parameters'),
                                                            'eliminate_cycles_method')
            tree = trees.get('credibility')
            if eliminate_cycles_method == 'cut_weakest' and tree is None:
                raise RuntimeError("'cut_weakest' option requires credibility as "
                                   "an additional input (apart from outranking).")
            d.credibility = _get_alternatives_comparisons(tree, alternatives,
                                                          categories_profiles=categories_profiles)

        elif p == 'criteria':
            d.criteria = px.getCriteriaID(trees['criteria'])

        elif p == 'cut_threshold':
            cut_threshold = px.getParameterByName(trees['method_parameters'], 'cut_threshold')
            if cut_threshold is None or not (0 <= float(cut_threshold) <= 1):
                raise RuntimeError(
                    "'cut_threshold' should be in range [0, 1] "
                    "(most commonly used values are 0.6 or 0.7)."
                )
            d.cut_threshold = cut_threshold

        # 'cv_crossed' == 'counter-veto crossed'
        elif p == 'cv_crossed':
            alternatives = px.getAlternativesID(trees['alternatives'])
            comparison_with = px.getParameterByName(trees['method_parameters'], 'comparison_with')
            if comparison_with in ('boundary_profiles', 'central_profiles'):
                categories_profiles = _get_categories_profiles(trees['categories_profiles'],
                                                               comparison_with)
            else:
                categories_profiles = None
            d.cv_crossed = _get_alternatives_comparisons(trees['counter_veto_crossed'],
                                                         alternatives,
                                                         categories_profiles=categories_profiles,
                                                         use_partials=True,
                                                         mcda_concept='counterVetoCrossed')

        elif p == 'discordance':
            alternatives = px.getAlternativesID(trees['alternatives'])
            comparison_with = px.getParameterByName(trees['method_parameters'], 'comparison_with')
            if kwargs.get('use_partials') is not None:
                use_partials = kwargs.get('use_partials')
            else:
                parameter = px.getParameterByName(trees['method_parameters'], 'use_partials')
                use_partials = True if parameter == 'true' else False
            if comparison_with in ('boundary_profiles', 'central_profiles'):
                categories_profiles = _get_categories_profiles(trees['categories_profiles'],
                                                               comparison_with)
            else:
                categories_profiles = None
            d.discordance = _get_alternatives_comparisons(trees['discordance'], alternatives,
                                                          categories_profiles=categories_profiles,
                                                          use_partials=use_partials)

        elif p == 'eliminate_cycles_method':
            d.eliminate_cycles_method = px.getParameterByName(trees['method_parameters'],
                                                              'eliminate_cycles_method')

        elif p == 'interactions':
            criteria = px.getCriteriaID(trees['criteria'])
            d.interactions = _get_criteria_interactions(trees['interactions'], criteria)

        elif p == 'outranking':
            d.outranking = _get_outranking_crisp(trees['outranking'])

        elif p == 'performances':
            d.performances = px.getPerformanceTable(trees['performance_table'], None, None)

        elif p == 'pref_directions':
            criteria = px.getCriteriaID(trees['criteria'])
            d.pref_directions = px.getCriteriaPreferenceDirections(trees['criteria'], criteria)

        elif p == 'profiles_performance_table':
            if comparison_with in ('boundary_profiles', 'central_profiles'):
                tree = trees.get('profiles_performance_table')
                if tree is None:
                    msg = ("Missing profiles performance table (did you forget "
                           "to provide 'profiles_performance_table.xml' file?).")
                    raise RuntimeError(msg)
                d.profiles_performance_table = px.getPerformanceTable(tree, None, None)
            else:
                d.profiles_performance_table = None

        elif p == 'reinforcement_factors':
            criteria = px.getCriteriaID(trees['criteria'])
            factors = {}
            for c in criteria:
                rf = px.getCriterionValue(trees['reinforcement_factors'], c,
                                          'reinforcement_factors')
                if len(rf) == 0:
                    continue
                if rf.get(c) <= 1:
                    msg = ("Reinforcement factor for criterion '{}' should be "
                           "higher than 1.0 (ideally between 1.2 and 1.5).")
                    raise RuntimeError(msg)
                factors.update(rf)
            d.reinforcement_factors = factors

        elif p == 'thresholds':
            criteria = px.getCriteriaID(trees['criteria'])
            d.thresholds = _get_thresholds(trees['criteria'])

        elif p == 'weights':
            criteria = px.getCriteriaID(trees['criteria'])
            d.weights = px.getCriterionValue(trees['weights'], criteria)

        elif p == 'z_function':
            d.z_function = px.getParameterByName(trees['method_parameters'], 'z_function')

        elif p == 'with_denominator':
            parameter = px.getParameterByName(trees['method_parameters'], 'with_denominator')
            d.with_denominator = True if parameter == 'true' else False

        elif p == 'only_max_discordance':
            parameter = px.getParameterByName(trees['method_parameters'], 'only_max_discordance')
            d.only_max_discordance = True if parameter == 'true' else False

        elif p == 'use_partials':
            parameter = px.getParameterByName(trees['method_parameters'], 'use_partials')
            d.use_partials = True if parameter == 'true' else False

        elif p == 'use_pre_veto':
            parameter = px.getParameterByName(trees['method_parameters'], 'use_pre_veto')
            d.use_pre_veto = True if parameter == 'true' else False

        else:
            raise RuntimeError("Unknown parameter '{}' specified.".format(p))

    for param in params:
        data = getattr(d, param)
        if type(data) in (type(list), type(dict)) and len(data) == 0:
            raise RuntimeError("No content for '{}' parameter provided."
                               .format(param))
    return d
def main(argv=None):
	if argv is None:
		argv = sys.argv
	
	parser = OptionParser()
	
	parser.add_option("-i", "--in", dest="in_dir")
	parser.add_option("-o", "--out", dest="out_dir")
	
	(options, args) = parser.parse_args(argv[1:])
	
	in_dir = options.in_dir
	out_dir = options.out_dir
	
	# Creating lists for error and log messages
	errorList = []
	logList = []
	
	# If some mandatory input files are missing
	if not os.path.isfile (in_dir+"/alternatives.xml") or not os.path.isfile (in_dir+"/criteria.xml") or not os.path.isfile (in_dir+"/alternativesComparisons.xml") or not os.path.isfile (in_dir+"/performanceTable.xml") :
		errorList.append("Some input files are missing")
	
	else :
		
		maxWeight = 0
		
		if os.path.isfile (in_dir+"/maxWeight.xml") :
			xmltree_maxWeight = PyXMCDA.parseValidate(in_dir+"/maxWeight.xml")
			if xmltree_maxWeight == None :
				errorList.append ("maxWeight file can't be validated.")
			else :
				maxWeight = PyXMCDA.getParameterByName (xmltree_maxWeight, "maxWeight")
				if not isinstance(maxWeight,int) :
					errorList.append ("maxWeight value should be a strictly positive integer")
				else :
					if maxWeight <= 0 :
						errorList.append ("maxWeightvalue should be a strictly positive integer")
			
			
		xmltree_alternatives = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
		xmltree_criteria = PyXMCDA.parseValidate(in_dir+"/criteria.xml")
		xmltree_altComparisons = PyXMCDA.parseValidate(in_dir+"/alternativesComparisons.xml")
		xmltree_perfTable = PyXMCDA.parseValidate(in_dir+"/performanceTable.xml")
		
		if xmltree_alternatives == None :
			errorList.append("The alternatives file can't be validated.")
		if xmltree_criteria == None :
			errorList.append("The criteria file can't be validated.")
		if xmltree_perfTable == None :
			errorList.append("The performance table file can't be validated.")
		if xmltree_altComparisons == None :
			errorList.append("The alternatives comparisons file can't be validated.")
	
		if not errorList :
		
			alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
			criteriaId = PyXMCDA.getCriteriaID(xmltree_criteria)
			perfTable = PyXMCDA.getPerformanceTable(xmltree_perfTable, alternativesId, criteriaId)
			thresholds = PyXMCDA.getConstantThresholds (xmltree_criteria, criteriaId)
			altComparisons = PyXMCDA.getAlternativesComparisons (xmltree_altComparisons, alternativesId)
			
			criComparisons = {}
			if os.path.isfile (in_dir+"/criteriaComparisons.xml") :
				xmltree_criComparisons = PyXMCDA.parseValidate(in_dir+"/criteriaComparisons.xml")
				if xmltree_criComparisons == None :
					errorList.append ("criteriaComparisons file can't be validated")
				else :
					criComparisons = PyXMCDA.getCriteriaComparisons (xmltree_criComparisons, criteriaId)
			
			criLB = {}
			if os.path.isfile (in_dir+"/criteriaLowerBounds.xml") :
				xmltree_criLB = PyXMCDA.parseValidate(in_dir+"/criteriaLowerBounds.xml")
				if xmltree_criLB == None :
					errorList.append ("criteriaLowerBounds file can't be validated")
				else :
					criLB = PyXMCDA.getCriterionValue (xmltree_criLB, criteriaId)
					
			criUB = {}
			if os.path.isfile (in_dir+"/criteriaUpperBounds.xml") :
				xmltree_criUB = PyXMCDA.parseValidate(in_dir+"/criteriaUpperBounds.xml")
				if xmltree_criUB == None :
					errorList.append ("criteriaUpperBounds file can't be validated")
				else :
					criUB = PyXMCDA.getCriterionValue (xmltree_criUB, criteriaId)
					
			
			if not alternativesId :
				errorList.append("No alternatives found. Is your alternatives file correct ?")
			if not criteriaId :
				errorList.append("No criteria found. Is your criteria file correct ?")
			if not perfTable :
				errorList.append("No performance table found. Is your performance table file correct ?")
			#if not altComparisons :
			#	errorList.append("No alternatives comparisons found. Is your file correct ?")
			if not thresholds :
				errorList.append("Problem when retrieving the thresholds. The thresholds need to be constant.")
		
	if not errorList :
	
		p = subprocess.Popen(['ampl'], shell=False, bufsize=0,stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
		
		# We write in the pipe the first part of the ampl file
		file = open ("amplRoadef2010_model.txt", 'r')
		p.stdin.write(file.read()) 
		p.stdin.write("\n")
		
		lib_ampl_reverse.create_ampl_reverse_data (p.stdin, alternativesId, criteriaId, perfTable, altComparisons, thresholds, maxWeight, criComparisons, criLB, criUB)
		
		file = open ("amplRoadef2010_solve.txt", 'r')
		p.stdin.write(file.read())
		p.stdin.write("\n")
		p.stdin.flush()
		
		# Calling CPlex for solving MILP
		output,stderr = p.communicate()
		status = p.returncode
		
		# We check the correct resolution
		if status == 0  and not stderr :
			
			if PyXMCDA.getStringPart(output, "nolicense") == "" :
			
				if PyXMCDA.getStringPart(output, "infeasible") != "infeasible" :
							
					# We create the criteriaWeights file
					fileWeights = open(out_dir+"/criteriaWeights.xml", 'w')
					PyXMCDA.writeHeader (fileWeights)
					fileWeights.write (PyXMCDA.getStringPart(output, "criteriaValues"))	
					logList.append("Execution ok")
					logList.append(PyXMCDA.getStringPart(output, "slackSum")) 
					logList.append(PyXMCDA.getCleanedStringPart(output, "CPLexInfos"))
					PyXMCDA.writeFooter(fileWeights)
					fileWeights.close()
				
				else :
					errorList.append ("Infeasible problem.")
					errorList.append (PyXMCDA.getStringPart(output, "CPLexInfos"))
								
			else :
				errorList.append ("No license available.")
				errorList.append (PyXMCDA.getStringPart(output, "CPLexInfos"))
			
		else :
			errorList.append ("CPlex is unable to solve the problem.")
			errorList.append ("CPlex returned status : " + str(status))
			errorList.append (stderr)
		
	
	
	# Creating log and error file, messages.xml
	fileMessages = open(out_dir+"/messages.xml", 'w')
	PyXMCDA.writeHeader (fileMessages)
	
	if not errorList :
		PyXMCDA.writeLogMessages (fileMessages, logList)
	else :
		PyXMCDA.writeErrorMessages (fileMessages, errorList)
		
	PyXMCDA.writeFooter(fileMessages)
	fileMessages.close()
Пример #39
0
def get_input_data(input_dir, filenames, params, **kwargs):
    trees = _get_trees(input_dir, filenames)
    d = _create_data_object(params)
    for p in params:
        if p == 'alternatives':
            d.alternatives = px.getAlternativesID(trees['alternatives'])

        elif p == 'categories_profiles':
            comparison_with = kwargs.get('comparison_with')
            if comparison_with is None:
                comparison_with = px.getParameterByName(
                    trees['method_parameters'], 'comparison_with')
            d.categories_profiles = _get_categories_profiles(
                trees.get('categories_profiles'), comparison_with)

        elif p == 'categories_rank':
            categories = px.getCategoriesID(trees['categories'])
            d.categories_rank = px.getCategoriesRank(trees['categories'],
                                                     categories)

        elif p == 'comparison_with':
            d.comparison_with = px.getParameterByName(
                trees['method_parameters'], 'comparison_with')

        elif p == 'concordance':
            alternatives = px.getAlternativesID(trees['alternatives'])
            comparison_with = px.getParameterByName(trees['method_parameters'],
                                                    'comparison_with')
            if comparison_with in ('boundary_profiles', 'central_profiles'):
                categories_profiles = _get_categories_profiles(
                    trees['categories_profiles'], comparison_with)
                d.concordance = _get_alternatives_comparisons(
                    trees['concordance'], alternatives, categories_profiles)
            else:
                d.concordance = px.getAlternativesComparisons(
                    trees['concordance'], alternatives)

        elif p == 'credibility':
            alternatives = px.getAlternativesID(trees['alternatives'])
            comparison_with = kwargs.get('comparison_with')
            if not comparison_with:
                comparison_with = px.getParameterByName(
                    trees['method_parameters'], 'comparison_with')
            if comparison_with in ('boundary_profiles', 'central_profiles'):
                categories_profiles = _get_categories_profiles(
                    trees['categories_profiles'], comparison_with)
            else:
                categories_profiles = None
            eliminate_cycles_method = px.getParameterByName(
                trees.get('method_parameters'), 'eliminate_cycles_method')
            tree = trees.get('credibility')
            if eliminate_cycles_method == 'cut_weakest' and tree is None:
                raise RuntimeError(
                    "'cut_weakest' option requires credibility as "
                    "an additional input (apart from outranking).")
            d.credibility = _get_alternatives_comparisons(
                tree, alternatives, categories_profiles=categories_profiles)

        elif p == 'criteria':
            d.criteria = px.getCriteriaID(trees['criteria'])

        elif p == 'cut_threshold':
            cut_threshold = px.getParameterByName(trees['method_parameters'],
                                                  'cut_threshold')
            if cut_threshold is None or not (0 <= float(cut_threshold) <= 1):
                raise RuntimeError(
                    "'cut_threshold' should be in range [0, 1] "
                    "(most commonly used values are 0.6 or 0.7).")
            d.cut_threshold = cut_threshold

        # 'cv_crossed' == 'counter-veto crossed'
        elif p == 'cv_crossed':
            alternatives = px.getAlternativesID(trees['alternatives'])
            comparison_with = px.getParameterByName(trees['method_parameters'],
                                                    'comparison_with')
            if comparison_with in ('boundary_profiles', 'central_profiles'):
                categories_profiles = _get_categories_profiles(
                    trees['categories_profiles'], comparison_with)
            else:
                categories_profiles = None
            d.cv_crossed = _get_alternatives_comparisons(
                trees['counter_veto_crossed'],
                alternatives,
                categories_profiles=categories_profiles,
                use_partials=True,
                mcda_concept='counterVetoCrossed')

        elif p == 'discordance':
            alternatives = px.getAlternativesID(trees['alternatives'])
            comparison_with = px.getParameterByName(trees['method_parameters'],
                                                    'comparison_with')
            if kwargs.get('use_partials') is not None:
                use_partials = kwargs.get('use_partials')
            else:
                parameter = px.getParameterByName(trees['method_parameters'],
                                                  'use_partials')
                use_partials = True if parameter == 'true' else False
            if comparison_with in ('boundary_profiles', 'central_profiles'):
                categories_profiles = _get_categories_profiles(
                    trees['categories_profiles'], comparison_with)
            else:
                categories_profiles = None
            d.discordance = _get_alternatives_comparisons(
                trees['discordance'],
                alternatives,
                categories_profiles=categories_profiles,
                use_partials=use_partials)

        elif p == 'eliminate_cycles_method':
            d.eliminate_cycles_method = px.getParameterByName(
                trees['method_parameters'], 'eliminate_cycles_method')

        elif p == 'interactions':
            criteria = px.getCriteriaID(trees['criteria'])
            d.interactions = _get_criteria_interactions(
                trees['interactions'], criteria)

        elif p == 'outranking':
            d.outranking = _get_outranking_crisp(trees['outranking'])

        elif p == 'performances':
            d.performances = px.getPerformanceTable(trees['performance_table'],
                                                    None, None)

        elif p == 'pref_directions':
            criteria = px.getCriteriaID(trees['criteria'])
            d.pref_directions = px.getCriteriaPreferenceDirections(
                trees['criteria'], criteria)

        elif p == 'profiles_performance_table':
            if comparison_with in ('boundary_profiles', 'central_profiles'):
                tree = trees.get('profiles_performance_table')
                if tree is None:
                    msg = (
                        "Missing profiles performance table (did you forget "
                        "to provide 'profiles_performance_table.xml' file?).")
                    raise RuntimeError(msg)
                d.profiles_performance_table = px.getPerformanceTable(
                    tree, None, None)
            else:
                d.profiles_performance_table = None

        elif p == 'reinforcement_factors':
            criteria = px.getCriteriaID(trees['criteria'])
            factors = {}
            for c in criteria:
                rf = px.getCriterionValue(trees['reinforcement_factors'], c,
                                          'reinforcement_factors')
                if len(rf) == 0:
                    continue
                if rf.get(c) <= 1:
                    msg = ("Reinforcement factor for criterion '{}' should be "
                           "higher than 1.0 (ideally between 1.2 and 1.5).")
                    raise RuntimeError(msg)
                factors.update(rf)
            d.reinforcement_factors = factors

        elif p == 'thresholds':
            criteria = px.getCriteriaID(trees['criteria'])
            d.thresholds = _get_thresholds(trees['criteria'])

        elif p == 'weights':
            criteria = px.getCriteriaID(trees['criteria'])
            d.weights = px.getCriterionValue(trees['weights'], criteria)

        elif p == 'z_function':
            d.z_function = px.getParameterByName(trees['method_parameters'],
                                                 'z_function')

        elif p == 'with_denominator':
            parameter = px.getParameterByName(trees['method_parameters'],
                                              'with_denominator')
            d.with_denominator = True if parameter == 'true' else False

        elif p == 'only_max_discordance':
            parameter = px.getParameterByName(trees['method_parameters'],
                                              'only_max_discordance')
            d.only_max_discordance = True if parameter == 'true' else False

        elif p == 'use_partials':
            parameter = px.getParameterByName(trees['method_parameters'],
                                              'use_partials')
            d.use_partials = True if parameter == 'true' else False

        elif p == 'use_pre_veto':
            parameter = px.getParameterByName(trees['method_parameters'],
                                              'use_pre_veto')
            d.use_pre_veto = True if parameter == 'true' else False

        else:
            raise RuntimeError("Unknown parameter '{}' specified.".format(p))

    for param in params:
        data = getattr(d, param)
        if type(data) in (type(list), type(dict)) and len(data) == 0:
            raise RuntimeError(
                "No content for '{}' parameter provided.".format(param))
    return d
Пример #40
0
def main(argv=None):
    
    if argv is None:
        argv = sys.argv
        
    parser = OptionParser()

    parser.add_option("-i", "--in", dest="in_dir")
    parser.add_option("-o", "--out", dest="out_dir")

    (options, args) = parser.parse_args(argv[1:])

    in_dir = options.in_dir
    out_dir = options.out_dir

    # Creating a list for error messages
    errorList = []
    
    if not in_dir:
        errorList.append("option --in is missing")
    if not out_dir:
        errorList.append("option --out is missing")
    
    if not errorList:
        if not os.path.isfile (in_dir+"/alternatives.xml"):
            errorList.append("alternatives.xml is missing")
        if not os.path.isfile (in_dir+"/preferenceRelation.xml"):
            errorList.append("preferenceRelation.xml is missing")
        if not os.path.isfile (in_dir+"/alternativesAffectations.xml"):
            errorList.append("alternativesAffectations.xml is missing")
        if not os.path.isfile (in_dir+"/clustersRelations.xml"):
            errorList.append("clustersRelations.xml is missing")
        if not os.path.isfile (in_dir+"/clustersRelationsDetailed.xml"):
            errorList.append("clustersRelationsDetailed.xml is missing")

    if not errorList:
        # We parse all the mandatory input files
        xmltree_alternatives = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
        xmltree_preferenceRelation = PyXMCDA.parseValidate(in_dir+"/preferenceRelation.xml")
        xmltree_alternativesAffectations = PyXMCDA.parseValidate(in_dir+"/alternativesAffectations.xml")
        xmltree_clustersRelations = PyXMCDA.parseValidate(in_dir+"/clustersRelations.xml")
        xmltree_clustersRelationsDetailed = PyXMCDA.parseValidate(in_dir+"/clustersRelationsDetailed.xml")
        
        # We check if all mandatory input files are valid
        if xmltree_alternatives == None :
            errorList.append("alternatives.xml can't be validated.")
        if xmltree_preferenceRelation == None :
            errorList.append("preferenceRelation.xml can't be validated.")
        if xmltree_alternativesAffectations == None :
            errorList.append("alternativesAffectations.xml can't be validated.")
        if xmltree_clustersRelations == None :
            errorList.append("clustersRelations.xml can't be validated.")
        if xmltree_clustersRelationsDetailed == None :
            errorList.append("clustersRelationsDetailed.xml can't be validated.")
            
        if not errorList :

            alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
            alternativesRel = PyXMCDA.getAlternativesComparisonsValues(xmltree_preferenceRelation, alternativesId)
            
            if not alternativesId :
                errorList.append("No active alternatives found.")
            if not alternativesRel :
                errorList.append("Problems between relation and alternatives.")
            missing_eval = False
            for o in alternativesId:
                if not (o in alternativesRel):
                    missing_eval = True
                    break
                else:
                    for p in alternativesId:
                        if not (p in alternativesRel[o]):
                            missing_eval = True
                            break
                        else:
                            if not ('i' in alternativesRel[o][p]):
                                missing_eval = True
                                break
                            if not ('p+' in alternativesRel[o][p]):
                                missing_eval = True
                                break
                            if not ('p-' in alternativesRel[o][p]):
                                missing_eval = True
                                break
                            if not ('j' in alternativesRel[o][p]):
                                missing_eval = True
                                break
            if missing_eval:
                errorList.append("Not all alternatives from alternatives.xml contain evaluations in preferenceRelation.xml, or evaluations are incomplete. Possible inputs from different sources")
                
            alternativesAffectations = PyXMCDA.getAlternativesAffectations(xmltree_alternativesAffectations)
            Knames = []
            for o in alternativesId:
                clusterId = alternativesAffectations[o]
                if not (clusterId in Knames):
                    Knames.append(clusterId)
            
            if Knames == []:
                errorList.append("No clusters found.")
                
            K = {}
            for clusterId in Knames:
                K[clusterId] = []
            for o in alternativesId:
                K[alternativesAffectations[o]].append(o)
                
            clustersRel = PyXMCDA.getCategoriesComparisonsValues(xmltree_clustersRelations, Knames)
            
            if not clustersRel :
                errorList.append("Problems with clusters relations.")
                
            RK = {}
            for cid1 in Knames:
                RK[cid1] = {}
                for cid2 in Knames:
                    if cid1 == cid2:
                        RK[cid1][cid2] = 'i'
                    else:
                        RK[cid1][cid2] = ''
            missing_eval = False
            for cid1 in Knames:
                for cid2 in Knames:
                    if cid1 != cid2:
                        found = False
                        if cid1 in clustersRel:
                            if cid2 in clustersRel[cid1]:
                                found = True
                                RK[cid1][cid2] = clustersRel[cid1][cid2]
                                if clustersRel[cid1][cid2] == 'p+':
                                    RK[cid2][cid1] = 'p-'
                                elif clustersRel[cid1][cid2] == 'p-':
                                    RK[cid2][cid1] = 'p+'
                                else:
                                    RK[cid2][cid1] = clustersRel[cid1][cid2]
                        if not found and cid2 in clustersRel:
                            if cid1 in clustersRel[cid2]:
                                found = True
                                RK[cid2][cid1] = clustersRel[cid2][cid1]
                                if clustersRel[cid2][cid1] == 'p+':
                                    RK[cid1][cid2] = 'p-'
                                elif clustersRel[cid2][cid1] == 'p-':
                                    RK[cid1][cid2] = 'p+'
                                else:
                                    RK[cid1][cid2] = clustersRel[cid2][cid1]
                        if not found:
                            missing_eval = True
                            break
            if missing_eval:
                errorList.append("Incomplete clusters relations.")
                
            RKsum = PyXMCDA.getCategoriesComparisonsAllValues(xmltree_clustersRelationsDetailed, Knames)

            if not RKsum :
                errorList.append("Problems with detailed clusters relations.")
            missing_eval = False
            for k1 in Knames:
                if not (k1 in RKsum):
                    missing_eval = True
                    break
                else:
                    for k2 in Knames:
                        if not (k2 in RKsum[k1]):
                            missing_eval = True
                            break
                        else:
                            if not ('i' in RKsum[k1][k2]):
                                missing_eval = True
                                break
                            if not ('p+' in RKsum[k1][k2]):
                                missing_eval = True
                                break
                            if not ('p-' in RKsum[k1][k2]):
                                missing_eval = True
                                break
                            if not ('j' in RKsum[k1][k2]):
                                missing_eval = True
                                break
            if missing_eval:
                errorList.append("Incomplete clusters relations summary.")

        if not errorList :
            PC = PlotClusters(alternativesId, alternativesRel, Knames, K, RK, RKsum)
            try:
                PC.PlotKideal(out_dir)
                fo = open(out_dir+"/Kideal.xml",'w')
                PyXMCDA.writeHeader(fo)
                fo.write('<alternativeValue mcdaConcept="Ideal Relations between Clusters">\n')
                fo.write('\t<value>\n')
                fo.write('\t\t<image>')
                fo.write(base64.b64encode(open(out_dir+"/Kideal.png","rb").read()))
                fo.write('</image>\n')
                fo.write('\t</value>\n')
                fo.write('</alternativeValue>\n')
                PyXMCDA.writeFooter(fo)
                fo.close()
                os.remove(out_dir+'/Kideal.png')
                
                PC.PlotKreal(out_dir)
                fo = open(out_dir+"/Kreal.xml",'w')
                PyXMCDA.writeHeader(fo)
                fo.write('<alternativeValue mcdaConcept="Real Relations between Clusters">\n')
                fo.write('\t<value>\n')
                fo.write('\t\t<image>')
                fo.write(base64.b64encode(open(out_dir+"/Kreal.png","rb").read()))
                fo.write('</image>\n')
                fo.write('\t</value>\n')
                fo.write('</alternativeValue>\n')
                PyXMCDA.writeFooter(fo)
                fo.close()
                os.remove(out_dir+'/Kreal.png')
                
                PC.PlotKidealsum(out_dir)
                fo = open(out_dir+"/Kidealsum.xml",'w')
                PyXMCDA.writeHeader(fo)
                fo.write('<alternativeValue mcdaConcept="Summary of Ideal Relations between Clusters">\n')
                fo.write('\t<value>\n')
                fo.write('\t\t<image>')
                fo.write(base64.b64encode(open(out_dir+"/Kidealsum.png","rb").read()))
                fo.write('</image>\n')
                fo.write('\t</value>\n')
                fo.write('</alternativeValue>\n')
                PyXMCDA.writeFooter(fo)
                fo.close()
                os.remove(out_dir+'/Kidealsum.png')
                
                PC.PlotKrealsum(out_dir)      
                fo = open(out_dir+"/Krealsum.xml",'w')
                PyXMCDA.writeHeader(fo)
                fo.write('<alternativeValue mcdaConcept="Summary of Real Relations between Clusters">\n')
                fo.write('\t<value>\n')
                fo.write('\t\t<image>')
                fo.write(base64.b64encode(open(out_dir+"/Krealsum.png","rb").read()))
                fo.write('</image>\n')
                fo.write('\t</value>\n')
                fo.write('</alternativeValue>\n')
                PyXMCDA.writeFooter(fo)
                fo.close()
                os.remove(out_dir+'/Krealsum.png')              

            except Exception as e:
                import traceback
                traceback.print_exc()
                errorList.append("Could not plot clusters.")
            
        # Creating log and error file, messages.xml
        fileMessages = open(out_dir+"/messages.xml", 'w')
        PyXMCDA.writeHeader (fileMessages)

        if not errorList :
            PyXMCDA.writeLogMessages (fileMessages, ["Execution ok"])
        else :
            PyXMCDA.writeErrorMessages (fileMessages, errorList)

        PyXMCDA.writeFooter(fileMessages)
        fileMessages.close()
Пример #41
0
def main(argv=None):
	if argv is None:
		argv = sys.argv
	
	parser = OptionParser()
	
	parser.add_option("-i", "--in", dest="in_dir")
	parser.add_option("-o", "--out", dest="out_dir")
	
	(options, args) = parser.parse_args(argv[1:])
	
	in_dir = options.in_dir
	out_dir = options.out_dir
	
	# Creating a list for error messages
	errorList = []
	
	# If some mandatory input files are missing
	if not os.path.isfile (in_dir+"/alternatives.xml") or not os.path.isfile (in_dir+"/criteria.xml") or not os.path.isfile (in_dir+"/criteriaWeights.xml") or not os.path.isfile (in_dir+"/performanceTable.xml") :
		errorList.append("Some input files are missing")
	
	else :
		
		# We parse all the mandatory input files
		xmltree_alternatives = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
		xmltree_criteria = PyXMCDA.parseValidate(in_dir+"/criteria.xml")
		xmltree_weights = PyXMCDA.parseValidate(in_dir+"/criteriaWeights.xml")
		xmltree_perfTable = PyXMCDA.parseValidate(in_dir+"/performanceTable.xml")
		
		# We check if all madatory input files are valid
		if xmltree_alternatives == None :
			errorList.append("The alternatives file can't be validated.")
		if xmltree_criteria == None :
			errorList.append("The criteria file can't be validated.")
		if xmltree_perfTable == None :
			errorList.append("The performance table file can't be validated.")
		if xmltree_weights == None :
			errorList.append("The criteria weights file can't be validated.")
		
		if not errorList :
		
			alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
			criteriaId = PyXMCDA.getCriteriaID(xmltree_criteria)
			perfTable = PyXMCDA.getPerformanceTable(xmltree_perfTable, alternativesId, criteriaId)
			thresholds = PyXMCDA.getConstantThresholds (xmltree_criteria, criteriaId)
			weights = PyXMCDA.getCriterionValue (xmltree_weights, criteriaId)
		
			if not alternativesId :
				errorList.append("No alternatives found. Is your alternatives file correct ?")
			if not criteriaId :
				errorList.append("No criteria found. Is your criteria file correct ?")
			if not perfTable :
				errorList.append("No performance table found. Is your performance table file correct ?")
			if not weights :
				errorList.append("No weights found. Is your weights file correct ?")
	
	
	if not errorList :
	
		# We check if a criterion weight is defined for all the active criteria
		for crit in criteriaId :
			if not weights.has_key(crit) :
				errorList.append("There is no defined weight for criterion "+crit+".")
		
		
	if not errorList :
		
		# We compute the weighted sum for all the active alternatives
		fileAltValues = open(out_dir+"/alternativesValues.xml", 'w')
		PyXMCDA.writeHeader (fileAltValues)
		
		fileAltValues.write ("<alternativesValues>\n")
		
		for alt in alternativesId :
		
			fileAltValues.write("<alternativeValue><alternativeID>"+alt+"</alternativeID><value>")
			sum = 0.0
			errorAlt = False
	
			for crit in criteriaId :
				
				try :
					sum = sum + weights[crit] * perfTable[alt][crit]
				except :
					errorList.append("No evaluation found for alternative "+alt+" on criterion "+crit+" in the performance table.")
					errorAlt = True
		
			if not errorAlt :	
				fileAltValues.write ("<real>"+str(sum)+"</real></value></alternativeValue>\n")
			else :
				fileAltValues.write ("<NA>not available</NA></value></alternativeValue>\n")
			
		fileAltValues.write ("</alternativesValues>")
		
		PyXMCDA.writeFooter(fileAltValues)
		fileAltValues.close()
	
	# Creating log and error file, messages.xml
	fileMessages = open(out_dir+"/messages.xml", 'w')
	PyXMCDA.writeHeader (fileMessages)
	
	if not errorList :
	
		PyXMCDA.writeLogMessages (fileMessages, ["Execution ok"])
	else :
		PyXMCDA.writeErrorMessages (fileMessages, errorList)
		
	PyXMCDA.writeFooter(fileMessages)
	fileMessages.close()
def main(argv=None):
	if argv is None:
		argv = sys.argv
	
	parser = OptionParser()
	
	parser.add_option("-i", "--in", dest="in_dir")
	parser.add_option("-o", "--out", dest="out_dir")
	
	(options, args) = parser.parse_args(argv[1:])
	
	in_dir = options.in_dir
	out_dir = options.out_dir
	
	# Creating lists for error and log messages
	errorList = []
	logList = []
	
	# If some mandatory input files are missing
	if not os.path.isfile (in_dir+"/alternatives.xml") or not os.path.isfile (in_dir+"/criteria.xml") or not os.path.isfile (in_dir+"/performanceTable.xml"):
		errorList.append("Some input files are missing")
	
	else:
			
		xmltree_alternatives = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
		xmltree_criteria = PyXMCDA.parseValidate(in_dir+"/criteria.xml")
		xmltree_perfTable = PyXMCDA.parseValidate(in_dir+"/performanceTable.xml")
		
		if xmltree_alternatives == None:
			errorList.append("The alternatives file can't be validated.")
		if xmltree_criteria == None:
			errorList.append("The criteria file can't be validated.")
		if xmltree_perfTable == None:
			errorList.append("The performance table file can't be validated.")

		if not errorList:
		
			alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
			criteriaId = PyXMCDA.getCriteriaID(xmltree_criteria)
			perfTable = PyXMCDA.getPerformanceTable(xmltree_perfTable, alternativesId, criteriaId)
			thresholds = PyXMCDA.getConstantThresholds (xmltree_criteria, criteriaId)
		
			if not alternativesId:
				errorList.append("No alternatives found. Is your alternatives file correct ?")
			if not criteriaId:
				errorList.append("No criteria found. Is your criteria file correct ?")
			if not perfTable:
				errorList.append("No performance table found. Is your performance table file correct ?")
		
	if not errorList:
	
		ElemOut = PyXMCDA.getRubisElementaryOutranking (alternativesId, criteriaId, perfTable, thresholds)
		
		# Adding thresholds equals to 0 when they are not defined
		for crit in criteriaId:
			if not thresholds.has_key(crit):
				thresholds[crit] = {}
			if not thresholds[crit].has_key("indifference"):
				thresholds[crit]["indifference"] = 0
			if not thresholds[crit].has_key("preference"):
				thresholds[crit]["preference"] = 0
				
		# Creating the table for min and max thresholds
		thresholdsBounds = {}
		
		for crit in criteriaId:
			thresholdsBounds[crit] = {}
			thresholdsBounds[crit]["ind"] = {}
			thresholdsBounds[crit]["ind"]["min"] = 0.0
			thresholdsBounds[crit]["pre"] = {}
			thresholdsBounds[crit]["pre"]["min"] = 0.0
			
			for alt1 in alternativesId:
				for alt2 in alternativesId:
					if alt1 != alt2:
						if perfTable[alt1][crit] < perfTable[alt2][crit]:
							if ElemOut[alt1][alt2][crit] == 1:
								if perfTable[alt2][crit] - perfTable[alt1][crit] > thresholdsBounds[crit]["ind"]["min"]:
									thresholdsBounds[crit]["ind"]["min"] = perfTable[alt2][crit] - perfTable[alt1][crit]
								if perfTable[alt2][crit] - perfTable[alt1][crit] > thresholdsBounds[crit]["pre"]["min"]:
									thresholdsBounds[crit]["pre"]["min"] = perfTable[alt2][crit] - perfTable[alt1][crit]
							elif ElemOut[alt1][alt2][crit] == 0.5:
								if perfTable[alt2][crit] - perfTable[alt1][crit] > thresholdsBounds[crit]["pre"]["min"]:
									thresholdsBounds[crit]["pre"]["min"] = perfTable[alt2][crit] - perfTable[alt1][crit]
								if not thresholdsBounds[crit]["ind"].has_key("max") or perfTable[alt2][crit] - perfTable[alt1][crit] < thresholdsBounds[crit]["ind"]["max"]:
									thresholdsBounds[crit]["ind"]["max"] = perfTable[alt2][crit] - perfTable[alt1][crit]
							else:
								if not thresholdsBounds[crit]["ind"].has_key("max") or perfTable[alt2][crit] - perfTable[alt1][crit] < thresholdsBounds[crit]["ind"]["max"]:
									thresholdsBounds[crit]["ind"]["max"] = perfTable[alt2][crit] - perfTable[alt1][crit]
								if not thresholdsBounds[crit]["pre"].has_key("max") or perfTable[alt2][crit] - perfTable[alt1][crit] < thresholdsBounds[crit]["pre"]["max"]:
									thresholdsBounds[crit]["pre"]["max"] = perfTable[alt2][crit] - perfTable[alt1][crit]

		# Creating criteriaThresholdsBounds file
		fileThresholds = open(out_dir+"/criteriaThresholdsBounds.xml",'w')
		PyXMCDA.writeHeader(fileThresholds)
		
		# We write some information about the generated file
		fileThresholds.write ("\t<projectReference>\n\t\t<title>Thresholds Sensitivity Analysis (TSA)</title>\n\t\t<version>"+VERSION+"</version>\n\t\t<author>ws_PyXMCDA suite (TV)</author>\n\t</projectReference>\n\n")
	
		# Writing the indLowerBounds
		fileThresholds.write("<criteriaValues mcdaConcept='indLowerBounds'>\n")
		for crit in criteriaId:
			if thresholdsBounds[crit]["ind"].has_key("min"):
				fileThresholds.write("<criterionValue><criterionID>"+crit+"</criterionID><value><real>"+str(thresholdsBounds[crit]["ind"]["min"])+"</real></value></criterionValue>\n")
		fileThresholds.write("</criteriaValues>\n\n")
		
		# Writing the indUpperBounds
		fileThresholds.write("<criteriaValues mcdaConcept='indUpperBounds'>\n")
		for crit in criteriaId:
			if thresholdsBounds[crit]["ind"].has_key("max"):
				fileThresholds.write("<criterionValue><criterionID>"+crit+"</criterionID><value><real>"+str(thresholdsBounds[crit]["ind"]["max"])+"</real></value></criterionValue>\n")
		fileThresholds.write("</criteriaValues>\n\n")
		
		# Writing the indLowerBounds
		fileThresholds.write("<criteriaValues mcdaConcept='prefLowerBounds'>\n")
		for crit in criteriaId:
			if thresholdsBounds[crit]["pre"].has_key("min"):
				fileThresholds.write("<criterionValue><criterionID>"+crit+"</criterionID><value><real>"+str(thresholdsBounds[crit]["pre"]["min"])+"</real></value></criterionValue>\n")
		fileThresholds.write("</criteriaValues>\n\n")
		
		# Writing the preUpperBounds
		fileThresholds.write("<criteriaValues mcdaConcept='prefUpperBounds'>\n")
		for crit in criteriaId:
			if thresholdsBounds[crit]["pre"].has_key("max"):
				fileThresholds.write("<criterionValue><criterionID>"+crit+"</criterionID><value><real>"+str(thresholdsBounds[crit]["pre"]["max"])+"</real></value></criterionValue>\n")
		fileThresholds.write("</criteriaValues>\n\n")
		
		PyXMCDA.writeFooter(fileThresholds)
		fileThresholds.close()
			
	# Creating log and error file, messages.xml
	fileMessages = open(out_dir+"/messages.xml", 'w')
	PyXMCDA.writeHeader (fileMessages)
	
	if not errorList:
		logList.append("Execution ok")
		PyXMCDA.writeLogMessages (fileMessages, logList)
	else:
		PyXMCDA.writeErrorMessages (fileMessages, errorList)
		
	PyXMCDA.writeFooter(fileMessages)
	fileMessages.close()
Пример #43
0
def main(argv=None):
    
    if argv is None:
        argv = sys.argv
        
    parser = OptionParser()

    parser.add_option("-i", "--in", dest="in_dir")
    parser.add_option("-o", "--out", dest="out_dir")

    (options, args) = parser.parse_args(argv[1:])

    in_dir = options.in_dir
    out_dir = options.out_dir

    # Creating a list for error messages
    errorList = []
    
    if not in_dir:
        errorList.append("option --in is missing")
    if not out_dir:
        errorList.append("option --out is missing")
    
    if not errorList:
        if not os.path.isfile (in_dir+"/alternatives.xml"):
            errorList.append("alternatives.xml is missing")
        if not os.path.isfile (in_dir+"/preferenceRelation.xml"):
            errorList.append("preferenceRelation.xml is missing")
        if not os.path.isfile (in_dir+"/alternativesAffectations.xml"):
            errorList.append("alternativesAffectations.xml is missing")

    if not errorList:
        # We parse all the mandatory input files
        xmltree_alternatives = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
        xmltree_preferenceRelation = PyXMCDA.parseValidate(in_dir+"/preferenceRelation.xml")
        xmltree_alternativesAffectations = PyXMCDA.parseValidate(in_dir+"/alternativesAffectations.xml")
        
        # We check if all mandatory input files are valid
        if xmltree_alternatives == None :
            errorList.append("alternatives.xml can't be validated.")
        if xmltree_preferenceRelation == None :
            errorList.append("preferenceRelation.xml can't be validated.")
        if xmltree_alternativesAffectations == None :
            errorList.append("alternativesAffectations.xml can't be validated.")
            
        if not errorList :

            alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
            alternativesRel = PyXMCDA.getAlternativesComparisonsValues(xmltree_preferenceRelation, alternativesId)
            
            if not alternativesId :
                errorList.append("No active alternatives found.")
            if not alternativesRel :
                errorList.append("Problems between relation and alternatives.")
            missing_eval = False
            for o in alternativesId:
                if not (o in alternativesRel):
                    missing_eval = True
                    break
                else:
                    for p in alternativesId:
                        if not (p in alternativesRel[o]):
                            missing_eval = True
                            break
                        else:
                            if not ('i' in alternativesRel[o][p]):
                                missing_eval = True
                                break
                            if not ('p+' in alternativesRel[o][p]):
                                missing_eval = True
                                break
                            if not ('p-' in alternativesRel[o][p]):
                                missing_eval = True
                                break
                            if not ('j' in alternativesRel[o][p]):
                                missing_eval = True
                                break
            if missing_eval:
                errorList.append("Not all alternatives from alternatives.xml contain evaluations in preferenceRelation.xml, or evaluations are incomplete. Possible inputs from different sources")
                
            alternativesAffectations = PyXMCDA.getAlternativesAffectations(xmltree_alternativesAffectations)
            Knames = []
            for o in alternativesId:
                clusterId = alternativesAffectations[o]
                if not (clusterId in Knames):
                    Knames.append(clusterId)
            
            if Knames == []:
                errorList.append("No clusters found.")
                
            K = {}
            for clusterId in Knames:
                K[clusterId] = []
            for o in alternativesId:
                K[alternativesAffectations[o]].append(o)

            if not errorList :
                CRS = ClustersRelationSummary(alternativesId, alternativesRel)
                RKsum = CRS.RKSummary(K)
            
                L = ['i','p+','p-','j']
            
                fo = open(out_dir+"/clustersRelationsDetailed.xml",'w')
                PyXMCDA.writeHeader(fo)
                fo.write('<categoriesComparisons>\n')
                fo.write('\t<pairs>\n')
                for i in Knames:
                    for j in Knames:
                        fo.write('\t\t<pair>\n')
                        fo.write('\t\t\t<initial>\n')
                        fo.write('\t\t\t\t<categoryID>'+i+'</categoryID>\n')
                        fo.write('\t\t\t</initial>\n')
                        fo.write('\t\t\t<terminal>\n')
                        fo.write('\t\t\t\t<categoryID>'+j+'</categoryID>\n')
                        fo.write('\t\t\t</terminal>\n')
                        fo.write('\t\t\t<values>\n')
                        for l in L:
                            fo.write('\t\t\t\t<value id="'+ l +'">\n')
                            fo.write('\t\t\t\t\t<real>'+str(RKsum[i][j][l])+'</real>\n')
                            fo.write('\t\t\t\t</value>\n')
                        fo.write('\t\t\t</values>\n')
                        fo.write('\t\t</pair>\n')
                fo.write('\t</pairs>\n')
                fo.write('</categoriesComparisons>\n')
                PyXMCDA.writeFooter(fo)
                fo.close()
                
            
        # Creating log and error file, messages.xml
        fileMessages = open(out_dir+"/messages.xml", 'w')
        PyXMCDA.writeHeader (fileMessages)

        if not errorList :
            PyXMCDA.writeLogMessages (fileMessages, ["Execution ok"])
        else :
            PyXMCDA.writeErrorMessages (fileMessages, errorList)

        PyXMCDA.writeFooter(fileMessages)
        fileMessages.close()
Пример #44
0
def main(argv=None):
	if argv is None:
		argv = sys.argv
	
	parser = OptionParser()
	
	parser.add_option("-i", "--in", dest="in_dir")
	parser.add_option("-o", "--out", dest="out_dir")
	
	(options, args) = parser.parse_args(argv[1:])
	
	in_dir = options.in_dir
	out_dir = options.out_dir
	
	critAverage = {}
	critNormalSD = {}
	critTriangSD = {}
	
	# Creating a list for error messages
	errorList = []
	
	# If some mandatory input files are missing
	if not os.path.isfile (in_dir+"/alternatives.xml") or not os.path.isfile (in_dir+"/criteria.xml") :
		errorList.append("Some input files are missing")
	
	else :
		
		# We parse all the mandatory input files
		xmltree_alternatives = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
		xmltree_criteria = PyXMCDA.parseValidate(in_dir+"/criteria.xml")
		
		# We check if all madatory input files are valid
		if xmltree_alternatives == None :
			errorList.append("The alternatives file can't be validated.")
		if xmltree_criteria == None :
			errorList.append("The criteria file can't be validated.")
	
		if not errorList :
		
			alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
			criteriaId = PyXMCDA.getCriteriaID(xmltree_criteria)
			
			if not alternativesId :
				errorList.append("No alternatives found. Is your alternatives file correct ?")
			if not criteriaId :
				errorList.append("No criteria found. Is your criteria file correct ?")
	
	if not errorList :
	
		# We check if parameters for criteria distribution profile have been provided
		if os.path.isfile (in_dir+"/criteriaProfiles.xml") :
			xmltree_CritProfile = PyXMCDA.parseValidate(in_dir+"/criteriaProfiles.xml")
			if xmltree_CritProfile == None :
				errorList.append ("criteriaProfiles file can't be validated.")
			else :
				critAverage = PyXMCDA.getNamedParametersByName (xmltree_CritProfile, "distributionAverage")
				critNormalSD = PyXMCDA.getNamedParametersByName (xmltree_CritProfile, "normalDistributionStandardDeviation")
				critTriangSD = PyXMCDA.getNamedParametersByName (xmltree_CritProfile, "triangularDistributionStandardDeviation")
				# ...
				
	if not errorList :
	
		# We check if a seed is provided for the random generation
		if os.path.isfile (in_dir+"/seed.xml") :
			xmltree_seed = PyXMCDA.parseValidate(in_dir+"/seed.xml")
			if xmltree_seed == None :
				errorList.append ("seed file can't be validated.")
			else :
				seed = PyXMCDA.getParameterByName (xmltree_seed, "seed")
				if not isinstance(seed,int) :
					errorList.append ("seed value should be a strictly positive integer")
				else :
					if seed <= 0 :
						errorList.append ("seed should be a strictly positive integer")
					else:
						# We initialize the random generator
						random.seed(seed)
						
	if not errorList :
	
		for i in range(20):
			print random.random()
	
		# We recover criteria scale information
		criteriaTypes = PyXMCDA.getCriteriaScalesTypes (xmltree_criteria, criteriaId)
		criteriaDir = PyXMCDA.getCriteriaPreferenceDirections (xmltree_criteria, criteriaId)
		criteriaUB = PyXMCDA.getCriteriaUpperBounds (xmltree_criteria, criteriaId)
		criteriaLB = PyXMCDA.getCriteriaLowerBounds (xmltree_criteria, criteriaId)
		criteriaRL = PyXMCDA.getCriteriaRankedLabel (xmltree_criteria, criteriaId)
		
		# We add some default lower and upper bounds
		for crit in criteriaId :
			if not criteriaLB.has_key (crit) or criteriaLB[crit] == None :
				if criteriaTypes[crit] == "quantitative" :
					criteriaLB[crit] = 0.0
				else :
					criteriaLB[crit] = 1
			if not criteriaUB.has_key (crit) or criteriaUB[crit] == None :
				if criteriaTypes[crit] == "quantitative" :
					criteriaUB[crit] = 100.0
				else :
					if criteriaRL.has_key(crit) and criteriaRL[crit] != None :
						criteriaUB[crit] = len(criteriaRL[crit])
					else :
						criteriaUB[crit] = 10
				
		# We construct the performance Tableau
		Tab = {}
		for crit in criteriaId :
			Tab[crit] = {}
			
			if critNormalSD.has_key(crit) :
				sd = critNormalSD[crit]
				if critAverage.has_key(crit) :
					average = critAverage[crit]
				else :
					average = (criteriaLB[crit] + criteriaUB[crit])/2.0
				for alt in alternativesId :			
					temp = criteriaLB[crit] -1
					while temp < criteriaLB[crit] or temp > criteriaUB[crit] :
						temp = random.gauss (average,sd)
					Tab[crit][alt] = temp
					if criteriaTypes[crit] == "qualitative" :
						Tab[crit][alt] = int(Tab[crit][alt])
					
			elif critTriangSD.has_key (crit) :
				for alt in alternativesId :
					# TO BE CHANGED !!!
					Tab[crit][alt] = random.randint (criteriaLB[crit], criteriaUB[crit])
			
			else :
				for alt in alternativesId :
					if criteriaTypes[crit] == "quantitative" :
						Tab[crit][alt] = float(random.randint (criteriaLB[crit]*100, criteriaUB[crit]*100))/100.0
					else :
						Tab[crit][alt] = random.randint (criteriaLB[crit], criteriaUB[crit])
		
		# We construct the performanceTable.xml file
		filePerfTable = open(out_dir+"/performanceTable.xml", 'w')
		PyXMCDA.writeHeader (filePerfTable)
		
		filePerfTable.write ("<performanceTable>\n")
		
		for alt in alternativesId :
			filePerfTable.write ("\t<alternativePerformances>\n\t\t<alternativeID>" + alt + "</alternativeID>\n")
			
			for crit in criteriaId :
				if criteriaTypes[crit] == "quantitative" :
					filePerfTable.write ("\t\t<performance>\n\t\t\t<criterionID>" + crit + "</criterionID>\n\t\t\t<value><real>"+ str(Tab[crit][alt]) + "</real></value>\n\t\t</performance>\n")
				else :
					filePerfTable.write ("\t\t<performance>\n\t\t\t<criterionID>" + crit + "</criterionID>\n\t\t\t<value><integer>"+ str(Tab[crit][alt]) + "</integer></value>\n\t\t</performance>\n")
			
			filePerfTable.write ("\t</alternativePerformances>\n")
		
		filePerfTable.write ("</performanceTable>\n")
		
		PyXMCDA.writeFooter(filePerfTable)
		filePerfTable.close()
	
	# Creating log and error file, messages.xml
	fileMessages = open(out_dir+"/messages.xml", 'w')
	PyXMCDA.writeHeader (fileMessages)
	
	if not errorList :
	
		PyXMCDA.writeLogMessages (fileMessages, ["Execution ok"])
	else :
		PyXMCDA.writeErrorMessages (fileMessages, errorList)
		
	PyXMCDA.writeFooter(fileMessages)
	fileMessages.close()
Пример #45
0
def main(argv=None):
	if argv is None:
		argv = sys.argv
	
	parser = OptionParser()
	
	parser.add_option("-i", "--in", dest="in_dir")
	parser.add_option("-o", "--out", dest="out_dir")
	
	(options, args) = parser.parse_args(argv[1:])
	
	in_dir = options.in_dir
	out_dir = options.out_dir
	
	# Creating lists for error and log messages
	errorList = []
	logList = []
	
	# If some mandatory input files are missing
	if not os.path.isfile (in_dir+"/alternatives.xml") or not os.path.isfile (in_dir+"/categories.xml") or not os.path.isfile (in_dir+"/categoriesProfiles.xml") or not os.path.isfile (in_dir+"/stabilityRelation.xml"):
		errorList.append("Some input files are missing")
	
	else :
		
		if os.path.isfile (in_dir+"/sortingMode.xml") :
			xmltree_mode = PyXMCDA.parseValidate(in_dir+"/sortingMode.xml")
			if xmltree_mode == None :
				errorList.append ("sortingMode file cannot be validated.")
			else :
				mode = PyXMCDA.getParameterByName (xmltree_mode, "sortingMode")
				if not (mode == "pessimistic" or mode == "optimistic"):
					errorList.append ("Value of parameter sortingMode should be 'pessimistic' or 'optimistic'.")			
			
		xmltree_alternatives = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
		xmltree_categories = PyXMCDA.parseValidate(in_dir+"/categories.xml")
		xmltree_profiles = PyXMCDA.parseValidate(in_dir+"/categoriesProfiles.xml")
		xmltree_altStability = PyXMCDA.parseValidate(in_dir+"/stabilityRelation.xml")
		
		if xmltree_alternatives == None :
			errorList.append("The alternatives file cannot be validated.")
		if xmltree_categories == None :
			errorList.append("The categories file cannot be validated.")
		if xmltree_profiles == None :
			errorList.append("The categoriesProfiles file cannot be validated.")
		if xmltree_altStability == None :
			errorList.append("The alternatives comparisons file cannot be validated.")
				
		if not errorList :
		
			alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives, "ACTIVEREAL")
			allalt = PyXMCDA.getAlternativesID(xmltree_alternatives, "ACTIVE")
			categoriesId = PyXMCDA.getCategoriesID(xmltree_categories)
			categoriesRank = PyXMCDA.getCategoriesRank(xmltree_categories, categoriesId)
			altStability = PyXMCDA.getAlternativesComparisons (xmltree_altStability, allalt)
			
			if not alternativesId:
				errorList.append("No alternatives found.")
			if not categoriesId:
				errorList.append("No categories found.")
			if not altStability :
				errorList.append("No alternatives comparisons found.")
					
	if not errorList :
		
		catPro = PyXMCDA.getCategoriesProfiles(xmltree_profiles, categoriesId)
		proCat = PyXMCDA.getProfilesCategories(xmltree_profiles, categoriesId)
		profilesId = proCat.keys()
		
		# On retourne la liste pour trier selon les rangs
		rankCategories = {}
		for i, j in categoriesRank.iteritems():
			rankCategories[j] = i
			
		ranks = rankCategories.keys()[:]
		
		ranks.sort()
		lowestRank = ranks.pop()
		
		# Un tableau pour conserver les affectations
		affectations = {}
		
		if mode == "pessimistic":
			# Electre tri pessimistic rule
			for alt in alternativesId:
				affectations[alt] = []
				for rank in ranks:
					profile = catPro[rankCategories[rank]]["lower"]
					if altStability[alt][profile] >= -1 and altStability[alt][profile] <= 1:
						# Surclassement instable, on ajoute les categories sup et inf
						if affectations[alt].count(proCat[profile]["lower"]) == 0:
							affectations[alt].append(proCat[profile]["lower"])
						if affectations[alt].count(proCat[profile]["upper"]) == 0:
							affectations[alt].append(proCat[profile]["upper"])
					if altStability[alt][profile] > 1:
						# Surclassement stable, on ajoute que sup et on arrete
						if affectations[alt].count(proCat[profile]["upper"]) == 0:
							affectations[alt].append(proCat[profile]["upper"])
							break
				
				if affectations[alt] == []:
					# Tous les surc stables et negatifs, on force la categorie la plus basse
					affectations[alt] = [rankCategories[lowestRank]]

		else:
			errorList.append("Optimistic rule is not taken into account yet")
	
	if not errorList :	
					
		# Creating alternativesAffectations file
		fileAffectations = open(out_dir+"/alternativesAffectations.xml",'w')
		PyXMCDA.writeHeader(fileAffectations)
		
		# We write some information about the generated file
		fileAffectations.write ("\t<projectReference>\n\t\t<title>Stable alternatives affectation</title>\n\t\t<version>"+VERSION+"</version>\n\t\t<author>ws_PyXMCDA suite (TV)</author>\n\t</projectReference>\n\n")
		
		fileAffectations.write("\t<alternativesAffectations>\n")
		
		for alt in alternativesId:
			fileAffectations.write("\t\t<alternativeAffectation>\n\t\t\t<alternativeID>"+alt+"</alternativeID>\n\t\t\t<categoriesSet>\n")
			
			for cat in affectations[alt]:
				fileAffectations.write("\t\t\t\t<element><categoryID>"+cat+"</categoryID></element>\n")

			fileAffectations.write("\t\t\t</categoriesSet>\n\t\t</alternativeAffectation>\n")
		
		fileAffectations.write("\t</alternativesAffectations>\n")
		PyXMCDA.writeFooter(fileAffectations)
		fileAffectations.close()
	
	
	# Creating log and error file, messages.xml
	fileMessages = open(out_dir+"/messages.xml", 'w')
	PyXMCDA.writeHeader (fileMessages)
	
	if not errorList :
		logList.append("Execution ok")
		PyXMCDA.writeLogMessages (fileMessages, logList)
	else :
		PyXMCDA.writeErrorMessages (fileMessages, errorList)
		
	PyXMCDA.writeFooter(fileMessages)
	fileMessages.close()
def main(argv=None):
	if argv is None:
		argv = sys.argv
	
	parser = OptionParser()
	
	parser.add_option("-i", "--in", dest="in_dir")
	parser.add_option("-o", "--out", dest="out_dir")
	
	(options, args) = parser.parse_args(argv[1:])
	
	in_dir = options.in_dir
	out_dir = options.out_dir
	
	# Creating a list for error messages
	errorList = []
	
	# If some mandatory input files are missing
	if not os.path.isfile (in_dir+"/alternatives.xml") or not os.path.isfile (in_dir+"/criteria.xml") or not os.path.isfile (in_dir+"/criteriaWeights.xml") or not os.path.isfile (in_dir+"/performanceTable.xml") :
		errorList.append("Some input files are missing")
	
	else :
		
		# We parse all the mandatory input files
		xmltree_alternatives = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
		xmltree_criteria = PyXMCDA.parseValidate(in_dir+"/criteria.xml")
		xmltree_weights = PyXMCDA.parseValidate(in_dir+"/criteriaWeights.xml")
		xmltree_perfTable = PyXMCDA.parseValidate(in_dir+"/performanceTable.xml")
		
		# We check if all madatory input files are valid
		if xmltree_alternatives == None :
			errorList.append("The alternatives file can't be validated.")
		if xmltree_criteria == None :
			errorList.append("The criteria file can't be validated.")
		if xmltree_perfTable == None :
			errorList.append("The performance table file can't be validated.")
		if xmltree_weights == None :
			errorList.append("The criteria weights file can't be validated.")
		
		# By default, the valuation domain is fixed to [0,1]	
		minValDomain = 0
		maxValDomain = 1
		
		# If a valuation domain input file has been provided
		if os.path.isfile (in_dir+"/valuationDomain.xml") :
		
			xmltree_valuation = PyXMCDA.parseValidate(in_dir+"/valuationDomain.xml")
			if xmltree_valuation == None :
				errorList.append ("valuationDomain file can't be validated.")
				
			else :
			
				minValDomain = PyXMCDA.getParameterByName (xmltree_valuation, "min", "valuationDomain")
				maxValDomain = PyXMCDA.getParameterByName (xmltree_valuation, "max", "valuationDomain")
				
				# We check the validity of the parameters
				if not isinstance(minValDomain,float) and not isinstance(minValDomain,int) :
					errorList.append ("min value should be an integer or a real")
				if not isinstance(maxValDomain,float) and not isinstance(maxValDomain,int) :
					errorList.append ("max value should be an integer or a real")
					
				if not errorList :
					if minValDomain >= maxValDomain :
						errorList.append ("The max value should be strictly greater than the min value")
	
		if not errorList :
		
			alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
			criteriaId = PyXMCDA.getCriteriaID(xmltree_criteria)
			perfTable = PyXMCDA.getPerformanceTable(xmltree_perfTable, alternativesId, criteriaId)
			thresholds = PyXMCDA.getConstantThresholds (xmltree_criteria, criteriaId)
			weights = PyXMCDA.getCriterionValue (xmltree_weights, criteriaId)
		
			if not alternativesId :
				errorList.append("No alternatives found. Is your alternatives file correct ?")
			if not criteriaId :
				errorList.append("No criteria found. Is your criteria file correct ?")
			if not perfTable :
				errorList.append("No performance table found. Is your performance table file correct ?")
			if not weights :
				errorList.append("No weights found. Is your weights file correct ?")
		
	if not errorList :
	
		# We compute the weight sum (only the weights associated to active criteria)
		sumWeights = 0.0
		
		for crit in criteriaId :
			try :
				sumWeights = sumWeights + weights[crit]
			except :
				errorList.append("There is no defined weight for criterion "+crit+".")
		
	if not errorList :
		
		# We recover the criteria preference directions
		criteriaDir = PyXMCDA.getCriteriaPreferenceDirections (xmltree_criteria, criteriaId)
	
		# We compute the alternative comparisons values
		fileAltValues = open(out_dir+"/alternativesComparisons.xml", 'w')
		PyXMCDA.writeHeader (fileAltValues)
		
		fileAltValues.write ("\t<alternativesComparisons>\n\t\t<pairs>\n")
		
		ElemOut = PyXMCDA.getRubisElementaryOutranking (alternativesId, criteriaId, perfTable, thresholds)
		
		for alt1 in alternativesId :
			for alt2 in alternativesId :
			
				fileAltValues.write("\t\t\t<pair>\n\t\t\t\t<initial><alternativeID>"+alt1+"</alternativeID></initial>\n\t\t\t\t<terminal><alternativeID>"+alt2+"</alternativeID></terminal>\n")
				
				# Verifier s'il manque des valeurs !!! try expect
				#fileAltValues.write ("\t\t\t\t<value><NA>not available</NA></value>\n\t\t\t</pair>\n")
				sum = 0.0
				
				for crit in criteriaId :
					
					sum += ElemOut[alt1][alt2][crit] * weights[crit]
					
				sum = sum/sumWeights
				
				# La valeur est entre 0 et 1, on la met dans le bon intervalle
				sum = (maxValDomain - minValDomain)*sum + minValDomain
				
				fileAltValues.write ("\t\t\t\t<value><real>"+str(sum)+"</real></value>\n\t\t\t</pair>\n")
					
			
		fileAltValues.write ("\t\t</pairs>\n\t</alternativesComparisons>\n")
			
		PyXMCDA.writeFooter(fileAltValues)
		fileAltValues.close()
	
	# Creating log and error file, messages.xml
	fileMessages = open(out_dir+"/messages.xml", 'w')
	PyXMCDA.writeHeader (fileMessages)
	
	if not errorList :
	
		PyXMCDA.writeLogMessages (fileMessages, ["Execution ok"])
	else :
		PyXMCDA.writeErrorMessages (fileMessages, errorList)
		
	PyXMCDA.writeFooter(fileMessages)
	fileMessages.close()
Пример #47
0
def main(argv=None):
    
    if argv is None:
        argv = sys.argv
        
    parser = OptionParser()

    parser.add_option("-i", "--in", dest="in_dir")
    parser.add_option("-o", "--out", dest="out_dir")

    (options, args) = parser.parse_args(argv[1:])

    in_dir = options.in_dir
    out_dir = options.out_dir

    # Creating a list for error messages
    errorList = []
    
    if not in_dir:
        errorList.append("option --in is missing")
    if not out_dir:
        errorList.append("option --out is missing")
    # Creating a list for log messages
    logList = []

    if not errorList:  
        if not os.path.isfile (in_dir+"/alternatives.xml"):
            errorList.append("alternatives.xml is missing")
        if not os.path.isfile (in_dir+"/preferenceRelation.xml"):
            errorList.append("preferenceRelation.xml is missing")
        if not os.path.isfile (in_dir+"/alternativesAffectations.xml"):
            errorList.append("alternativesAffectations.xml is missing")
        if not os.path.isfile (in_dir+"/clustersRelations.xml"):
            errorList.append("clustersRelations.xml is missing")

    if not errorList:
        # We parse all the mandatory input files
        xmltree_alternatives = PyXMCDA.parseValidate(in_dir+"/alternatives.xml")
        xmltree_preferenceRelation = PyXMCDA.parseValidate(in_dir+"/preferenceRelation.xml")
        xmltree_alternativesAffectations = PyXMCDA.parseValidate(in_dir+"/alternativesAffectations.xml")
        xmltree_clustersRelations = PyXMCDA.parseValidate(in_dir+"/clustersRelations.xml")
        
        # We check if all mandatory input files are valid
        if xmltree_alternatives == None :
            errorList.append("alternatives.xml can't be validated.")
        if xmltree_preferenceRelation == None :
            errorList.append("preferenceRelation.xml can't be validated.")
        if xmltree_alternativesAffectations == None :
            errorList.append("alternativesAffectations.xml can't be validated.")
        if xmltree_clustersRelations == None :
            errorList.append("clustersRelations.xml can't be validated.")
            
        if not errorList :

            alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
            alternativesRel = PyXMCDA.getAlternativesComparisonsValues(xmltree_preferenceRelation, alternativesId)
            
            if not alternativesId :
                errorList.append("No active alternatives found.")
            if not alternativesRel :
                errorList.append("Problems between relation and alternatives.")
            missing_eval = False
            for o in alternativesId:
                if not (o in alternativesRel):
                    missing_eval = True
                    break
                else:
                    for p in alternativesId:
                        if not (p in alternativesRel[o]):
                            missing_eval = True
                            break
                        else:
                            if not ('i' in alternativesRel[o][p]):
                                missing_eval = True
                                break
                            if not ('p+' in alternativesRel[o][p]):
                                missing_eval = True
                                break
                            if not ('p-' in alternativesRel[o][p]):
                                missing_eval = True
                                break
                            if not ('j' in alternativesRel[o][p]):
                                missing_eval = True
                                break
            if missing_eval:
                errorList.append("Not all alternatives from alternatives.xml contain evaluations in preferenceRelation.xml, or evaluations are incomplete. Possible inputs from different sources")
                
            alternativesAffectations = PyXMCDA.getAlternativesAffectations(xmltree_alternativesAffectations)
            Knames = []
            for o in alternativesId:
                clusterId = alternativesAffectations[o]
                if not (clusterId in Knames):
                    Knames.append(clusterId)
            
            if Knames == []:
                errorList.append("No clusters found.")
                
            K = {}
            for clusterId in Knames:
                K[clusterId] = []
            for o in alternativesId:
                K[alternativesAffectations[o]].append(o)
                
            clustersRel = PyXMCDA.getCategoriesComparisonsValues(xmltree_clustersRelations, Knames)
            
            if not clustersRel :
                errorList.append("Problems with clusters relations.")
                
            RK = {}
            for cid1 in Knames:
                RK[cid1] = {}
                for cid2 in Knames:
                    if cid1 == cid2:
                        RK[cid1][cid2] = 'i'
                    else:
                        RK[cid1][cid2] = ''
            missing_eval = False
            for cid1 in Knames:
                for cid2 in Knames:
                    if cid1 != cid2:
                        found = False
                        if cid1 in clustersRel:
                            if cid2 in clustersRel[cid1]:
                                found = True
                                RK[cid1][cid2] = clustersRel[cid1][cid2]
                                if clustersRel[cid1][cid2] == 'p+':
                                    RK[cid2][cid1] = 'p-'
                                elif clustersRel[cid1][cid2] == 'p-':
                                    RK[cid2][cid1] = 'p+'
                                else:
                                    RK[cid2][cid1] = clustersRel[cid1][cid2]
                        if not found and cid2 in clustersRel:
                            if cid1 in clustersRel[cid2]:
                                found = True
                                RK[cid2][cid1] = clustersRel[cid2][cid1]
                                if clustersRel[cid2][cid1] == 'p+':
                                    RK[cid1][cid2] = 'p-'
                                elif clustersRel[cid2][cid1] == 'p-':
                                    RK[cid1][cid2] = 'p+'
                                else:
                                    RK[cid1][cid2] = clustersRel[cid2][cid1]
                        if not found:
                            missing_eval = True
                            break
            if missing_eval:
                errorList.append("Incomplete clusters relations. Each pair needs an evaluation.")


        if not errorList :
            E = MccEval(alternativesId, alternativesRel, Knames, K, RK)
            o_nr,o_r,o_t,o_q = E.GetPerformances()
            
            logList.append("%.2f %% (%d/%d) relations in accordance to the Non-Relational Clustering problematic"%(200*o_nr/len(alternativesId)/(len(alternativesId) - 1),o_nr,len(alternativesId)*(len(alternativesId) - 1)/2))
            logList.append("%.2f %% (%d/%d) relations in accordance to the Relational Clustering problematic"%(200*o_r/len(alternativesId)/(len(alternativesId) - 1),o_r,len(alternativesId)*(len(alternativesId) - 1)/2))
            logList.append("%d cycles detected"%(o_t))
            logList.append("%d relations in discordance to the {p+,p-}-exclusivity property"%(o_q))                    

        if not errorList :
	    # Output results, results.xml
            output = open(out_dir+"/results.xml", 'w')
            PyXMCDA.writeHeader (output)
            PyXMCDA.writeLogMessages (output, logList)
	    PyXMCDA.writeFooter(output)
            output.close()

        # Creating log and error file, messages.xml
        fileMessages = open(out_dir+"/messages.xml", 'w')
        PyXMCDA.writeHeader (fileMessages)

        if not errorList :
            PyXMCDA.writeLogMessages (fileMessages, ["Execution ok"])
        else :
            PyXMCDA.writeErrorMessages (fileMessages, errorList)

        PyXMCDA.writeFooter(fileMessages)
        fileMessages.close()
Пример #48
0
def main(argv=None):

    if argv is None:
        argv = sys.argv

    parser = OptionParser()

    parser.add_option("-i", "--in", dest="in_dir")
    parser.add_option("-o", "--out", dest="out_dir")

    (options, args) = parser.parse_args(argv[1:])

    in_dir = options.in_dir
    out_dir = options.out_dir

    # Creating a list for error messages
    errorList = []

    if not os.path.isfile(in_dir + "/alternatives.xml"):
        errorList.append("alternatives.xml is missing")
    if not os.path.isfile(in_dir + "/relation.xml"):
        errorList.append("relation.xml is missing")
    if not os.path.isfile(in_dir + "/parameters.xml"):
        errorList.append("parameters.xml is missing")

    if not errorList:
        # We parse all the mandatory input files
        xmltree_alternatives = PyXMCDA.parseValidate(in_dir +
                                                     "/alternatives.xml")
        xmltree_relation = PyXMCDA.parseValidate(in_dir + "/relation.xml")
        xmltree_parameters = PyXMCDA.parseValidate(in_dir + "/parameters.xml")

        # We check if all madatory input files are valid
        if xmltree_alternatives == None:
            errorList.append("alternatives.xml can't be validated.")
        if xmltree_relation == None:
            errorList.append("relation.xml can't be validated.")
        if xmltree_parameters == None:
            errorList.append("parameters.xml can't be validated.")

        if not errorList:

            alternativesId = PyXMCDA.getAlternativesID(xmltree_alternatives)
            alternativesRel = PyXMCDA.getAlternativesComparisons(
                xmltree_relation, alternativesId)
            relationMin = PyXMCDA.getParameterByName(xmltree_parameters, "min")
            relationMax = PyXMCDA.getParameterByName(xmltree_parameters, "max")
            relationCut = PyXMCDA.getParameterByName(xmltree_parameters, "cut")
            relationBipolar = PyXMCDA.getParameterByName(
                xmltree_parameters, "bipolar")

            if not alternativesId:
                errorList.append("No active alternatives found.")
            if not alternativesRel:
                errorList.append("Problems between relation and alternatives.")
            if relationMin is None:
                errorList.append("No \'min\' method parameter found")
            if relationMax is None:
                errorList.append("No \'max\' method parameter found")
            if relationCut is None:
                errorList.append("No \'cut\' method parameter found")
            if relationBipolar is None:
                errorList.append("No \'bipolar\' method parameter found")

        if not errorList:

            alg = algMccP(alternativesId, alternativesRel, relationMin,
                          relationMax, relationCut, relationBipolar)
            results = alg.Run()

            fo = open(out_dir + "/output.xml", 'w')
            PyXMCDA.writeHeader(fo)
            fo.write('<alternativesAffectations>\n')
            for o in results:
                fo.write('\t<alternativeAffectation>\n\t\t<alternativeID>' +
                         o + '</alternativeID>\n\t\t\t<categoryID>' +
                         results[o] +
                         '</categoryID>\n\t</alternativeAffectation>\n')
            fo.write('</alternativesAffectations>')
            PyXMCDA.writeFooter(fo)
            fo.close()

        # Creating log and error file, messages.xml
        fileMessages = open(out_dir + "/messages.xml", 'w')
        PyXMCDA.writeHeader(fileMessages)

        if not errorList:
            PyXMCDA.writeLogMessages(fileMessages, ["Execution ok"])
        else:
            PyXMCDA.writeErrorMessages(fileMessages, errorList)

        PyXMCDA.writeFooter(fileMessages)
        fileMessages.close()
Пример #49
0
 def get_alternatives(*args, **kwargs):
     alternatives = px.getAlternativesID(trees['alternatives'])
     return alternatives  # list