miner improve

This commit is contained in:
2023-09-28 10:55:22 +08:00
parent 0a83e90e32
commit 805dc08146

View File

@ -153,6 +153,7 @@ void PrintEquations(std::vector<std::vector<double> > equations) {
std::cout << std::endl; std::cout << std::endl;
} }
} }
inline int RandIntLessThan(int n) { return RawRnd() % n; }
/** /**
* @brief The definition of function GenerateEquations() * @brief The definition of function GenerateEquations()
* *
@ -217,6 +218,8 @@ std::vector<std::vector<double> > GenerateEquations() {
} }
} }
// PrintEquations(equations); // PrintEquations(equations);
// randome shuffle lines of equations using RawRnd
std::random_shuffle(equations.begin(), equations.end(), RandIntLessThan);
return equations; return equations;
} }
/** /**
@ -241,20 +244,61 @@ std::vector<std::vector<double> > GaussianJordanElimination(
int n = equations.size(); int n = equations.size();
if (n == 0) return equations; if (n == 0) return equations;
int m = equations[0].size(); int m = equations[0].size();
std::vector<double> equa_template;
equa_template.resize(m);
// assert(n + 1 == m); // assert(n + 1 == m);
for (int i = 0; i < n; i++) { for (int tot = 0; tot < 3; tot++) {
int pivot = i; n = equations.size();
for (int j = i + 1; j < n; j++) for (int i = 0; i < n; i++) {
if (abs(equations[j][i]) > abs(equations[pivot][i])) pivot = j; int pivot = i;
std::swap(equations[i], equations[pivot]); for (int j = i + 1; j < n; j++)
if (abs(equations[i][i]) < eps) continue; if (abs(equations[j][i]) > abs(equations[pivot][i])) pivot = j;
const double pivot_value = equations[i][i]; std::swap(equations[i], equations[pivot]);
for (int j = 0; j < m; j++) equations[i][j] /= pivot_value; if (abs(equations[i][i]) < eps) continue;
for (int j = 0; j < n; j++) const double pivot_value = equations[i][i];
if (j != i) { for (int j = 0; j < m; j++) equations[i][j] /= pivot_value;
const double tmp = equations[j][i]; for (int j = 0; j < n; j++)
for (int k = 0; k < m; k++) equations[j][k] -= tmp * equations[i][k]; if (j != i) {
const double tmp = equations[j][i];
for (int k = 0; k < m; k++) equations[j][k] -= tmp * equations[i][k];
}
}
// continue;
for (int i = 0; i < equations.size(); i++) {
bool error_occur = false;
int total_num = 0;
for (int j = 0; j < m - 1; j++) {
int v = NearbyInt(equations[i][j]);
if (v == error_status_of_nearint || v < 0) {
error_occur = true;
break;
}
total_num += v;
} }
if (error_occur) continue;
if(total_num==1) continue;
if (NearbyInt(equations[i][m - 1]) == 0) {
for (int j = 0; j < m - 1; j++)
if (NearbyInt(equations[i][j]) > 0) {
equations.push_back(equa_template);
for (int k = 0; k < m; k++) equations[equations.size() - 1][k] = 0;
equations[equations.size() - 1][m - 1] = 0;
equations[equations.size() - 1][j] = 1;
}
equations.erase(equations.begin()+i);
i--;
} else if (NearbyInt(equations[i][m - 1]) == total_num) {
for (int j = 0; j < m - 1; j++)
if (NearbyInt(equations[i][j]) > 0) {
equations.push_back(equa_template);
for (int k = 0; k < m; k++) equations[equations.size() - 1][k] = 0;
equations[equations.size() - 1][m - 1] = 1;
equations[equations.size() - 1][j] = 1;
}
equations.erase(equations.begin()+i);
i--;
}
}
} }
return equations; return equations;
} }
@ -286,11 +330,12 @@ void InterpretResult(std::vector<std::vector<double> > equations) {
if (number_of_1 != 1) continue; if (number_of_1 != 1) continue;
int sol = NearbyInt(equations[i][m - 1]); int sol = NearbyInt(equations[i][m - 1]);
if (sol == error_status_of_nearint) continue; if (sol == error_status_of_nearint) continue;
if(sol!=0&&sol!=1) if (sol != 0 && sol != 1) {
{ std::cerr << "sol=" << sol << std::endl;
std::cerr<<"sol="<<sol<<std::endl; std::cerr << "one=" << number_of_1
std::cerr<<"one="<<number_of_1<<" not one not zero="<<number_of_non1<<std::endl; << " not one not zero=" << number_of_non1 << std::endl;
std::cerr<<NearbyInt(equations[i][m - 1])<<' '<<equations[i][m - 1]<<std::endl; std::cerr << NearbyInt(equations[i][m - 1]) << ' ' << equations[i][m - 1]
<< std::endl;
PrintEquations(equations); PrintEquations(equations);
} }
assert(sol == 0 || sol == 1); assert(sol == 0 || sol == 1);
@ -340,9 +385,11 @@ void PreProcessData() {
// 3. interpret the result of Gaussian-Jordan Elimination,store the result in // 3. interpret the result of Gaussian-Jordan Elimination,store the result in
// map_status and push the newly found block that definitely has no mine // map_status and push the newly found block that definitely has no mine
// into no_mine_block_to_be_clicked // into no_mine_block_to_be_clicked
std::vector<std::vector<double> > equations = GenerateEquations(); for (int i = 0; i < 4; i++) {
equations = GaussianJordanElimination(equations); std::vector<std::vector<double> > equations = GenerateEquations();
InterpretResult(equations); equations = GaussianJordanElimination(equations);
InterpretResult(equations);
}
} }
/** /**
* @brief The definition of function TotalRandomGuess() * @brief The definition of function TotalRandomGuess()
@ -402,7 +449,7 @@ std::pair<int, int> SimpleGuess() {
nearby_mines--; nearby_mines--;
} }
} }
if(nearby_unkown==0) continue; if (nearby_unkown == 0) continue;
for (int k = 0; k < 8; k++) { for (int k = 0; k < 8; k++) {
int x = i + dx[k], y = j + dy[k]; int x = i + dx[k], y = j + dy[k];
if (x >= 0 && x < rows && y >= 0 && y < columns) { if (x >= 0 && x < rows && y >= 0 && y < columns) {
@ -413,30 +460,28 @@ std::pair<int, int> SimpleGuess() {
} }
} }
std::pair<int, int> best_guess = TotalRandomGuess(); std::pair<int, int> best_guess = TotalRandomGuess();
for(int i=0;i<rows;i++) for (int i = 0; i < rows; i++)
for(int j=0;j<columns;j++) for (int j = 0; j < columns; j++)
if(map_status[i][j]==0) if (map_status[i][j] == 0) {
{ double current_prob = default_probability;
double current_prob=default_probability; if (probability[best_guess.first][best_guess.second].size() > 0) {
if(probability[best_guess.first][best_guess.second].size()>0) current_prob = 0;
{ for (int k = 0;
current_prob=0; k < probability[best_guess.first][best_guess.second].size(); k++)
for(int k=0;k<probability[best_guess.first][best_guess.second].size();k++) current_prob += probability[best_guess.first][best_guess.second][k];
current_prob+=probability[best_guess.first][best_guess.second][k]; current_prob /=
current_prob/=probability[best_guess.first][best_guess.second].size(); probability[best_guess.first][best_guess.second].size();
} }
double this_prob=default_probability; double this_prob = default_probability;
if(probability[i][j].size()>0) if (probability[i][j].size() > 0) {
{ this_prob = 0;
this_prob=0; for (int k = 0; k < probability[i][j].size(); k++)
for(int k=0;k<probability[i][j].size();k++) this_prob += probability[i][j][k];
this_prob+=probability[i][j][k]; this_prob /= probability[i][j].size();
this_prob/=probability[i][j].size();
} }
if(this_prob<current_prob) if (this_prob < current_prob) {
{ best_guess.first = i;
best_guess.first=i; best_guess.second = j;
best_guess.second=j;
} }
} }
return best_guess; return best_guess;