summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy@asynk.ch>2022-03-25 17:14:18 +0100
committerJérémy Zurcher <jeremy@asynk.ch>2022-03-25 17:14:18 +0100
commit2412c08dcd6cb50e56355a2997e9f21d70da97b7 (patch)
tree807c445c390d2748b799b94306d59e9b131bdfac
parent701b6b88ac8258a5c21197bb726825e7592d762b (diff)
downloadcoursera-2412c08dcd6cb50e56355a2997e9f21d70da97b7.zip
coursera-2412c08dcd6cb50e56355a2997e9f21d70da97b7.tar.gz
Algorithms : complete 05-advanced_algorithms_and_complexity 03-np-completness
-rw-r--r--05-advanced_algorithms_and_complexity/03-np-completness/01-gsm_network/gsm_network.cpp39
-rw-r--r--05-advanced_algorithms_and_complexity/03-np-completness/02-cleaning_apartment/cleaning_apartment.cpp66
-rw-r--r--05-advanced_algorithms_and_complexity/03-np-completness/03-budget_allocation/budget_allocation.cpp59
3 files changed, 143 insertions, 21 deletions
diff --git a/05-advanced_algorithms_and_complexity/03-np-completness/01-gsm_network/gsm_network.cpp b/05-advanced_algorithms_and_complexity/03-np-completness/01-gsm_network/gsm_network.cpp
index 5eafa18..ff53c87 100644
--- a/05-advanced_algorithms_and_complexity/03-np-completness/01-gsm_network/gsm_network.cpp
+++ b/05-advanced_algorithms_and_complexity/03-np-completness/01-gsm_network/gsm_network.cpp
@@ -18,14 +18,39 @@ struct ConvertGSMNetworkProblemToSat {
edges(m)
{ }
+ static inline int var(int vertex, int color) { return vertex * 3 + color; }
+
void printEquisatisfiableSatFormula() {
- // This solution prints a simple satisfiable formula
- // and passes about half of the tests.
- // Change this function to solve the problem.
- cout << "3 2" << endl;
- cout << "1 2 0" << endl;
- cout << "-1 -2 0" << endl;
- cout << "1 -2 0" << endl;
+ vector<vector<int>> clauses;
+
+ // 1 color per vertex
+ for (int i = 0; i < numVertices; i++) {
+ // at least one var must be true
+ clauses.push_back({var(i, 1), var(i, 2), var(i, 3)}); // R || G || B
+ // both can't be true
+ clauses.push_back({-var(i, 1), -var(i, 2)}); // !R || !G
+ clauses.push_back({-var(i, 1), -var(i, 3)}); // !R || !B
+ clauses.push_back({-var(i, 2), -var(i, 3)}); // !B || !G
+ }
+
+ // 2 colors per edge
+ for (Edge e : edges) {
+ int from = e.from - 1;
+ int to = e.to - 1;
+ // both can't be true
+ clauses.push_back({-var(from, 1), -var(to, 1)}); // !R || !R
+ clauses.push_back({-var(from, 2), -var(to, 2)}); // !G || !G
+ clauses.push_back({-var(from, 3), -var(to, 3)}); // !B || !B
+ }
+
+ cout << clauses.size() << " " << numVertices * 3 << endl;
+ for (vector<int>& c : clauses) {
+ for (int v : c) {
+ cout << v << " ";
+ }
+ cout << "0" << endl;
+ }
+ cout << endl;
}
};
diff --git a/05-advanced_algorithms_and_complexity/03-np-completness/02-cleaning_apartment/cleaning_apartment.cpp b/05-advanced_algorithms_and_complexity/03-np-completness/02-cleaning_apartment/cleaning_apartment.cpp
index 5690be7..a205158 100644
--- a/05-advanced_algorithms_and_complexity/03-np-completness/02-cleaning_apartment/cleaning_apartment.cpp
+++ b/05-advanced_algorithms_and_complexity/03-np-completness/02-cleaning_apartment/cleaning_apartment.cpp
@@ -15,14 +15,66 @@ struct ConvertHampathToSat {
edges(m)
{ }
+ // matrix of vertices * vertices (+1 because 0 is reserved)
+ static inline int var(int v1, int v2, int n) { return 1 + v1 * n + v2; }
+
void printEquisatisfiableSatFormula() {
- // This solution prints a simple satisfiable formula
- // and passes about half of the tests.
- // Change this function to solve the problem.
- cout << "3 2" << endl;
- cout << "1 2 0" << endl;
- cout << "-1 -2 0" << endl;
- cout << "1 -2 0" << endl;
+ vector<vector<int>> clauses;
+ vector<int> cstrs;
+
+ for (int i = 0; i < numVertices; i++) {
+ // the vertex belongs to the path, matrix rows
+ cstrs.clear();
+ for (int j = 0; j < numVertices; j++)
+ cstrs.push_back(var(i, j, numVertices)); // (Xi0 || Xi1 || Xi2 ...)
+ clauses.push_back(cstrs);
+
+ // the vertex appears just once in the path
+ for (int j = 0; j < numVertices; j++) {
+ for (int k = j + 1; k < numVertices; k++)
+ clauses.push_back({-var(i, j, numVertices), -var(i, k, numVertices)}); // ( !Xij && !Xik )
+ }
+
+ // each position in the path has a vertex, matrix cols
+ cstrs.clear();
+ for (int j = 0; j < numVertices; j++)
+ cstrs.push_back(var(j, i, numVertices)); // (X0i || X1i || X2i ...)
+ clauses.push_back(cstrs);
+
+ // each position has only 1 vertex
+ for (int j = 0; j < numVertices; j++) {
+ for (int k = j + 1; k < numVertices; k++)
+ clauses.push_back({-var(j, i, numVertices), -var(k, i, numVertices)}); // ( !Xji && !Xki )
+ }
+
+ // if there is no ij edje, there is no Xik Xj(k+1) or Xjk Xi(k+1)
+ for (int j = i + 1; j < numVertices; j++) {
+ // would be much faster with an adjacent matrix
+ bool found = false;
+ for (Edge e : edges) {
+ if ((e.from == i+1 && e.to == j+1) || (e.from == j+1 && e.to == i+1)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // no v-w edge
+ for (int k = 0; k < (numVertices - 1); k++) {
+ clauses.push_back({-var(i, k, numVertices), -var(j, k + 1, numVertices)}); // ( !Xik && !Xj(k+1)
+ clauses.push_back({-var(j, k, numVertices), -var(i, k + 1, numVertices)}); // ( !Xjk && !Xi(k+1)
+ }
+ }
+ }
+ }
+
+ cout << clauses.size() << " " << numVertices * numVertices << endl;
+ for (vector<int>& c : clauses) {
+ for (int v : c) {
+ cout << v << " ";
+ }
+ cout << "0" << endl;
+ }
+ cout << endl;
}
};
diff --git a/05-advanced_algorithms_and_complexity/03-np-completness/03-budget_allocation/budget_allocation.cpp b/05-advanced_algorithms_and_complexity/03-np-completness/03-budget_allocation/budget_allocation.cpp
index d2bfc51..c97937b 100644
--- a/05-advanced_algorithms_and_complexity/03-np-completness/03-budget_allocation/budget_allocation.cpp
+++ b/05-advanced_algorithms_and_complexity/03-np-completness/03-budget_allocation/budget_allocation.cpp
@@ -12,13 +12,58 @@ struct ConvertILPToSat {
{}
void printEquisatisfiableSatFormula() {
- // This solution prints a simple satisfiable formula
- // and passes about half of the tests.
- // Change this function to solve the problem.
- cout << "3 2" << endl;
- cout << "1 2 0" << endl;
- cout << "-1 -2 0" << endl;
- cout << "1 -2 0" << endl;
+ int vars = A[0].size();
+ int eqs = A.size();
+ vector<vector<int>> clauses;
+
+ // 5x1 + 2x2 + 3x3 ≤ 6
+ // vector that are no solutions : (1,1,1)=10, (1,1,0)=7, (1,0,1)=8
+ // corresponding clauses (!x || !y || !z), (!x || !y || z), (!x || y || !z)
+ vector<int> coefficients(vars, -1);
+ for (int i = 0; i < eqs; i++) {
+
+ vector<int> equ = A[i];
+
+ // collect non 0 coefficients
+ coefficients.clear();
+ for (int j = 0; j < vars; j++) {
+ if (equ[j] != 0) coefficients.push_back(j);
+ }
+
+ vector<int> clause;
+ // for each bit combinaison
+ for (int j = 0; j < (1<<coefficients.size()); j++) {
+
+ // sum the coefficients using the bit map
+ int v = 0;
+ clause.clear();
+ for (int k = 0; k < coefficients.size(); k++) {
+ bool b = ((j & (1<<k)) > 0);
+ int w = coefficients[k];
+ if (b) v += equ[w];
+ w += 1;
+ clause.push_back(b ? -w: w);
+ }
+
+ if (v > b[i]) {
+ clauses.push_back(clause);
+ }
+ }
+ }
+
+ int n = clauses.size();
+ if (n == 0) {
+ cout << "1 1\n1 -1 0"<< endl;
+ } else {
+ cout << clauses.size() << " " << vars << endl;
+ for (vector<int>& c : clauses) {
+ for (int v : c) {
+ cout << v << " ";
+ }
+ cout << "0" << endl;
+ }
+ cout << endl;
+ }
}
};