IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

2-SAT problem papadimitriou's algorithm


Sujet :

C++

  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 126
    Par défaut 2-SAT problem papadimitriou's algorithm
    Bonjour tout le monde, je voudrais remercier par avance tous ceux qui m'aideront avec mon problème.

    Voilà j'essaie d'implémenter l'algorithme de Papadimitriou pour résoudre le "2SAT" problem.

    A l'heure actuelle j'ai décidé comme conseillé de réaliser un travail préliminaire sur les données pour réduire la taille du problème. En effet le fichier est donné sous la forme suivante :
    -x1 x2
    x3 x4
    -x5 -x6
    ...
    ...

    chaque fois qu'il y a un - cela signifie "non" (logique puisque les variables xi sont booléennes).

    Le travail préliminaire est le suivant : en lisant le fichier je stock les variables précédées du - dans un std::set<long int> negations et les autres dans un std::set<long int> variables

    Ensuite je parcours le set de variables et je regarde si chaque variable est aussi présente dans le set de négations (si ce n'est pas le cas les contraintes qui impliquent la variable en question peuvent etre supprimées du probleme donc les boucles ultérieures sur ces contraintes seront bcp moins longues).

    Ce qui m'interpelle c'est le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void simplify_problem(problem& prob) {
    	for(auto e = prob.variable_iterator(); e!= prob.no_more_variable(); ++e){
    		if(prob.get_negations().find(*e) == prob.no_more_negation()){
    			prob.remove_variable(*e);
    		}
    	}
    }
    il est extrêmement long à executer et pourtant je ne fais pas encore tout le travail que je devrais (à savoir supprimer les contraintes et faire la même chose mais cette fois ci en parcourant le set de négations).

    Mes sets contiennent environ 65 000 valeurs, j'ai regardé et itérer sur ces sets en affichant les valeurs prend à peine 1 sec, tandis que ma fonction prend plusieurs minutes. Je sais que la fonction "find" a une complexité logarithmic (donc log 65000 soit < 5) et donc je comprends que ce soit plus long, mais à mon sens ça ne devrait pas être à ce point plus long.

    Quelqu'un a une idée de ce qui ralentit mon programme ? merci infiniment

  2. #2
    Membre émérite
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Par défaut
    Déjà, il faudrait l'implémentation de "problem" pour avoir une certitude.

    Mais, si prob.remove_variable se contentait d'appeler (avec des noms de variables fictifs) variable_set.erase(variable_set.find(param)), alors tu aurais un problème dans ton code : e serait un itérateur sur variable_set, qui serait de fait invalidé par l'appel à remove_variable. Ce qui serait donc, si je me souviens bien, UB.

    Cependant, ce ne sont que des suppositions tant que tu ne donnes pas l'implémentation de la classe "problem".

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 126
    Par défaut
    Voilà le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    class problem {
     
    private:
    	typedef std::map<Couple, clause, couple_compare> myClauses;
    	myClauses clauses;
     
    	typedef std::set<long int> myVariables;
    	myVariables variables;
     
    	typedef std::set<long int> myNegations;
    	myNegations negations;
     
    public:
    	void create_clause(variable var_1, variable var_2, bool clause_) {
    		Couple couple;
    		couple.variab1 = var_1.get_variable();
    		couple.variab2 = var_2.get_variable();
    		clauses.insert(std::make_pair(couple, clause(var_1, var_2, clause_)));
    	}
     
    	void create_variable(long int var) {variables.insert(var);};clauses
    	void create_negation(long int neg) {negations.insert(neg);};
    	void remove_variable(long int var) {variables.erase(var);};
    	void remove_negation(long int neg) {negations.erase((neg));};
    	void remove_clause(long int variable) {}
     
    	myClauses get_clauses() {return clauses;};
    	myVariables get_variables() {return variables;};
    	myNegations get_negations() {return negations;};
     
    	std::map<Couple, clause, couple_compare>::iterator clause_iterator() {return clauses.begin();};
    	std::map<Couple, clause, couple_compare>::iterator noClause() {return clauses.end();};
     
    	std::set<long int>::iterator variable_iterator() {return variables.begin();};
    	std::set<long int>::iterator no_more_variable() {return variables.end();};
     
    	std::set<long int>::iterator negation_iterator() {return negations.begin();};
    	std::set<long int>::iterator no_more_negation() {return negations.end();};
    };
    Merci de ton intérêt ! Je suis désolé mais je ne comprends pas trop le problème je crois avoir fait comme ici http://www.cplusplus.com/reference/set/set/erase/

    Aurais-tu une alternative ?

  4. #4
    Membre émérite
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Par défaut
    Si tu regardes bien, dans la section "Iterator validity", il y a ce message :

    Iterators, pointers and references referring to elements removed by the function are invalidated.
    All other iterators, pointers and references keep their validity.
    Ce qui signifie que, après l'appel à prob.remove_variable(*e), tout itérateur qui pointe sur *e dans le set variables est invalidé. Or e est un itérateur qui pointe sur *e, et qui est dans le set variables.

    Ainsi, l'itérateur e est invalidé par l'appel à prob.remove_variable. Ce qui signifie qu'il ne devrait plus être utilisé.

    Étant donné que tu utilises un set et non un multiset ; et que donc chaque valeur n'apparait qu'une fois dans le set, une correction pourrait être de copier l'itérateur puis de l'incrémenter avant d'effacer, puis de décrémenter, mais ceci pourrait causer problème si jamais on était en bord de set.

    Alors, afin d'éliminer l'UB (Undefined Behaviour), je pense que l'idéal serait de rajouter une fonction à problem du genre "remove_variable_from_iterator" ; qui supprimerait une variable à partir de l'itérateur et qui retournerait le retour de erase (nécessite de compiler avec c++11). (Ceci n'expose pas plus l'implémentation qu'auparavant, étant donné que des itérateurs sont déjà fournis par d'autres fonctions.)

    La boucle for deviendrait alors ceci (non testé) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void simplify_problem(problem& prob) {
    	for(auto e = prob.variable_iterator(); e!= prob.no_more_variable(); ){
    		if(prob.get_negations().find(*e) == prob.no_more_negation()){
    			e = prob.remove_variable_from_iterator(e);
    		} else {
    			++e;
    		}
    	}
    }

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 126
    Par défaut
    Hey merci de ton aide Ekleog. Malheureusement cela ne fonctionne pas, j'ai codé la fonction comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::set<long int>::iterator remove_variable_by_iterator(std::set<long int>::iterator it) {variables.erase(it); return it;};
    et j'ai écris ensuite comme toi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void simplify_problem(problem& prob) {
    	for(auto e = prob.variable_iterator(); e!= prob.no_more_variable(); ++e){
    		if(prob.get_negations().find(*e) == prob.no_more_negation()){
    			e = prob.remove_variable_by_iterator(e);
    		}
    		else
    			++e;
    	}
    }
    Je vous mets le code en entier au cas où :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    #include <iostream>
    #include <fstream>
    #include <set>
    #include <string>
    #include <sstream>
    #include <utility>
    #include <algorithm>
    #include <map>
     
     
    class variable {
     
    private:
    	long int var;
    	bool checked;
     
    public:
    	long int get_variable() {return var;};
    	bool isChecked() {return checked;};
    	void setChecked(bool boolean) {checked = boolean;};
    	variable(long int var_, bool checked_) : var(var_), checked(checked_) {}
     
     
    };
     
    class clause {
     
    private:
    	variable var_1;
    	variable var_2;
    	bool expression;
     
    public:
    	bool verified() {return expression;};
    	variable getFirstVar() const {return var_1;};
    	variable getSecondVar() const {return var_2;};
    	clause(variable var_1_, variable var_2_, bool clause_) : var_1(var_1_), var_2(var_2_), expression(clause_) {}
     
    };
     
    class problem {
     
    private:
    	typedef std::map<long int, std::map<long int, clause>> myClauses;
    	myClauses clauses;
     
    	typedef std::set<long int> myVariables;
    	myVariables variables;
     
    	typedef std::set<long int> myNegations;
    	myNegations negations;
     
    public:
    	void create_clause(variable var_1, variable var_2, bool clause_) {
    		clauses[var_1.get_variable()].insert(std::make_pair(var_2.get_variable(), clause(var_1, var_2, clause_)));
    		clauses[var_2.get_variable()].insert(std::make_pair(var_1.get_variable(), clause(var_1, var_2, clause_)));
    	}
     
    	void create_variable(long int var) {variables.insert(var);};
    	void create_negation(long int neg) {negations.insert(neg);};
    	void remove_variable(long int var) {variables.erase(var);};
    	std::set<long int>::iterator remove_variable_by_iterator(std::set<long int>::iterator it) {variables.erase(it); return it;};
    	void remove_negation(long int neg) {negations.erase((neg));};
    	void remove_clause(long int variable) {}
     
    	myClauses get_clauses() {return clauses;};
    	myVariables get_variables() {return variables;};
    	myNegations get_negations() {return negations;};
     
    	std::map<long int, std::map<long int, clause>>::iterator map_iterator() {return clauses.begin();};
    	std::map<long int, std::map<long int, clause>>::iterator noMap() {return clauses.end();};
     
    	std::map<long int, clause>::iterator clause_iterator(std::map<long int, clause> m) {return m.begin();};
    	std::map<long int, clause>::iterator noClause(std::map<long int, clause> m) {return m.end();};
     
    	std::set<long int>::iterator variable_iterator() {return variables.begin();};
    	std::set<long int>::iterator no_more_variable() {return variables.end();};
     
    	std::set<long int>::iterator negation_iterator() {return negations.begin();};
    	std::set<long int>::iterator no_more_negation() {return negations.end();};
    };
     
    problem parse(const char* filename) {
    	problem prob;
     
    	std::string line;
    	std::ifstream fichier(filename);
     
    	getline(fichier, line);
     
    	while(std::getline(fichier, line)){
    		std::istringstream iss(line);
     
    		long int var1, var2;
     
    		iss >> var1 >> var2;
     
    		variable variable1(abs(var1), true);
    		variable variable2(abs(var2), true);
     
    		if(var1 < 0 and var2 > 0) {	
    			prob.create_clause(variable1, variable2, !variable1.isChecked() || variable2.isChecked());
    			prob.create_negation(abs(var1));
    			prob.create_variable(var2);
    		}
    		else if(var1 < 0 and var2 < 0) {
    			prob.create_clause(variable1, variable2, !variable1.isChecked() || !variable2.isChecked());
    			prob.create_negation(abs(var1));
    			prob.create_negation(abs(var2));
    		}
    		else if(var1 > 0 and var2 < 0) {
    			prob.create_clause(variable1, variable2, variable1.isChecked() || !variable2.isChecked());
    			prob.create_variable(var1);
    			prob.create_negation(abs(var2));
    		}
    		else {
    			prob.create_clause(variable1, variable2, variable1.isChecked() || variable2.isChecked());
    			prob.create_variable(var1);
    			prob.create_variable(var2);
    		}
    	}
     
    	return prob;
    }
     
    void simplify_problem(problem& prob) {
    	for(auto e = prob.variable_iterator(); e!= prob.no_more_variable(); ++e){
    		std::cout << *e << std::endl;
    		if(prob.get_negations().find(*e) == prob.no_more_negation()){
    			std::cout << "yo   " << *e << std::endl;
    			e = prob.remove_variable_by_iterator(e);
    		}
    		else
    			++e;
    	}
    }
     
    int main(int argc, char* argv[]) {
     
    	problem prob = parse("2sat1.txt");
     
    	for(auto e = prob.map_iterator(); e!= prob.noMap(); ++e){
    		for(auto el = prob.clause_iterator(e->second); el!= prob.noClause(e->second); ++el)
    			std::cout << el->second.getFirstVar().get_variable() << " - " << el->second.getSecondVar().get_variable() << " ; " << el->second.verified() << std::endl;		
    	}
     
    	std::cout << prob.get_variables().size() << std::endl;
    	std::cout << prob.get_negations().size() << std::endl;
    	/*for(auto e = prob.negation_iterator(); e!=prob.no_more_negation(); ++e){
    		std::cout << *e << std::endl;
    	}*/
    	simplify_problem(prob);
     
    	std::cout << *(prob.get_variables().find(3)) << std::endl;
    	std::cout << *(prob.get_negations().find(3)) << std::endl;
     
    	return 0;
    }
     
    /*
    Make lists of all variables and negations. 
    If there is a variable that appears in one list but not the other then remove that variable
    from the list it does appear in and all clauses containing that variable from the list of clauses. 
    If you want to keep track of what to set it to (I didn't, but wish I had and may go back and code it in) 
    then set the value for any variable that appears without negation to T and any that only appears negated to F.
    Do this repeatedly until you reach a loop with no deletions.  Remember to rebuild the lists of variables and 
    negations each time through (this is what I forgot to do when I coded it up in the wee hours of the morning).
     
     
     
    Basically instead of looping over all clauses just loop over failing ones and flip values there.
    So you need to maintain linked list of failing clauses and additionally dictionary of clauses indexed by variable 
    (use simple array for that). Every time algorithm flips the variable you only re-evaluate clauses in which this variable appears, 
    updating linked list of failing clauses accordingly. 
    */
    Par ailleurs en utilisant des std::cout j'ai remarqué que je n'entrais jamais dans la boucle if ce qui n'est pas possible compte-tenu de mes données. Quelqu'un aurait-il une idée concernant l'un ou l'autre de mes problèmes ? Merci à tous

  6. #6
    Membre émérite
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Par défaut
    En fait, dans remove_variable_by_iterator, il devrait y avoir return variables.erase(it);.

    Ceci devrait résoudre au moins le problème qui surviendrait si on entrait dans le if.

    Après, je ne vois pas pourquoi tu ne rentrerais pas dans le if.

    Par contre, par une lecture rapide de parse, je me demandais : as-tu bien traité le cas où var1 == 0 ou var2 == 0 ?

  7. #7
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2014
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2014
    Messages : 126
    Par défaut
    Hey merci de ton aide ! Désolé j'aurais du te le dire mais dans mes fichiers je n'ai pas de variable 0 donc je n'ai pas besoin de traiter ces cas. Je te reposte mon code car j'ai bien progressé : j'ai réussi à rentrer dans la boucle if et à simplifier mon problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    #include <iostream>
    #include <fstream>
    #include <set>
    #include <string>
    #include <sstream>
    #include <utility>
    #include <algorithm>
    #include <map>
     
     
    class variable {
     
    private:
    	long int var;
    	bool checked;
     
    public:
    	long int get_variable() {return var;};
    	bool isChecked() {return checked;};
    	void setChecked(bool boolean) {checked = boolean;};
    	variable(long int var_, bool checked_) : var(var_), checked(checked_) {}
     
     
    };
     
    class clause {
     
    private:
    	variable var_1;
    	variable var_2;
    	bool expression;
     
    public:
    	bool verified() {return expression;};
    	variable getFirstVar() const {return var_1;};
    	variable getSecondVar() const {return var_2;};
    	clause(variable var_1_, variable var_2_, bool clause_) : var_1(var_1_), var_2(var_2_), expression(clause_) {}
     
    };
     
    class problem {
     
    private:
    	typedef std::map<long int, std::map<long int, clause>> myClauses;
    	myClauses clauses;
     
    	typedef std::set<long int> myVariables;
    	myVariables variables;
     
    	typedef std::set<long int> myNegations;
    	myNegations negations;
     
    public:
    	void create_clause(variable var_1, variable var_2, bool clause_) {
    		clauses[var_1.get_variable()].insert(std::make_pair(var_2.get_variable(), clause(var_1, var_2, clause_)));
    	}
    	void remove_clauses(long int var_1){
    		clauses.erase(var_1);
    	}
     
    	void create_variable(long int var) {variables.insert(var);};
    	void create_negation(long int neg) {negations.insert(neg);};
    	void remove_variable(long int var) {variables.erase(var);};
    	std::set<long int>::iterator remove_variable_by_iterator(std::set<long int>::iterator it) {return variables.erase(it);};
    	std::set<long int>::iterator remove_negation_by_iterator(std::set<long int>::iterator it) {return negations.erase(it);};
    	void remove_negation(long int neg) {negations.erase((neg));};
    	void remove_clause(long int variable) {clauses.erase(variable);};
     
    	myClauses get_clauses() {return clauses;};
    	myVariables get_variables() {return variables;};
    	myNegations get_negations() {return negations;};
     
    	bool contains_var(long int var) {if(variables.find(var) != no_more_variable()) return true; else return false;};
    	bool contains_neg(long int neg) {if(negations.find(neg) != no_more_negation()) return true; else return false;};
     
    	std::map<long int, std::map<long int, clause>>::iterator map_iterator() {return clauses.begin();};
    	std::map<long int, std::map<long int, clause>>::iterator noMap() {return clauses.end();};
     
    	std::map<long int, clause>::iterator clause_iterator(std::map<long int, clause> m) {return m.begin();};
    	std::map<long int, clause>::iterator noClause(std::map<long int, clause> m) {return m.end();};
     
    	std::set<long int>::iterator variable_iterator() {return variables.begin();};
    	std::set<long int>::iterator no_more_variable() {return variables.end();};
     
    	std::set<long int>::iterator negation_iterator() {return negations.begin();};
    	std::set<long int>::iterator no_more_negation() {return negations.end();};
    };
     
    problem parse(const char* filename) {
    	problem prob;
     
    	std::string line;
    	std::ifstream fichier(filename);
     
    	getline(fichier, line);
     
    	while(std::getline(fichier, line)){
    		std::istringstream iss(line);
     
    		long int var1, var2;
     
    		iss >> var1 >> var2;
     
    		variable variable1(abs(var1), true);
    		variable variable2(abs(var2), true);
     
    		if(var1 < 0 and var2 > 0) {	
    			prob.create_clause(variable1, variable2, !variable1.isChecked() || variable2.isChecked());
    			prob.create_negation(abs(var1));
    			prob.create_variable(var2);
    		}
    		else if(var1 < 0 and var2 < 0) {
    			prob.create_clause(variable1, variable2, !variable1.isChecked() || !variable2.isChecked());
    			prob.create_negation(abs(var1));
    			prob.create_negation(abs(var2));
    		}
    		else if(var1 > 0 and var2 < 0) {
    			prob.create_clause(variable1, variable2, variable1.isChecked() || !variable2.isChecked());
    			prob.create_variable(var1);
    			prob.create_negation(abs(var2));
    		}
    		else {
    			prob.create_clause(variable1, variable2, variable1.isChecked() || variable2.isChecked());
    			prob.create_variable(var1);
    			prob.create_variable(var2);
    		}
    	}
     
    	return prob;
    }
     
    int simplify_problem(problem& prob) {
    	int nb_deletions(0);
    	for(auto e = prob.variable_iterator(); e!= prob.no_more_variable(); ++e){
    		if(!prob.contains_neg(*e)){
    			std::set<long int>::iterator v = prob.remove_variable_by_iterator(e);
    			prob.remove_clause(*e);
    			nb_deletions++;
    		}
    	}
    	for(auto e = prob.negation_iterator(); e!= prob.no_more_negation(); ++e){
    		if(!prob.contains_var(*e)){
    			std::set<long int>::iterator v = prob.remove_negation_by_iterator(e);
    			prob.remove_clause(*e);
    			nb_deletions++;
    		}
    	}
    	return nb_deletions;
    }
     
    int main(int argc, char* argv[]) {
     
    	problem prob = parse("2sat1.txt");
     
    	/*for(auto e = prob.map_iterator(); e!= prob.noMap(); ++e){
    		for(auto el = prob.clause_iterator(e->second); el!= prob.noClause(e->second); ++el)
    			std::cout << el->second.getFirstVar().get_variable() << " - " << el->second.getSecondVar().get_variable() << " ; " << el->second.verified() << std::endl;		
    	}*/
     
    	std::cout << prob.get_variables().size() << " nb var " << std::endl;
    	std::cout << prob.get_negations().size() << " nb neg " << std::endl;
    	std::cout << prob.get_clauses().size() << " nb clauses " << std::endl;
    	/*for(auto e = prob.negation_iterator(); e!=prob.no_more_negation(); ++e){
    		std::cout << *e << std::endl;
    	}*/
    	int nb_deletions(-1);
    	while(nb_deletions != 0){
    		nb_deletions = simplify_problem(prob);
    	}
     
    	std::cout << prob.get_variables().size() << " nb var " << std::endl;
    	std::cout << prob.get_negations().size() << " nb neg " << std::endl;
    	std::cout << prob.get_clauses().size() << " nb clauses " << std::endl;
    	return 0;
    }
     
    /*
    Make lists of all variables and negations. 
    If there is a variable that appears in one list but not the other then remove that variable
    from the list it does appear in and all clauses containing that variable from the list of clauses. 
    If you want to keep track of what to set it to (I didn't, but wish I had and may go back and code it in) 
    then set the value for any variable that appears without negation to T and any that only appears negated to F.
    Do this repeatedly until you reach a loop with no deletions.  Remember to rebuild the lists of variables and 
    negations each time through (this is what I forgot to do when I coded it up in the wee hours of the morning).
     
     
     
    Basically instead of looping over all clauses just loop over failing ones and flip values there.
    So you need to maintain linked list of failing clauses and additionally dictionary of clauses indexed by variable 
    (use simple array for that). Every time algorithm flips the variable you only re-evaluate clauses in which this variable appears, 
    updating linked list of failing clauses accordingly. 
    */
    Maintenant si tu es toujours motivé pour m'aider (dans le cas contraire je ne t'en voudrais pas :p) j'ai une nouvelle énigme pour toi...

    Avec le code que je t'ai posté ci dessus (et tu peux dailleurs le faire tourner avec -Wall -std=c++11 si tu en as envie). J'arrive à supprimer des éléments du set variables et du set négations mais je n'arrive pas à supprimer mes clauses...(contraintes).

    Au temps pour moi, j'y suis parvenu....mais je n'en ai pas supprimé suffisamment. Je reposterai si jamais j'ai d'autres ennuis, en attendant je marque le problème résolu. Merci de ton aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. probleme traduction d'algorithme de tri
    Par flyzi dans le forum Débuter avec Java
    Réponses: 5
    Dernier message: 24/02/2009, 17h51
  2. probleme avec un algorithme
    Par Zac EFRON dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 18/11/2008, 14h19
  3. Probleme avec mon algorithme de tri
    Par kaygee dans le forum Langage
    Réponses: 6
    Dernier message: 09/01/2006, 21h23
  4. Probleme avec un algorithme
    Par vodevil dans le forum Langage
    Réponses: 2
    Dernier message: 20/11/2005, 01h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo