修改分支定界搜索过程中,状态未更新导致的找不到最优解的问题
This commit is contained in:
@@ -31,8 +31,8 @@ namespace sv {
|
|||||||
|
|
||||||
Var* vars;
|
Var* vars;
|
||||||
|
|
||||||
matrix mt;
|
matrix table;
|
||||||
matrix mt_cvt;
|
matrix ope_table;
|
||||||
size_t cn, bn;
|
size_t cn, bn;
|
||||||
std::vector<int> basic;
|
std::vector<int> basic;
|
||||||
rtn rtn_;
|
rtn rtn_;
|
||||||
|
@@ -33,10 +33,10 @@ Expr sv::operator+(const Expr& x, const Expr& y)
|
|||||||
exp.coeffs.resize(std::max(x.coeffs.size(), y.coeffs.size()), 0);
|
exp.coeffs.resize(std::max(x.coeffs.size(), y.coeffs.size()), 0);
|
||||||
for (int c = 0; c < exp.coeffs.size(); c++) {
|
for (int c = 0; c < exp.coeffs.size(); c++) {
|
||||||
if (c < x.coeffs.size() && c < y.coeffs.size()) {
|
if (c < x.coeffs.size() && c < y.coeffs.size()) {
|
||||||
exp.coeffs[c] = x.coeffs[c] + y.coeffs[c];
|
exp.coeffs.at(c) = x.coeffs.at(c) + y.coeffs.at(c);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
exp.coeffs[c] = c < x.coeffs.size() ? x.coeffs[c] : y.coeffs[c];
|
exp.coeffs.at(c) = c < x.coeffs.size() ? x.coeffs.at(c) : y.coeffs.at(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exp.constant = x.constant + y.constant;
|
exp.constant = x.constant + y.constant;
|
||||||
@@ -52,8 +52,8 @@ Expr sv::operator+(Var x, Var y)
|
|||||||
{
|
{
|
||||||
Expr exp;
|
Expr exp;
|
||||||
exp.coeffs.resize(std::max(x.get(IntAttr::NumCol) + 1, y.get(IntAttr::NumCol) + 1), 0);
|
exp.coeffs.resize(std::max(x.get(IntAttr::NumCol) + 1, y.get(IntAttr::NumCol) + 1), 0);
|
||||||
exp.coeffs[x.get(IntAttr::NumCol)] = x.get(DoubleAttr::Coeff);
|
exp.coeffs.at(x.get(IntAttr::NumCol)) = x.get(DoubleAttr::Coeff);
|
||||||
exp.coeffs[y.get(IntAttr::NumCol)] = y.get(DoubleAttr::Coeff);
|
exp.coeffs.at(y.get(IntAttr::NumCol)) = y.get(DoubleAttr::Coeff);
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,10 +76,10 @@ Expr sv::operator-(const Expr& x, const Expr& y)
|
|||||||
exp.coeffs.resize(std::max(x.coeffs.size(), y.coeffs.size()), 0);
|
exp.coeffs.resize(std::max(x.coeffs.size(), y.coeffs.size()), 0);
|
||||||
for (int c = 0; c < exp.coeffs.size(); c++) {
|
for (int c = 0; c < exp.coeffs.size(); c++) {
|
||||||
if (c < x.coeffs.size() && c < y.coeffs.size()) {
|
if (c < x.coeffs.size() && c < y.coeffs.size()) {
|
||||||
exp.coeffs[c] = x.coeffs[c] - y.coeffs[c];
|
exp.coeffs.at(c) = x.coeffs.at(c) - y.coeffs.at(c);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
exp.coeffs[c] = c < x.coeffs.size() ? x.coeffs[c] : y.coeffs[c];
|
exp.coeffs.at(c) = c < x.coeffs.size() ? x.coeffs.at(c) : y.coeffs.at(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exp.constant = x.constant + y.constant;
|
exp.constant = x.constant + y.constant;
|
||||||
@@ -90,7 +90,7 @@ Expr sv::operator-(const Expr& x)
|
|||||||
{
|
{
|
||||||
Expr expr(x);
|
Expr expr(x);
|
||||||
for (int c = 0; c < expr.coeffs.size(); c++) {
|
for (int c = 0; c < expr.coeffs.size(); c++) {
|
||||||
expr.coeffs[c] = -expr.coeffs[c];
|
expr.coeffs.at(c) = -expr.coeffs.at(c);
|
||||||
}
|
}
|
||||||
expr.constant = -expr.constant;
|
expr.constant = -expr.constant;
|
||||||
return expr;
|
return expr;
|
||||||
@@ -105,8 +105,8 @@ Expr sv::operator-(Var x, Var y)
|
|||||||
{
|
{
|
||||||
Expr exp;
|
Expr exp;
|
||||||
exp.coeffs.resize(std::max(x.get(IntAttr::NumCol) + 1, y.get(IntAttr::NumCol) + 1), 0);
|
exp.coeffs.resize(std::max(x.get(IntAttr::NumCol) + 1, y.get(IntAttr::NumCol) + 1), 0);
|
||||||
exp.coeffs[x.get(IntAttr::NumCol)] = x.get(DoubleAttr::Coeff);
|
exp.coeffs.at(x.get(IntAttr::NumCol)) = x.get(DoubleAttr::Coeff);
|
||||||
exp.coeffs[y.get(IntAttr::NumCol)] = -y.get(DoubleAttr::Coeff);
|
exp.coeffs.at(y.get(IntAttr::NumCol)) = -y.get(DoubleAttr::Coeff);
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ Expr sv::operator*(double a, Var x)
|
|||||||
{
|
{
|
||||||
Expr exp;
|
Expr exp;
|
||||||
exp.coeffs.resize(x.get(IntAttr::NumCol) + 1, 0);
|
exp.coeffs.resize(x.get(IntAttr::NumCol) + 1, 0);
|
||||||
exp.coeffs[x.get(IntAttr::NumCol)] = a * x.get(DoubleAttr::Coeff);
|
exp.coeffs.at(x.get(IntAttr::NumCol)) = a * x.get(DoubleAttr::Coeff);
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ Expr sv::operator*(const Expr& x, double a)
|
|||||||
{
|
{
|
||||||
Expr exp = x;
|
Expr exp = x;
|
||||||
for (int c = 0; c < exp.coeffs.size(); c++) {
|
for (int c = 0; c < exp.coeffs.size(); c++) {
|
||||||
exp.coeffs[c] *= a;
|
exp.coeffs.at(c) *= a;
|
||||||
}
|
}
|
||||||
exp.constant *= a;
|
exp.constant *= a;
|
||||||
return exp;
|
return exp;
|
||||||
@@ -157,7 +157,7 @@ Expr sv::operator/(const Expr& x, double a)
|
|||||||
{
|
{
|
||||||
Expr exp = x;
|
Expr exp = x;
|
||||||
for (int c = 0; c < exp.coeffs.size(); c++) {
|
for (int c = 0; c < exp.coeffs.size(); c++) {
|
||||||
exp.coeffs[c] /= a;
|
exp.coeffs.at(c) /= a;
|
||||||
}
|
}
|
||||||
exp.constant /= a;
|
exp.constant /= a;
|
||||||
return exp;
|
return exp;
|
||||||
@@ -171,7 +171,7 @@ Expr::Expr(double constant)
|
|||||||
Expr::Expr(Var var, double coeff)
|
Expr::Expr(Var var, double coeff)
|
||||||
{
|
{
|
||||||
this->coeffs.resize(var.col + 1);
|
this->coeffs.resize(var.col + 1);
|
||||||
this->coeffs[var.col] = coeff;
|
this->coeffs.at(var.col) = coeff;
|
||||||
this->constant = 0;
|
this->constant = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ void Expr::operator+=(const Expr& expr)
|
|||||||
{
|
{
|
||||||
coeffs.resize(std::max(coeffs.size(), expr.coeffs.size()));
|
coeffs.resize(std::max(coeffs.size(), expr.coeffs.size()));
|
||||||
for (int c = 0; c < expr.coeffs.size(); c++) {
|
for (int c = 0; c < expr.coeffs.size(); c++) {
|
||||||
coeffs[c] += expr.coeffs[c];
|
coeffs.at(c) += expr.coeffs.at(c);
|
||||||
}
|
}
|
||||||
constant += expr.constant;
|
constant += expr.constant;
|
||||||
}
|
}
|
||||||
@@ -193,7 +193,7 @@ void Expr::operator-=(const Expr& expr)
|
|||||||
{
|
{
|
||||||
coeffs.resize(std::max(coeffs.size(), expr.coeffs.size()));
|
coeffs.resize(std::max(coeffs.size(), expr.coeffs.size()));
|
||||||
for (int c = 0; c < expr.coeffs.size(); c++) {
|
for (int c = 0; c < expr.coeffs.size(); c++) {
|
||||||
coeffs[c] -= expr.coeffs[c];
|
coeffs.at(c) -= expr.coeffs.at(c);
|
||||||
}
|
}
|
||||||
constant -= expr.constant;
|
constant -= expr.constant;
|
||||||
}
|
}
|
||||||
@@ -201,7 +201,7 @@ void Expr::operator-=(const Expr& expr)
|
|||||||
void Expr::operator*=(double mult)
|
void Expr::operator*=(double mult)
|
||||||
{
|
{
|
||||||
for (int c = 0; c < coeffs.size(); c++) {
|
for (int c = 0; c < coeffs.size(); c++) {
|
||||||
coeffs[c] *= mult;
|
coeffs.at(c) *= mult;
|
||||||
}
|
}
|
||||||
constant *= mult;
|
constant *= mult;
|
||||||
}
|
}
|
||||||
@@ -209,7 +209,7 @@ void Expr::operator*=(double mult)
|
|||||||
void Expr::operator/=(double a)
|
void Expr::operator/=(double a)
|
||||||
{
|
{
|
||||||
for (int c = 0; c < coeffs.size(); c++) {
|
for (int c = 0; c < coeffs.size(); c++) {
|
||||||
coeffs[c] /= a;
|
coeffs.at(c) /= a;
|
||||||
}
|
}
|
||||||
constant /= a;
|
constant /= a;
|
||||||
}
|
}
|
||||||
@@ -218,7 +218,7 @@ Expr Expr::operator+(const Expr& rhs)
|
|||||||
{
|
{
|
||||||
coeffs.resize(std::max(coeffs.size(), rhs.coeffs.size()));
|
coeffs.resize(std::max(coeffs.size(), rhs.coeffs.size()));
|
||||||
for (int c = 0; c < rhs.coeffs.size(); c++) {
|
for (int c = 0; c < rhs.coeffs.size(); c++) {
|
||||||
coeffs[c] += rhs.coeffs[c];
|
coeffs.at(c) += rhs.coeffs.at(c);
|
||||||
}
|
}
|
||||||
constant += rhs.constant;
|
constant += rhs.constant;
|
||||||
return *this;
|
return *this;
|
||||||
@@ -228,7 +228,7 @@ Expr Expr::operator-(const Expr& rhs)
|
|||||||
{
|
{
|
||||||
coeffs.resize(std::max(coeffs.size(), rhs.coeffs.size()));
|
coeffs.resize(std::max(coeffs.size(), rhs.coeffs.size()));
|
||||||
for (int c = 0; c < rhs.coeffs.size(); c++) {
|
for (int c = 0; c < rhs.coeffs.size(); c++) {
|
||||||
coeffs[c] -= rhs.coeffs[c];
|
coeffs.at(c) -= rhs.coeffs.at(c);
|
||||||
}
|
}
|
||||||
constant -= rhs.constant;
|
constant -= rhs.constant;
|
||||||
return *this;
|
return *this;
|
||||||
|
14
src/main.cpp
14
src/main.cpp
@@ -10,20 +10,14 @@ using namespace sv;
|
|||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
Model mdl;
|
Model mdl;
|
||||||
|
|
||||||
Var* vars = mdl.addVars(2, VarType::INTEGER);
|
Var* vars = mdl.addVars(3, VarType::INTEGER);
|
||||||
|
|
||||||
|
|
||||||
//mdl.addConstr(vars[0] + vars[1], ConstrOper::LESS_EQUAL, 2);
|
|
||||||
//mdl.addConstr(vars[0] + vars[1], ConstrOper::GREATER_EQUAL, 1);
|
|
||||||
//mdl.addConstr(5 * vars[0] - 2 * vars[1], ConstrOper::GREATER_EQUAL, -2);
|
|
||||||
|
|
||||||
//mdl.setObjective(vars[0] + 2 * vars[1], MDL_MAXIMIZE);
|
|
||||||
|
|
||||||
mdl.addConstr(2 * vars[0] + vars[1], ConstrOper::LESS_EQUAL, 10);
|
mdl.addConstr(2 * vars[0] + vars[1], ConstrOper::LESS_EQUAL, 10);
|
||||||
mdl.addConstr(3 * vars[0] + 6 * vars[1], ConstrOper::LESS_EQUAL, 40);
|
mdl.addConstr(3 * vars[0] + 6 * vars[1], ConstrOper::LESS_EQUAL, 40);
|
||||||
|
mdl.addConstr(3 * vars[0] + 6 * vars[1] + 4 * vars[2], ConstrOper::LESS_EQUAL, 50);
|
||||||
|
mdl.setObjective(100 * vars[0] + 150 * vars[1] + 120 * vars[2], MDL_MAXIMIZE);
|
||||||
|
|
||||||
mdl.setObjective(100 * vars[0] + 150 * vars[1], MDL_MAXIMIZE);
|
|
||||||
switch(mdl.optimize()) {
|
switch(mdl.optimize()) {
|
||||||
case OPTIMAL:
|
case OPTIMAL:
|
||||||
cout << "OPTIMAL SOLUTION: " << mdl.get(DoubleAttr::Obj) << endl;
|
cout << "OPTIMAL SOLUTION: " << mdl.get(DoubleAttr::Obj) << endl;
|
||||||
|
145
src/solver.cpp
145
src/solver.cpp
@@ -24,11 +24,14 @@ struct Node
|
|||||||
};
|
};
|
||||||
|
|
||||||
LinSolver::LinSolver() :
|
LinSolver::LinSolver() :
|
||||||
|
obj_(0),
|
||||||
|
rtn_(LOADED),
|
||||||
cn(0),
|
cn(0),
|
||||||
bn(1),
|
bn(1),
|
||||||
sense(0),
|
sense(0),
|
||||||
vars(nullptr)
|
vars(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sv::LinSolver::~LinSolver()
|
sv::LinSolver::~LinSolver()
|
||||||
@@ -40,7 +43,7 @@ sv::LinSolver::LinSolver(const LinSolver& solver)
|
|||||||
: vars(nullptr),
|
: vars(nullptr),
|
||||||
cn(solver.cn),
|
cn(solver.cn),
|
||||||
bn(solver.bn),
|
bn(solver.bn),
|
||||||
mt(solver.mt),
|
table(solver.table),
|
||||||
basic(solver.basic),
|
basic(solver.basic),
|
||||||
rtn_(solver.rtn_),
|
rtn_(solver.rtn_),
|
||||||
obj_(solver.obj_),
|
obj_(solver.obj_),
|
||||||
@@ -71,8 +74,7 @@ LinSolver& sv::LinSolver::operator=(const LinSolver& solver)
|
|||||||
vars[i] = solver.vars[i]; // <20><EFBFBD><EEBFBD>
|
vars[i] = solver.vars[i]; // <20><EFBFBD><EEBFBD>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
table = solver.table;
|
||||||
mt = solver.mt;
|
|
||||||
cn = solver.cn, bn = solver.bn;
|
cn = solver.cn, bn = solver.bn;
|
||||||
basic = solver.basic;
|
basic = solver.basic;
|
||||||
rtn_ = solver.rtn_;
|
rtn_ = solver.rtn_;
|
||||||
@@ -91,9 +93,6 @@ Var* LinSolver::addVars(int num, VarType type)
|
|||||||
vars[c].type = type;
|
vars[c].type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
//for (int i = 0; i < cn; i++) {
|
|
||||||
// *(vars + i) = *(old + i);
|
|
||||||
//}
|
|
||||||
memcpy(vars, old, sizeof(Var) * cn);
|
memcpy(vars, old, sizeof(Var) * cn);
|
||||||
delete[] old;
|
delete[] old;
|
||||||
cn += num;
|
cn += num;
|
||||||
@@ -110,14 +109,14 @@ void LinSolver::addConstr(const Expr& expr, ConstrOper sense, double rhs)
|
|||||||
{
|
{
|
||||||
if (sense == ConstrOper::LESS_EQUAL) {
|
if (sense == ConstrOper::LESS_EQUAL) {
|
||||||
bn++;
|
bn++;
|
||||||
mt.push_back(vector<double>(1, rhs - expr.constant));
|
table.push_back(vector<double>(1, rhs - expr.constant));
|
||||||
mt.back().insert(mt.back().end(), expr.coeffs.begin(), expr.coeffs.end());
|
table.back().insert(table.back().end(), expr.coeffs.begin(), expr.coeffs.end());
|
||||||
}
|
}
|
||||||
else if (sense == ConstrOper::GREATER_EQUAL) {
|
else if (sense == ConstrOper::GREATER_EQUAL) {
|
||||||
bn++;
|
bn++;
|
||||||
mt.push_back(vector<double>(1, expr.constant - rhs));
|
table.push_back(vector<double>(1, expr.constant - rhs));
|
||||||
for (int coeff : expr.coeffs) {
|
for (int coeff : expr.coeffs) {
|
||||||
mt.back().push_back(-coeff);
|
table.back().push_back(-coeff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -125,8 +124,8 @@ void LinSolver::addConstr(const Expr& expr, ConstrOper sense, double rhs)
|
|||||||
addConstr(expr, ConstrOper::GREATER_EQUAL, rhs);
|
addConstr(expr, ConstrOper::GREATER_EQUAL, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int c = mt.back().size(); c <= cn; c++) {
|
for (int c = table.back().size(); c <= cn; c++) {
|
||||||
mt.back().push_back(0);
|
table.back().push_back(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,25 +133,25 @@ void LinSolver::setObjective(Expr obje, int _sense)
|
|||||||
{
|
{
|
||||||
assert(_sense == 1 || _sense == -1);
|
assert(_sense == 1 || _sense == -1);
|
||||||
if (sense == 0) {
|
if (sense == 0) {
|
||||||
mt.insert(mt.begin(), obje.coeffs);
|
table.insert(table.begin(), obje.coeffs);
|
||||||
mt.front().insert(mt.front().begin(), -obje.constant);
|
table.front().insert(table.front().begin(), -obje.constant);
|
||||||
for (int c = obje.coeffs.size() + 1; c <= cn; c++) {
|
for (int c = obje.coeffs.size() + 1; c <= cn; c++) {
|
||||||
mt.front().push_back(0);
|
table.front().push_back(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mt.front().front() = -obje.constant;
|
table.front().front() = -obje.constant;
|
||||||
for (int c = 0; c < cn; c++) {
|
for (int col = 0; col < cn; col++) {
|
||||||
if (c < obje.coeffs.size()) {
|
if (col < obje.coeffs.size()) {
|
||||||
mt.front()[c + 1] = obje.coeffs[c];
|
table.front().at(col + 1) = obje.coeffs.at(col);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mt.front()[c] = 0;
|
table.front().at(col) = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < mt.front().size(); i++) {
|
for (int row = 0; row < table.front().size(); row++) {
|
||||||
mt.front()[i] = _sense * mt.front()[i];
|
table.front().at(row) = _sense * table.front().at(row);
|
||||||
}
|
}
|
||||||
sense = _sense;
|
sense = _sense;
|
||||||
}
|
}
|
||||||
@@ -160,27 +159,29 @@ void LinSolver::setObjective(Expr obje, int _sense)
|
|||||||
rtn LinSolver::optimize()
|
rtn LinSolver::optimize()
|
||||||
{
|
{
|
||||||
assert(sense);
|
assert(sense);
|
||||||
mt_cvt = mt;
|
ope_table = table;
|
||||||
|
rtn_ = LOADED;
|
||||||
rtn_ = feasible_solution();
|
rtn_ = feasible_solution();
|
||||||
if (rtn_ == LOADED) {
|
if (rtn_ == LOADED) {
|
||||||
obj_ = _simplex();
|
obj_ = _simplex();
|
||||||
}
|
}
|
||||||
|
|
||||||
cn = mt_cvt.front().size() - bn;
|
if (rtn_ == OPTIMAL) {
|
||||||
for (int row = 1; row < bn; row++) {
|
cn = ope_table.front().size() - bn;
|
||||||
if (basic[row - 1] - 1 <= cn) {
|
for (int row = 1; row < bn; row++) {
|
||||||
vars[basic[row - 1] - 1].val = mt_cvt[row].front();
|
if (basic.at(row - 1) - 1 < cn) {
|
||||||
|
vars[basic.at(row - 1) - 1].val = ope_table.at(row).front();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rtn_;
|
return rtn_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinSolver::print()
|
void LinSolver::print()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < mt_cvt.size(); i++) {
|
for (size_t row = 0; row < ope_table.size(); row++) {
|
||||||
for (size_t j = 0; j < mt_cvt[0].size(); j++) {
|
for (size_t col = 0; col < ope_table.front().size(); col++) {
|
||||||
cout << mt_cvt[i][j] << "\t";
|
cout << ope_table.at(row).at(col) << "\t";
|
||||||
}
|
}
|
||||||
cout << endl;
|
cout << endl;
|
||||||
}
|
}
|
||||||
@@ -202,14 +203,11 @@ rtn Model::optimize()
|
|||||||
|
|
||||||
std::stack<Node> list_;
|
std::stack<Node> list_;
|
||||||
|
|
||||||
Node incumbent_node, root_node;
|
Node root_node(solver, 0, solver.obj_);
|
||||||
root_node.solver = solver;
|
Node incumbent_node = root_node;
|
||||||
root_node.upper_bound = global_upper_bound, root_node.lower_bound = global_lower_bound;
|
|
||||||
|
|
||||||
list_.push(root_node);
|
list_.push(root_node);
|
||||||
int cnt = 0;
|
|
||||||
while (list_.size() && global_upper_bound - global_lower_bound > 1e-10) {
|
while (list_.size() && global_upper_bound - global_lower_bound > 1e-10) {
|
||||||
cout << ++cnt << endl;
|
|
||||||
Node current_node = list_.top();
|
Node current_node = list_.top();
|
||||||
list_.pop();
|
list_.pop();
|
||||||
current_node.solver.optimize();
|
current_node.solver.optimize();
|
||||||
@@ -310,18 +308,18 @@ double LinSolver::_simplex()
|
|||||||
}
|
}
|
||||||
_gaussian(t);
|
_gaussian(t);
|
||||||
}
|
}
|
||||||
return obj_ = mt_cvt.front().front();
|
return obj_ = ope_table.front().front();
|
||||||
}
|
}
|
||||||
|
|
||||||
rtn LinSolver::feasible_solution()
|
rtn LinSolver::feasible_solution()
|
||||||
{
|
{
|
||||||
for (int row = 1; row < bn; row++) {
|
for (int row = 1; row < bn; row++) {
|
||||||
mt_cvt.front().push_back(0);
|
ope_table.front().push_back(0);
|
||||||
for (int col = 1; col < bn; col++) {
|
for (int col = 1; col < bn; col++) {
|
||||||
mt_cvt[row].push_back(col == row ? 1 : 0);
|
ope_table.at(row).push_back(col == row ? 1 : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cn = mt_cvt.front().size();
|
cn = ope_table.front().size();
|
||||||
basic.clear();
|
basic.clear();
|
||||||
for (size_t i = 1; i < bn; i++) {
|
for (size_t i = 1; i < bn; i++) {
|
||||||
basic.push_back(cn - bn + i);
|
basic.push_back(cn - bn + i);
|
||||||
@@ -330,7 +328,7 @@ rtn LinSolver::feasible_solution()
|
|||||||
// === <20>жϳ<D0B6>ʼ<EFBFBD><CABC><EFBFBD>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>н<EFBFBD> ===
|
// === <20>жϳ<D0B6>ʼ<EFBFBD><CABC><EFBFBD>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>н<EFBFBD> ===
|
||||||
bool initial_feasible = true;
|
bool initial_feasible = true;
|
||||||
for (int row = 1; row < bn; row++) {
|
for (int row = 1; row < bn; row++) {
|
||||||
if (mt_cvt[row].front() < 0) {
|
if (ope_table.at(row).front() < 0) {
|
||||||
initial_feasible = false;
|
initial_feasible = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -338,65 +336,64 @@ rtn LinSolver::feasible_solution()
|
|||||||
|
|
||||||
// === <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>н<EFBFBD> ===
|
// === <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>н<EFBFBD> ===
|
||||||
if (!initial_feasible) {
|
if (!initial_feasible) {
|
||||||
vector<double> coeff = mt_cvt.front();
|
vector<double> coeff = ope_table.front();
|
||||||
mt_cvt.front() = vector<double>(cn, .0);
|
ope_table.front() = vector<double>(cn, .0);
|
||||||
mt_cvt.front().push_back(1);
|
ope_table.front().push_back(1);
|
||||||
pair<size_t, size_t> t = { -1 ,cn };
|
pair<size_t, size_t> t = { -1 ,cn };
|
||||||
|
|
||||||
for (int row = 1; row < bn; row++) {
|
for (int row = 1; row < bn; row++) {
|
||||||
mt_cvt[row].push_back(-1);
|
ope_table.at(row).push_back(-1);
|
||||||
if (t.first == -1 || mt_cvt[row].front() < mt_cvt[t.first].front()) {
|
if (t.first == -1 || ope_table.at(row).front() < ope_table.at(t.first).front()) {
|
||||||
t.first = row;
|
t.first = row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_gaussian(t);
|
_gaussian(t);
|
||||||
if (fabs(_simplex()) > 1e-10) {
|
if (fabs(_simplex()) > 1e-10) {
|
||||||
rtn_ = INFEASIBLE;
|
return rtn_ = INFEASIBLE;
|
||||||
return rtn_;
|
|
||||||
}
|
}
|
||||||
|
rtn_ = LOADED;
|
||||||
// if the x0 in B, we should pivot it.
|
// if the x0 in B, we should pivot it.
|
||||||
auto iter = find(basic.begin(), basic.end(), cn);
|
auto iter = find(basic.begin(), basic.end(), cn);
|
||||||
if (iter != basic.end()) {
|
if (iter != basic.end()) {
|
||||||
for (int col = 1; col < mt_cvt.front().size(); col++) {
|
for (int col = 1; col < ope_table.front().size(); col++) {
|
||||||
if (fabs(mt_cvt.front()[col]) > 1e-10) {
|
if (fabs(ope_table.front().at(col)) > 1e-10) {
|
||||||
t = make_pair(iter - basic.begin() + 1, col);
|
t = make_pair(iter - basic.begin() + 1, col);
|
||||||
_gaussian(t);
|
_gaussian(t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int row = 0; row < bn; row++) {
|
for (int row = 0; row < bn; row++) {
|
||||||
mt_cvt[row].pop_back();
|
ope_table.at(row).pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
// recover the coefficient line
|
// recover the coefficient line
|
||||||
for (int col = 0; col < cn; col++) {
|
for (int col = 0; col < cn; col++) {
|
||||||
mt_cvt.front()[col] = coeff[col];
|
ope_table.front().at(col) = coeff.at(col);
|
||||||
}
|
}
|
||||||
for (int row = 1; row <= basic.size(); row++) {
|
for (int row = 1; row <= basic.size(); row++) {
|
||||||
int norm = mt_cvt.front()[basic[row - 1]];
|
int norm = ope_table.front().at(basic.at(row - 1));
|
||||||
for (int col = 0; col < cn; col++) {
|
for (int col = 0; col < cn; col++) {
|
||||||
mt_cvt.front()[col] -= norm * mt_cvt[row][col];
|
ope_table.front().at(col) -= norm * ope_table.at(row).at(col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return LOADED;
|
return rtn_;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtn LinSolver::_pivot(pair<size_t, size_t>& p)
|
rtn LinSolver::_pivot(pair<size_t, size_t>& p)
|
||||||
{
|
{
|
||||||
p = make_pair(0, 0);
|
p = make_pair(0, 0);
|
||||||
double cmin = INT_MAX;
|
double cmin = INT_MAX;
|
||||||
vector<double> coef = mt_cvt.front();
|
vector<double> coef = ope_table.front();
|
||||||
|
|
||||||
// === <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сֵ ===
|
// === <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сֵ ===
|
||||||
for (size_t i = 1; i < coef.size(); i++) {
|
for (size_t col = 1; col < coef.size(); col++) {
|
||||||
if (cmin > coef[i] && find(basic.begin(), basic.end(), i) == basic.end()) {
|
if (cmin > coef.at(col) && find(basic.begin(), basic.end(), col) == basic.end()) {
|
||||||
cmin = coef[i];
|
cmin = coef.at(col);
|
||||||
p.second = i;
|
p.second = col;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cmin >= 0) {
|
if (cmin >= 0) {
|
||||||
@@ -404,8 +401,8 @@ rtn LinSolver::_pivot(pair<size_t, size_t>& p)
|
|||||||
}
|
}
|
||||||
double bmin = INT_MAX;
|
double bmin = INT_MAX;
|
||||||
for (size_t row = 1; row < bn; row++) {
|
for (size_t row = 1; row < bn; row++) {
|
||||||
double tmp = mt_cvt[row].front() / mt_cvt[row][p.second];
|
double tmp = ope_table.at(row).front() / ope_table.at(row).at(p.second);
|
||||||
if (mt_cvt[row][p.second] > 0 && bmin > tmp) {
|
if (ope_table.at(row).at(p.second) > 0 && bmin > tmp) {
|
||||||
bmin = tmp;
|
bmin = tmp;
|
||||||
p.first = row;
|
p.first = row;
|
||||||
}
|
}
|
||||||
@@ -416,12 +413,12 @@ rtn LinSolver::_pivot(pair<size_t, size_t>& p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto iter = basic.begin(); iter != basic.end(); iter++) {
|
for (auto iter = basic.begin(); iter != basic.end(); iter++) {
|
||||||
if (mt_cvt[p.first][*iter] != 0) {
|
if (ope_table.at(p.first).at(*iter) != 0) {
|
||||||
*iter = p.second;
|
*iter = p.second;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(basic[p.first - 1] == p.second);
|
assert(basic.at(p.first - 1) == p.second);
|
||||||
return PIVOT;
|
return PIVOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,9 +427,9 @@ void LinSolver::_gaussian(pair<size_t, size_t> p)
|
|||||||
size_t x = p.first, y = p.second;
|
size_t x = p.first, y = p.second;
|
||||||
|
|
||||||
// === <20><><EFBFBD>й<EFBFBD>һ<EFBFBD><D2BB> ===
|
// === <20><><EFBFBD>й<EFBFBD>һ<EFBFBD><D2BB> ===
|
||||||
double norm = mt_cvt[x][y];
|
double norm = ope_table.at(x).at(y);
|
||||||
for (size_t col = 0; col < mt_cvt[x].size(); col++) {
|
for (size_t col = 0; col < ope_table.at(x).size(); col++) {
|
||||||
mt_cvt[x][col] /= norm;
|
ope_table.at(x).at(col) /= norm;
|
||||||
}
|
}
|
||||||
|
|
||||||
// === <20><><EFBFBD><EFBFBD><EFBFBD>б任 ===
|
// === <20><><EFBFBD><EFBFBD><EFBFBD>б任 ===
|
||||||
@@ -440,13 +437,13 @@ void LinSolver::_gaussian(pair<size_t, size_t> p)
|
|||||||
if (row == x) {
|
if (row == x) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (mt_cvt[row][y] != 0) {
|
if (ope_table.at(row).at(y) != 0) {
|
||||||
double norm = mt_cvt[row][y];
|
double norm = ope_table.at(row).at(y);
|
||||||
for (size_t col = 0; col < mt_cvt[x].size(); col++) {
|
for (size_t col = 0; col < ope_table.at(x).size(); col++) {
|
||||||
mt_cvt[row][col] = mt_cvt[row][col] - norm * mt_cvt[x][col];
|
ope_table.at(row).at(col) = ope_table.at(row).at(col) - norm * ope_table.at(x).at(col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
basic[x - 1] = y; // <20><>Ԫ
|
basic.at(x - 1) = y; // <20><>Ԫ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user