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()
def create_ampl_reverse_data (file, altId, critId, perfTable, altComparisons, thresholds, maxWeight, criComparisons, criLB, criUB, criIndLB, criIndUB, criPreLB, criPreUB) : #Les contraintes du style g_i > g_j for crit in critId : file.write('set cr_'+crit+' := {"'+crit+'"};\n') #Un compteur pour numeroter les contraintes et les ensembles count = 1 for comp in criComparisons : # On ecrit l'ensemble des neuds initiaux file.write('\nset crs_init_'+str(count)+' := {') file.write(PyXMCDA.getListOnString (comp["initial"], '"', '"', ', ')) file.write('};\n') # On ecrit l'ensemble des noeuds terminaux file.write('set crs_term_'+str(count)+' := {') file.write(PyXMCDA.getListOnString (comp["terminal"], '"', '"', ', ')) file.write('};\n') file.write("s.t. ct_comp_"+str(count)+" : sum{init in crs_init_"+str(count)+"} sum {k in WEIGHTUNIT} Accumulator[init,k] >= sum{term in crs_term_"+str(count)+"} sum {k in WEIGHTUNIT} Accumulator[term,k] +1;\n") count = count + 1 #Les contraintes du style g_i > lower_bound_i file.write("\n") for crit in criLB.keys() : file.write("s.t. ct_LB_"+crit+"{j in cr_"+crit+"} : sum {k in WEIGHTUNIT} Accumulator[j,k] >= "+str(criLB[crit])+";\n") #Les contraintes du style g_i < upper_bound_i file.write("\n") for crit in criUB.keys() : file.write("s.t. ct_UB_"+crit+"{j in cr_"+crit+"} : sum {k in WEIGHTUNIT} Accumulator[j,k] <= "+str(criUB[crit])+";\n") #Les contraintes du style q_i > lower_bound_i file.write("\n") for crit in criIndLB.keys() : file.write("s.t. ct_q_LB_"+crit+"{j in cr_"+crit+"} : " + str(criIndLB[crit]) + " <= q[j];\n") #Les contraintes du style q_i < upper_bound_i file.write("\n") for crit in criIndUB.keys() : file.write("s.t. ct_q_UB_"+crit+"{j in cr_"+crit+"} : q[j] <= " + str(criIndUB[crit]) + ";\n") #Les contraintes du style p_i > lower_bound_i file.write("\n") for crit in criPreLB.keys() : file.write("s.t. ct_p_LB_"+crit+"{j in cr_"+crit+"} : " + str(criPreLB[crit]) + " <= p[j];\n") #Les contraintes du style p_i < upper_bound_i file.write("\n") for crit in criPreUB.keys() : file.write("s.t. ct_p_UB_"+crit+"{j in cr_"+crit+"} : p[j] <= " + str(criPreUB[crit]) + ";\n") file.write ("\n\n\ndata;\n\n") file.write ("set CRITERIA := ") for c in critId : file.write (c+" ") file.write(";\n\n") pairs2 = [] pairsm2 = [] pairs1 = [] pairsm1 = [] tabVeto = PyXMCDA.getVetos (altId, critId, perfTable, thresholds) for init in altComparisons.keys() : for term in altComparisons[init].keys() : if tabVeto.has_key(init) and tabVeto[init].has_key(term) and not tabVeto[init][term] is None : # Veto situation continue if init != term : val = altComparisons[init][term] if val == 2 : pairs2.append (""+init+term) elif val == -2 : pairsm2.append (""+init+term) elif val == 1 : pairs1.append (""+init+term) elif val == -1 : pairsm1.append (""+init+term) else: # On met une valeur pour dire que l'on n'a pas pris en compte cette valeur altComparisons[init][term] = 0 file.write ("set ROBUSTPREFPAIRS :=\n") count = 0 for pair in pairs2 : count = count + 1 file.write (pair+" ") if count == 10 : count = 0 file.write ("\n") file.write (";\n\nset ROBUSTnotPREFPAIRS :=\n") count = 0 for pair in pairsm2 : count = count + 1 file.write (pair+" ") if count == 10 : count = 0 file.write ("\n") file.write (";\n\nset SIMPLEPREFPAIRS :=\n") count = 0 for pair in pairs1 : count = count + 1 file.write (pair+" ") if count == 10 : count = 0 file.write ("\n") file.write (";\n\nset SIMPLEnotPREFPAIRS :=\n") count = 0 for pair in pairsm1 : count = count + 1 file.write (pair+" ") if count == 10 : count = 0 file.write ("\n") file.write(";\n\n") file.write ("param maxWeight := "+str(maxWeight)+";\n\n") # On ecrit le tableau de performance file.write("param Perf : ") for c in critId : file.write (c+" ") file.write (":=\n") for init in altComparisons.keys() : for term in altComparisons[init].keys() : if tabVeto.has_key(init) and tabVeto[init].has_key(term) and not tabVeto[init][term] is None: # Veto situation continue if altComparisons[init][term] == 0: continue if init != term : file.write (str(init)+str(term)+" ") for crit in critId : file.write(str(perfTable[init][crit] - perfTable[term][crit])+" ") file.write ("\n") file.write(";\n\n") # On ecrit l'ensemble des couples d'alt et des criteres pour lesquels la premiere alt performe mieux que la deuxieme sur le critere choisi (en gros, les surclassements ne dependant pas des seuils) # file.write ("param SureOut : ") # for c in critId : # file.write (c+" ") # file.write (":=\n") # for init in altComparisons.keys() : # for term in altComparisons[init].keys() : # # if tabVeto.has_key(init) and tabVeto[init].has_key(term) and not tabVeto[init][term] is None : # # Veto situation # continue # # if init != term : # file.write (str(init)+str(term)+" ") # for crit in critId : # if perfTable[init][crit] >= perfTable[term][crit]: # file.write ("1 ") # else: # file.write ("0 ") # file.write ("\n") # file.write(";\n\n") # Les valeurs max sur chaque critere, pour normaliser file.write("param MaxCrit [*] := \n") for c in critId : # On suppose les valeurs toutes positives !!!!!!!!! valMax = 0 for alt in altId: if perfTable[alt][c] > valMax: valMax = perfTable[alt][c] file.write (c+" "+str(valMax)+"\n") file.write (";\n\n")
def create_ampl_reverse_data (file, altId, critId, perfTable, altComparisons, thresholds, maxWeight, criComparisons, criLB, criUB) : #Les contraintes du style g_i > g_j for crit in critId : file.write('set cr_'+crit+' := {"'+crit+'"};\n') #Un compteur pour numeroter les contraintes et les ensembles count = 1 for comp in criComparisons : # On ecrit l'ensemble des neuds initiaux file.write('\nset crs_init_'+str(count)+' := {') file.write(PyXMCDA.getListOnString (comp["initial"], '"', '"', ', ')) file.write('};\n') # On ecrit l'ensemble des noeuds terminaux file.write('set crs_term_'+str(count)+' := {') file.write(PyXMCDA.getListOnString (comp["terminal"], '"', '"', ', ')) file.write('};\n') file.write("s.t. ct_comp_"+str(count)+" : sum{init in crs_init_"+str(count)+"} sum {k in WEIGHTUNIT} Accumulator[init,k] >= sum{term in crs_term_"+str(count)+"} sum {k in WEIGHTUNIT} Accumulator[term,k] +1;\n") count = count + 1 #Les contraintes du style g_i > lower_bound_i file.write("\n") for crit in criLB.keys() : file.write("s.t. ct_LB_"+crit+"{i in cr_"+crit+"} : sum {k in WEIGHTUNIT} Accumulator[i,k] >= "+str(criLB[crit])+";\n") #Les contraintes du style g_i < upper_bound_i file.write("\n") for crit in criUB.keys() : file.write("s.t. ct_UB_"+crit+"{i in cr_"+crit+"} : sum {k in WEIGHTUNIT} Accumulator[i,k] <= "+str(criUB[crit])+";\n") file.write ("\n\n\ndata;\n\n") file.write ("set CRITERIA := ") for c in critId : file.write (c+" ") file.write(";\n\nset ALLPAIRS :=\n") for a1 in altId : for a2 in altId : file.write (a1+a2+" ") file.write ("\n") file.write (";\n\n") pairs2 = [] pairsm2 = [] pairs1 = [] pairsm1 = [] tabVeto = PyXMCDA.getVetos (altId, critId, perfTable, thresholds) for init in altComparisons.keys() : for term in altComparisons[init].keys() : if tabVeto.has_key(init) and tabVeto[init].has_key(term) and not tabVeto[init][term] is None : # Veto situation continue if init != term : val = altComparisons[init][term] if val == 2 : pairs2.append (""+init+term) elif val == -2 : pairsm2.append (""+init+term) elif val == 1 : pairs1.append (""+init+term) elif val == -1 : pairsm1.append (""+init+term) file.write ("set ROBUSTPREFPAIRS :=\n") count = 0 for pair in pairs2 : count = count + 1 file.write (pair+" ") if count == 10 : count = 0 file.write ("\n") file.write (";\n\nset ROBUSTnotPREFPAIRS :=\n") count = 0 for pair in pairsm2 : count = count + 1 file.write (pair+" ") if count == 10 : count = 0 file.write ("\n") file.write (";\n\nset SIMPLEPREFPAIRS :=\n") count = 0 for pair in pairs1 : count = count + 1 file.write (pair+" ") if count == 10 : count = 0 file.write ("\n") file.write (";\n\nset SIMPLEnotPREFPAIRS :=\n") count = 0 for pair in pairsm1 : count = count + 1 file.write (pair+" ") if count == 10 : count = 0 file.write ("\n") file.write(";\n\n") file.write ("\nparam maxWeight := "+str(maxWeight)) file.write (";\nparam S : ") for c in critId : file.write (c+" ") file.write (":=\n") ElemOut = PyXMCDA.getRubisElementaryOutranking (altId, critId, perfTable, thresholds) for alt1 in altId : for alt2 in altId : file.write (str(alt1)+str(alt2)+" ") for crit in critId : file.write (str(ElemOut[alt1][alt2][crit])+" ") file.write ("\n") file.write(";\n")