调整目录结构
This commit is contained in:
@ -12,25 +12,20 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||||||
set(SOURCE_DIR "${PROJECT_SOURCE_DIR}/src")
|
set(SOURCE_DIR "${PROJECT_SOURCE_DIR}/src")
|
||||||
set(INCLUDE_DIR "${PROJECT_SOURCE_DIR}/inc")
|
set(INCLUDE_DIR "${PROJECT_SOURCE_DIR}/inc")
|
||||||
|
|
||||||
file(GLOB SOURCES "${SOURCE_DIR}/*.cpp$")
|
file(GLOB SOURCES "${SOURCE_DIR}/*.cpp")
|
||||||
file(GLOB HEADERS "${SOURCE_INCLUDE}/*.hpp$")
|
file(GLOB HEADERS "${INCLUDE_DIR}/*.hpp")
|
||||||
|
|
||||||
#include_directories(
|
#include_directories(
|
||||||
# ${GUROBI_INCLUDE_DIRS}
|
# ${GUROBI_INCLUDE_DIRS}
|
||||||
#)
|
#)
|
||||||
|
|
||||||
message(${SOURCE_DIR})
|
|
||||||
|
|
||||||
aux_source_directory(${SOURCE_DIR} src)
|
aux_source_directory(${SOURCE_DIR} src)
|
||||||
aux_source_directory(${INCLUDE_DIR} inc)
|
aux_source_directory(${INCLUDE_DIR} inc)
|
||||||
|
|
||||||
|
add_executable(Solver ${SOURCES} ${HEADERS})
|
||||||
add_executable(Solver
|
|
||||||
src/main.cpp src/solver.cpp inc/solver.hpp
|
|
||||||
)
|
|
||||||
|
|
||||||
#target_link_libraries(Solver
|
#target_link_libraries(Solver
|
||||||
# ${GUROBI_LIBRARIES}
|
# ${GUROBI_LIBRARIES}
|
||||||
#)
|
#)
|
||||||
|
|
||||||
target_include_directories(Solver PRIVATE ${SOURCE_DIR} ${INCLUDE_DIR})
|
target_include_directories(Solver PRIVATE ${SOURCE_DIR} ${INCLUDE_DIR})
|
||||||
|
163
inc/common.hpp
Normal file
163
inc/common.hpp
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define MDL_MINIMIZE 1
|
||||||
|
#define MDL_MAXIMIZE -1
|
||||||
|
|
||||||
|
#define LOADED 0
|
||||||
|
#define OPTIMAL 1
|
||||||
|
#define INFEASIBLE 2
|
||||||
|
#define INF_OR_UNBD 3
|
||||||
|
#define UNBOUNDED 4
|
||||||
|
#define CUTOFF 5
|
||||||
|
#define ITERATION_LIMIT 6
|
||||||
|
#define NODE_LIMIT 7
|
||||||
|
#define TIME_LIMIT 8
|
||||||
|
#define SOLUTION_LIMIT 9
|
||||||
|
#define INTERRUPTED 10
|
||||||
|
#define NUMERIC 11
|
||||||
|
#define SUBOPTIMAL 12
|
||||||
|
#define INPROGRESS 13
|
||||||
|
#define USER_OBJ_LIMIT 14
|
||||||
|
#define WORK_LIMIT 15
|
||||||
|
#define MEM_LIMIT 16
|
||||||
|
#define PIVOT 17
|
||||||
|
|
||||||
|
namespace sv {
|
||||||
|
using matrix = std::vector<std::vector<double>>;
|
||||||
|
using rtn = int;
|
||||||
|
class Expr;
|
||||||
|
class Var;
|
||||||
|
|
||||||
|
enum class IntAttr {
|
||||||
|
NumConstrs,
|
||||||
|
NumVars,
|
||||||
|
NumIntVars,
|
||||||
|
NumBinVars,
|
||||||
|
ModelSense,
|
||||||
|
IsMIP,
|
||||||
|
IsMultiObj,
|
||||||
|
Status,
|
||||||
|
SolCount,
|
||||||
|
Lazy,
|
||||||
|
NumObj,
|
||||||
|
NumCol
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class DoubleAttr {
|
||||||
|
Runtime,
|
||||||
|
Work,
|
||||||
|
ObjCon,
|
||||||
|
LB,
|
||||||
|
UB,
|
||||||
|
Obj,
|
||||||
|
Start,
|
||||||
|
RHS,
|
||||||
|
Coeff,
|
||||||
|
MaxCoeff,
|
||||||
|
MinCoeff,
|
||||||
|
MaxBound,
|
||||||
|
MinBound,
|
||||||
|
ObjVal,
|
||||||
|
MIPGap,
|
||||||
|
IterCount,
|
||||||
|
NodeCount,
|
||||||
|
X,
|
||||||
|
Slack,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class StringAttr {
|
||||||
|
ModelName,
|
||||||
|
VarName,
|
||||||
|
ConstrName,
|
||||||
|
QCName,
|
||||||
|
GenConstrName,
|
||||||
|
ObjNName,
|
||||||
|
ScenNName,
|
||||||
|
BatchID,
|
||||||
|
VTag,
|
||||||
|
CTag,
|
||||||
|
QCTag,
|
||||||
|
BatchErrorMessage
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ConstrOper {
|
||||||
|
LESS_EQUAL,
|
||||||
|
GREATER_EQUAL,
|
||||||
|
EQUAL
|
||||||
|
};
|
||||||
|
|
||||||
|
class Var {
|
||||||
|
public:
|
||||||
|
Var(double coef = 1) :col(0), val(0), coeffs(coef) {};
|
||||||
|
double get(DoubleAttr attr);
|
||||||
|
int get(IntAttr attr);
|
||||||
|
friend class Model;
|
||||||
|
friend class Expr;
|
||||||
|
private:
|
||||||
|
double coeffs;
|
||||||
|
double val;
|
||||||
|
int col;
|
||||||
|
};
|
||||||
|
|
||||||
|
Expr operator+(const Expr& x, const Expr& y);
|
||||||
|
Expr operator-(const Expr& x, const Expr& y);
|
||||||
|
Expr operator+(const Expr& x);
|
||||||
|
Expr operator+(Var x, Var y);
|
||||||
|
Expr operator+(Var x, double a);
|
||||||
|
Expr operator+(double a, Var x);
|
||||||
|
Expr operator-(const Expr& x);
|
||||||
|
Expr operator-(Var x);
|
||||||
|
Expr operator-(Var x, Var y);
|
||||||
|
Expr operator-(Var x, double a);
|
||||||
|
Expr operator-(double a, Var x);
|
||||||
|
Expr operator*(double a, Var x);
|
||||||
|
Expr operator*(Var x, double a);
|
||||||
|
Expr operator*(const Expr& x, double a);
|
||||||
|
Expr operator*(double a, const Expr& x);
|
||||||
|
Expr operator/(Var x, double a);
|
||||||
|
Expr operator/(const Expr& x, double a);
|
||||||
|
|
||||||
|
|
||||||
|
class Expr
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double constant;
|
||||||
|
std::vector<double> coeffs;
|
||||||
|
std::vector<Var> vars;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Expr(const Expr& expr) = default;
|
||||||
|
Expr(double constant = 0.0);
|
||||||
|
Expr(Var var, double coeff = 1.0);
|
||||||
|
|
||||||
|
friend class Model;
|
||||||
|
|
||||||
|
friend Expr operator+(const Expr& x, const Expr& y);
|
||||||
|
friend Expr operator+(const Expr& x);
|
||||||
|
friend Expr operator+(Var x, Var y);
|
||||||
|
friend Expr operator+(Var x, double a);
|
||||||
|
friend Expr operator+(double a, Var x);
|
||||||
|
friend Expr operator-(const Expr& x, const Expr& y);
|
||||||
|
friend Expr operator-(const Expr& x);
|
||||||
|
friend Expr operator-(Var x);
|
||||||
|
friend Expr operator-(Var x, Var y);
|
||||||
|
friend Expr operator-(Var x, double a);
|
||||||
|
friend Expr operator-(double a, Var x);
|
||||||
|
friend Expr operator*(double a, Var x);
|
||||||
|
friend Expr operator*(Var x, double a);
|
||||||
|
friend Expr operator*(const Expr& x, double a);
|
||||||
|
friend Expr operator*(double a, const Expr& x);
|
||||||
|
friend Expr operator/(Var x, double a);
|
||||||
|
friend Expr operator/(const Expr& x, double a);
|
||||||
|
|
||||||
|
|
||||||
|
Expr operator=(const Expr& rhs);
|
||||||
|
void operator+=(const Expr& expr);
|
||||||
|
void operator-=(const Expr& expr);
|
||||||
|
void operator*=(double mult);
|
||||||
|
void operator/=(double a);
|
||||||
|
Expr operator+(const Expr& rhs);
|
||||||
|
Expr operator-(const Expr& rhs);
|
||||||
|
};
|
||||||
|
}
|
5
inc/node.hpp
Normal file
5
inc/node.hpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Node {
|
||||||
|
|
||||||
|
};
|
345
inc/solver.hpp
345
inc/solver.hpp
@ -1,327 +1,34 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <vector>
|
#include <common.hpp>
|
||||||
using std::vector;
|
|
||||||
|
|
||||||
class Expr;
|
namespace sv {
|
||||||
class Var;
|
|
||||||
|
|
||||||
#define MDL_MINIMIZE 1
|
class Model
|
||||||
#define MDL_MAXIMIZE -1
|
{
|
||||||
|
public:
|
||||||
|
Model();
|
||||||
|
Var* addVars(int col);
|
||||||
|
void addConstr(const Expr& expr, ConstrOper sense, double rhs);
|
||||||
|
void setObjective(Expr obje, int sense = MDL_MAXIMIZE);
|
||||||
|
void print();
|
||||||
|
rtn optimize();
|
||||||
|
double get(DoubleAttr attr);
|
||||||
|
int get(IntAttr attr);
|
||||||
|
private:
|
||||||
|
double _simplex();
|
||||||
|
rtn _pivot(std::pair<size_t, size_t>& p);
|
||||||
|
void _gaussian(std::pair<size_t, size_t> p);
|
||||||
|
|
||||||
Expr operator+(const Expr& x, const Expr& y);
|
Var* vars;
|
||||||
Expr operator-(const Expr& x, const Expr& y);
|
|
||||||
Expr operator+(const Expr& x);
|
|
||||||
Expr operator+(Var x, Var y);
|
|
||||||
Expr operator+(Var x, double a);
|
|
||||||
Expr operator+(double a, Var x);
|
|
||||||
Expr operator-(const Expr& x);
|
|
||||||
Expr operator-(Var x);
|
|
||||||
Expr operator-(Var x, Var y);
|
|
||||||
Expr operator-(Var x, double a);
|
|
||||||
Expr operator-(double a, Var x);
|
|
||||||
Expr operator*(double a, Var x);
|
|
||||||
Expr operator*(Var x, double a);
|
|
||||||
Expr operator*(const Expr& x, double a);
|
|
||||||
Expr operator*(double a, const Expr& x);
|
|
||||||
Expr operator/(Var x, double a);
|
|
||||||
Expr operator/(const Expr& x, double a);
|
|
||||||
|
|
||||||
typedef vector<vector<double>> Matrix;
|
matrix mt;
|
||||||
|
size_t cn, bn;
|
||||||
enum class Rtn {
|
std::vector<int> basic;
|
||||||
LOADED,
|
rtn rtn_;
|
||||||
OPTIMAL,
|
double res_;
|
||||||
INFEASIBLE,
|
int sense;
|
||||||
INF_OR_UNBD,
|
};
|
||||||
UNBOUNDED,
|
}
|
||||||
CUTOFF,
|
|
||||||
ITERATION_LIMIT,
|
|
||||||
NODE_LIMIT,
|
|
||||||
TIME_LIMIT,
|
|
||||||
SOLUTION_LIMIT,
|
|
||||||
INTERRUPTED,
|
|
||||||
NUMERIC,
|
|
||||||
SUBOPTIMAL,
|
|
||||||
INPROGRESS,
|
|
||||||
USER_OBJ_LIMIT,
|
|
||||||
WORK_LIMIT,
|
|
||||||
MEM_LIMIT,
|
|
||||||
PIVOT,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class IntAttr {
|
|
||||||
NumConstrs,
|
|
||||||
NumVars,
|
|
||||||
NumSOS,
|
|
||||||
NumQConstrs,
|
|
||||||
NumGenConstrs,
|
|
||||||
NumNZs,
|
|
||||||
NumQNZs,
|
|
||||||
NumQCNZs,
|
|
||||||
NumIntVars,
|
|
||||||
NumBinVars,
|
|
||||||
NumPWLObjVars,
|
|
||||||
ModelSense,
|
|
||||||
IsMIP,
|
|
||||||
IsQP,
|
|
||||||
IsQCP,
|
|
||||||
IsMultiObj,
|
|
||||||
Status,
|
|
||||||
ConcurrentWinMethod,
|
|
||||||
SolCount,
|
|
||||||
BarIterCount,
|
|
||||||
VBasis,
|
|
||||||
CBasis,
|
|
||||||
PWLObjCvx,
|
|
||||||
BranchPriority,
|
|
||||||
VarPreStat,
|
|
||||||
BoundVioIndex,
|
|
||||||
BoundSVioIndex,
|
|
||||||
ConstrVioIndex,
|
|
||||||
ConstrSVioIndex,
|
|
||||||
ConstrResidualIndex,
|
|
||||||
ConstrSResidualIndex,
|
|
||||||
DualVioIndex,
|
|
||||||
DualSVioIndex,
|
|
||||||
DualResidualIndex,
|
|
||||||
DualSResidualIndex,
|
|
||||||
ComplVioIndex,
|
|
||||||
IntVioIndex,
|
|
||||||
IISMinimal,
|
|
||||||
IISLB,
|
|
||||||
IISUB,
|
|
||||||
IISConstr,
|
|
||||||
IISSOS,
|
|
||||||
IISQConstr,
|
|
||||||
IISGenConstr,
|
|
||||||
IISLBForce,
|
|
||||||
IISUBForce,
|
|
||||||
IISConstrForce,
|
|
||||||
IISSOSForce,
|
|
||||||
IISQConstrForce,
|
|
||||||
IISGenConstrForce,
|
|
||||||
TuneResultCount,
|
|
||||||
Lazy,
|
|
||||||
VarHintPri,
|
|
||||||
ObjNPriority,
|
|
||||||
NumObj,
|
|
||||||
GenConstrType,
|
|
||||||
NumStart,
|
|
||||||
Partition,
|
|
||||||
LicenseExpiration,
|
|
||||||
NumScenarios,
|
|
||||||
FuncPieces,
|
|
||||||
BatchErrorCode,
|
|
||||||
BatchStatus,
|
|
||||||
Fingerprint,
|
|
||||||
PoolIgnore,
|
|
||||||
FuncNonlinear,
|
|
||||||
ModelColumn
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class DoubleAttr{
|
|
||||||
Runtime,
|
|
||||||
Work,
|
|
||||||
ObjCon,
|
|
||||||
LB,
|
|
||||||
UB,
|
|
||||||
Obj,
|
|
||||||
Start,
|
|
||||||
PreFixVal,
|
|
||||||
RHS,
|
|
||||||
QCRHS,
|
|
||||||
Coeff,
|
|
||||||
MaxCoeff,
|
|
||||||
MinCoeff,
|
|
||||||
MaxBound,
|
|
||||||
MinBound,
|
|
||||||
MaxObjCoeff,
|
|
||||||
MinObjCoeff,
|
|
||||||
MaxRHS,
|
|
||||||
MinRHS,
|
|
||||||
MaxQCRHS,
|
|
||||||
MinQCRHS,
|
|
||||||
MaxQCCoeff,
|
|
||||||
MinQCCoeff,
|
|
||||||
MaxQCLCoeff,
|
|
||||||
MinQCLCoeff,
|
|
||||||
MaxQObjCoeff,
|
|
||||||
MinQObjCoeff,
|
|
||||||
ObjVal,
|
|
||||||
ObjBound,
|
|
||||||
ObjBoundC,
|
|
||||||
MIPGap,
|
|
||||||
IterCount,
|
|
||||||
NodeCount,
|
|
||||||
X,
|
|
||||||
RC,
|
|
||||||
Pi,
|
|
||||||
QCPi,
|
|
||||||
Slack,
|
|
||||||
QCSlack,
|
|
||||||
MaxVio,
|
|
||||||
BoundVio,
|
|
||||||
BoundSVio,
|
|
||||||
BoundVioSum,
|
|
||||||
BoundSVioSum,
|
|
||||||
ConstrVio,
|
|
||||||
ConstrSVio,
|
|
||||||
ConstrVioSum,
|
|
||||||
ConstrSVioSum,
|
|
||||||
ConstrResidual,
|
|
||||||
ConstrSResidual,
|
|
||||||
ConstrResidualSum,
|
|
||||||
ConstrSResidualSum,
|
|
||||||
DualVio,
|
|
||||||
DualSVio,
|
|
||||||
DualVioSum,
|
|
||||||
DualSVioSum,
|
|
||||||
DualResidual,
|
|
||||||
DualSResidual,
|
|
||||||
DualResidualSum,
|
|
||||||
DualSResidualSum,
|
|
||||||
ComplVio,
|
|
||||||
ComplVioSum,
|
|
||||||
IntVio,
|
|
||||||
IntVioSum,
|
|
||||||
Kappa,
|
|
||||||
KappaExact,
|
|
||||||
SAObjLow,
|
|
||||||
SAObjUp,
|
|
||||||
SALBLow,
|
|
||||||
SALBUp,
|
|
||||||
SARHSLow,
|
|
||||||
SAUBLow,
|
|
||||||
SAUBUp,
|
|
||||||
SARHSUp,
|
|
||||||
Xn,
|
|
||||||
FarkasProof,
|
|
||||||
FarkasDual,
|
|
||||||
UnbdRay,
|
|
||||||
PStart,
|
|
||||||
DStart,
|
|
||||||
BarX,
|
|
||||||
VarHintVal,
|
|
||||||
ObjN,
|
|
||||||
ObjNCon,
|
|
||||||
ObjNWeight,
|
|
||||||
ObjNRelTol,
|
|
||||||
ObjNAbsTol,
|
|
||||||
ObjNVal,
|
|
||||||
OpenNodeCount,
|
|
||||||
PoolObjBound,
|
|
||||||
PoolObjVal,
|
|
||||||
ScenNLB,
|
|
||||||
ScenNUB,
|
|
||||||
ScenNObj,
|
|
||||||
ScenNRHS,
|
|
||||||
ScenNX,
|
|
||||||
ScenNObjBound,
|
|
||||||
ScenNObjVal,
|
|
||||||
FuncPieceError,
|
|
||||||
FuncPieceLength,
|
|
||||||
FuncPieceRatio,
|
|
||||||
DNumNZs
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class StringAttr {
|
|
||||||
ModelName,
|
|
||||||
VarName,
|
|
||||||
ConstrName,
|
|
||||||
QCName,
|
|
||||||
GenConstrName,
|
|
||||||
ObjNName,
|
|
||||||
ScenNName,
|
|
||||||
BatchID,
|
|
||||||
VTag,
|
|
||||||
CTag,
|
|
||||||
QCTag,
|
|
||||||
BatchErrorMessage
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class ConstrOper {
|
|
||||||
LESS_EQUAL,
|
|
||||||
GREATER_EQUAL,
|
|
||||||
EQUAL
|
|
||||||
};
|
|
||||||
|
|
||||||
class Var {
|
|
||||||
public:
|
|
||||||
Var(double coef = 1) :col(0), val(0), coeffs(coef) {};
|
|
||||||
double get(DoubleAttr attr);
|
|
||||||
int get(IntAttr attr);
|
|
||||||
friend class Model;
|
|
||||||
friend class Expr;
|
|
||||||
private:
|
|
||||||
double coeffs;
|
|
||||||
double val;
|
|
||||||
int col;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Expr
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
double constant;
|
|
||||||
std::vector<double> coeffs;
|
|
||||||
std::vector<Var> vars;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Expr(const Expr& expr) = default;
|
|
||||||
Expr(double constant = 0.0);
|
|
||||||
Expr(Var var, double coeff = 1.0);
|
|
||||||
|
|
||||||
friend class Model;
|
|
||||||
|
|
||||||
friend Expr operator+(const Expr& x, const Expr& y);
|
|
||||||
friend Expr operator+(const Expr& x);
|
|
||||||
friend Expr operator+(Var x, Var y);
|
|
||||||
friend Expr operator+(Var x, double a);
|
|
||||||
friend Expr operator+(double a, Var x);
|
|
||||||
friend Expr operator-(const Expr& x, const Expr& y);
|
|
||||||
friend Expr operator-(const Expr& x);
|
|
||||||
friend Expr operator-(Var x);
|
|
||||||
friend Expr operator-(Var x, Var y);
|
|
||||||
friend Expr operator-(Var x, double a);
|
|
||||||
friend Expr operator-(double a, Var x);
|
|
||||||
friend Expr operator*(double a, Var x);
|
|
||||||
friend Expr operator*(Var x, double a);
|
|
||||||
friend Expr operator*(const Expr& x, double a);
|
|
||||||
friend Expr operator*(double a, const Expr& x);
|
|
||||||
friend Expr operator/(Var x, double a);
|
|
||||||
friend Expr operator/(const Expr& x, double a);
|
|
||||||
|
|
||||||
|
|
||||||
Expr operator=(const Expr& rhs);
|
|
||||||
void operator+=(const Expr& expr);
|
|
||||||
void operator-=(const Expr& expr);
|
|
||||||
void operator*=(double mult);
|
|
||||||
void operator/=(double a);
|
|
||||||
Expr operator+(const Expr& rhs);
|
|
||||||
Expr operator-(const Expr& rhs);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Model
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Model();
|
|
||||||
Var* addVars(int col);
|
|
||||||
void addConstr(const Expr& expr, ConstrOper sense, double rhs);
|
|
||||||
void setObjective(Expr obje, int sense = MDL_MAXIMIZE);
|
|
||||||
void print();
|
|
||||||
Rtn optimize();
|
|
||||||
double get(DoubleAttr attr);
|
|
||||||
int get(IntAttr attr);
|
|
||||||
private:
|
|
||||||
double _simplex();
|
|
||||||
Rtn _pivot(std::pair<size_t, size_t>& p);
|
|
||||||
void _gaussian(std::pair<size_t, size_t> p);
|
|
||||||
|
|
||||||
Var* vars;
|
|
||||||
|
|
||||||
Matrix matrix;
|
|
||||||
size_t cn, bn;
|
|
||||||
vector<int> basic;
|
|
||||||
Rtn rtn;
|
|
||||||
double res;
|
|
||||||
int sense;
|
|
||||||
};
|
|
225
src/common.cpp
Normal file
225
src/common.cpp
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
#include "common.hpp"
|
||||||
|
using namespace sv;
|
||||||
|
|
||||||
|
double Var::get(DoubleAttr attr)
|
||||||
|
{
|
||||||
|
switch (attr) {
|
||||||
|
case DoubleAttr::Coeff:
|
||||||
|
return coeffs;
|
||||||
|
case DoubleAttr::X:
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Var::get(IntAttr attr)
|
||||||
|
{
|
||||||
|
return col;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator+(const Expr& x, const Expr& y)
|
||||||
|
{
|
||||||
|
Expr exp;
|
||||||
|
exp.coeffs.resize(std::max(x.coeffs.size(), y.coeffs.size()), 0);
|
||||||
|
for (int c = 0; c < exp.coeffs.size(); c++) {
|
||||||
|
if (c < x.coeffs.size() && c < y.coeffs.size()) {
|
||||||
|
exp.coeffs[c] = x.coeffs[c] + y.coeffs[c];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
exp.coeffs[c] = c < x.coeffs.size() ? x.coeffs[c] : y.coeffs[c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exp.constant = x.constant + y.constant;
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator+(const Expr& x)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator+(Var x, Var y)
|
||||||
|
{
|
||||||
|
Expr exp;
|
||||||
|
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[y.get(IntAttr::NumCol)] = y.get(DoubleAttr::Coeff);
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator+(Var x, double a)
|
||||||
|
{
|
||||||
|
Expr exp;
|
||||||
|
exp.coeffs.resize(x.get(IntAttr::NumCol) + 1);
|
||||||
|
exp.constant = a;
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator+(double a, Var x)
|
||||||
|
{
|
||||||
|
return x + a;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator-(const Expr& x, const Expr& y)
|
||||||
|
{
|
||||||
|
Expr exp;
|
||||||
|
exp.coeffs.resize(std::max(x.coeffs.size(), y.coeffs.size()), 0);
|
||||||
|
for (int c = 0; c < exp.coeffs.size(); c++) {
|
||||||
|
if (c < x.coeffs.size() && c < y.coeffs.size()) {
|
||||||
|
exp.coeffs[c] = x.coeffs[c] - y.coeffs[c];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
exp.coeffs[c] = c < x.coeffs.size() ? x.coeffs[c] : y.coeffs[c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exp.constant = x.constant + y.constant;
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator-(const Expr& x)
|
||||||
|
{
|
||||||
|
Expr expr(x);
|
||||||
|
for (int c = 0; c < expr.coeffs.size(); c++) {
|
||||||
|
expr.coeffs[c] = -expr.coeffs[c];
|
||||||
|
}
|
||||||
|
expr.constant = -expr.constant;
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator-(Var x)
|
||||||
|
{
|
||||||
|
return -Expr(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator-(Var x, Var y)
|
||||||
|
{
|
||||||
|
Expr exp;
|
||||||
|
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[y.get(IntAttr::NumCol)] = -y.get(DoubleAttr::Coeff);
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator-(Var x, double a)
|
||||||
|
{
|
||||||
|
return x - Var(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator-(double a, Var x)
|
||||||
|
{
|
||||||
|
return x - a;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator*(double a, Var x)
|
||||||
|
{
|
||||||
|
Expr exp;
|
||||||
|
exp.coeffs.resize(x.get(IntAttr::NumCol) + 1, 0);
|
||||||
|
exp.coeffs[x.get(IntAttr::NumCol)] = a * x.get(DoubleAttr::Coeff);
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator*(Var x, double a)
|
||||||
|
{
|
||||||
|
return a * x;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator*(const Expr& x, double a)
|
||||||
|
{
|
||||||
|
Expr exp = x;
|
||||||
|
for (int c = 0; c < exp.coeffs.size(); c++) {
|
||||||
|
exp.coeffs[c] *= a;
|
||||||
|
}
|
||||||
|
exp.constant *= a;
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator*(double a, const Expr& x)
|
||||||
|
{
|
||||||
|
return x * a;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator/(Var x, double a)
|
||||||
|
{
|
||||||
|
return Expr(x) / a;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr sv::operator/(const Expr& x, double a)
|
||||||
|
{
|
||||||
|
Expr exp = x;
|
||||||
|
for (int c = 0; c < exp.coeffs.size(); c++) {
|
||||||
|
exp.coeffs[c] /= a;
|
||||||
|
}
|
||||||
|
exp.constant /= a;
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr::Expr(double constant)
|
||||||
|
:constant(constant)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr::Expr(Var var, double coeff)
|
||||||
|
{
|
||||||
|
this->coeffs.resize(var.col + 1);
|
||||||
|
this->coeffs[var.col] = coeff;
|
||||||
|
this->constant = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr Expr::operator=(const Expr& rhs)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Expr::operator+=(const Expr& expr)
|
||||||
|
{
|
||||||
|
coeffs.resize(std::max(coeffs.size(), expr.coeffs.size()));
|
||||||
|
for (int c = 0; c < expr.coeffs.size(); c++) {
|
||||||
|
coeffs[c] += expr.coeffs[c];
|
||||||
|
}
|
||||||
|
constant += expr.constant;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Expr::operator-=(const Expr& expr)
|
||||||
|
{
|
||||||
|
coeffs.resize(std::max(coeffs.size(), expr.coeffs.size()));
|
||||||
|
for (int c = 0; c < expr.coeffs.size(); c++) {
|
||||||
|
coeffs[c] -= expr.coeffs[c];
|
||||||
|
}
|
||||||
|
constant -= expr.constant;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Expr::operator*=(double mult)
|
||||||
|
{
|
||||||
|
for (int c = 0; c < coeffs.size(); c++) {
|
||||||
|
coeffs[c] *= mult;
|
||||||
|
}
|
||||||
|
constant *= mult;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Expr::operator/=(double a)
|
||||||
|
{
|
||||||
|
for (int c = 0; c < coeffs.size(); c++) {
|
||||||
|
coeffs[c] /= a;
|
||||||
|
}
|
||||||
|
constant /= a;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr Expr::operator+(const Expr& rhs)
|
||||||
|
{
|
||||||
|
coeffs.resize(std::max(coeffs.size(), rhs.coeffs.size()));
|
||||||
|
for (int c = 0; c < rhs.coeffs.size(); c++) {
|
||||||
|
coeffs[c] += rhs.coeffs[c];
|
||||||
|
}
|
||||||
|
constant += rhs.constant;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expr Expr::operator-(const Expr& rhs)
|
||||||
|
{
|
||||||
|
coeffs.resize(std::max(coeffs.size(), rhs.coeffs.size()));
|
||||||
|
for (int c = 0; c < rhs.coeffs.size(); c++) {
|
||||||
|
coeffs[c] -= rhs.coeffs[c];
|
||||||
|
}
|
||||||
|
constant -= rhs.constant;
|
||||||
|
return *this;
|
||||||
|
}
|
@ -4,6 +4,7 @@
|
|||||||
#include "solver.hpp"
|
#include "solver.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace sv;
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
@ -18,16 +19,16 @@ int main(int argc, char* argv[])
|
|||||||
mdl.setObjective(vars[0] + 2 * vars[1], MDL_MAXIMIZE);
|
mdl.setObjective(vars[0] + 2 * vars[1], MDL_MAXIMIZE);
|
||||||
|
|
||||||
switch(mdl.optimize()) {
|
switch(mdl.optimize()) {
|
||||||
case Rtn::OPTIMAL:
|
case OPTIMAL:
|
||||||
cout << "OPTIMAL SOLUTION: " << mdl.get(DoubleAttr::Obj) << endl;
|
cout << "OPTIMAL SOLUTION: " << mdl.get(DoubleAttr::Obj) << endl;
|
||||||
for (int i = 0; i < mdl.get(IntAttr::NumVars); i++) {
|
for (int i = 0; i < mdl.get(IntAttr::NumVars); i++) {
|
||||||
cout << "var[" << i << "] : " << vars[i].get(DoubleAttr::X) << endl;
|
cout << "var[" << i << "] : " << vars[i].get(DoubleAttr::X) << endl;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Rtn::INFEASIBLE:
|
case INFEASIBLE:
|
||||||
cout << "INFEASIBLE MODEL" << endl;
|
cout << "INFEASIBLE MODEL" << endl;
|
||||||
break;
|
break;
|
||||||
case Rtn::UNBOUNDED:
|
case UNBOUNDED:
|
||||||
cout << "UNBOUNDED SOLUTION" << endl;
|
cout << "UNBOUNDED SOLUTION" << endl;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
352
src/solver.cpp
352
src/solver.cpp
@ -1,148 +1,17 @@
|
|||||||
#include "solver.hpp"
|
#include "solver.hpp"
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
using namespace sv;
|
||||||
|
|
||||||
using std::make_pair;
|
using std::make_pair;
|
||||||
using std::pair;
|
using std::pair;
|
||||||
using std::cout;
|
using std::cout;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
|
using std::vector;
|
||||||
Expr operator+(const Expr& x, const Expr& y)
|
|
||||||
{
|
|
||||||
Expr exp;
|
|
||||||
exp.coeffs.resize(std::max(x.coeffs.size(), y.coeffs.size()), 0);
|
|
||||||
for (int c = 0; c < exp.coeffs.size(); c++) {
|
|
||||||
if (c < x.coeffs.size() && c < y.coeffs.size()) {
|
|
||||||
exp.coeffs[c] = x.coeffs[c] + y.coeffs[c];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
exp.coeffs[c]= c < x.coeffs.size()? x.coeffs[c] : y.coeffs[c];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exp.constant = x.constant + y.constant;
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator+(const Expr& x)
|
|
||||||
{
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator+(Var x, Var y)
|
|
||||||
{
|
|
||||||
Expr exp;
|
|
||||||
exp.coeffs.resize(std::max(x.get(IntAttr::ModelColumn) + 1, y.get(IntAttr::ModelColumn) + 1), 0);
|
|
||||||
exp.coeffs[x.get(IntAttr::ModelColumn)] = x.get(DoubleAttr::Coeff);
|
|
||||||
exp.coeffs[y.get(IntAttr::ModelColumn)] = y.get(DoubleAttr::Coeff);
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator+(Var x, double a)
|
|
||||||
{
|
|
||||||
Expr exp;
|
|
||||||
exp.coeffs.resize(x.get(IntAttr::ModelColumn) + 1);
|
|
||||||
exp.constant = a;
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator+(double a, Var x)
|
|
||||||
{
|
|
||||||
return x + a;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator-(const Expr& x, const Expr& y)
|
|
||||||
{
|
|
||||||
Expr exp;
|
|
||||||
exp.coeffs.resize(std::max(x.coeffs.size(), y.coeffs.size()), 0);
|
|
||||||
for (int c = 0; c < exp.coeffs.size(); c++) {
|
|
||||||
if (c < x.coeffs.size() && c < y.coeffs.size()) {
|
|
||||||
exp.coeffs[c] = x.coeffs[c] - y.coeffs[c];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
exp.coeffs[c] = c < x.coeffs.size() ? x.coeffs[c] : y.coeffs[c];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exp.constant = x.constant + y.constant;
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator-(const Expr& x)
|
|
||||||
{
|
|
||||||
Expr expr(x);
|
|
||||||
for (int c = 0; c < expr.coeffs.size(); c++) {
|
|
||||||
expr.coeffs[c] = -expr.coeffs[c];
|
|
||||||
}
|
|
||||||
expr.constant = -expr.constant;
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator-(Var x)
|
|
||||||
{
|
|
||||||
return -Expr(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator-(Var x, Var y)
|
|
||||||
{
|
|
||||||
Expr exp;
|
|
||||||
exp.coeffs.resize(std::max(x.get(IntAttr::ModelColumn) + 1, y.get(IntAttr::ModelColumn) + 1), 0);
|
|
||||||
exp.coeffs[x.get(IntAttr::ModelColumn)] = x.get(DoubleAttr::Coeff);
|
|
||||||
exp.coeffs[y.get(IntAttr::ModelColumn)] = -y.get(DoubleAttr::Coeff);
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator-(Var x, double a)
|
|
||||||
{
|
|
||||||
return x - Var(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator-(double a, Var x)
|
|
||||||
{
|
|
||||||
return x - a;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator*(double a, Var x)
|
|
||||||
{
|
|
||||||
Expr exp;
|
|
||||||
exp.coeffs.resize(x.get(IntAttr::ModelColumn) + 1, 0);
|
|
||||||
exp.coeffs[x.get(IntAttr::ModelColumn)] = a * x.get(DoubleAttr::Coeff);
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator*(Var x, double a)
|
|
||||||
{
|
|
||||||
return a * x;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator*(const Expr& x, double a)
|
|
||||||
{
|
|
||||||
Expr exp = x;
|
|
||||||
for (int c = 0; c < exp.coeffs.size(); c++) {
|
|
||||||
exp.coeffs[c] *= a;
|
|
||||||
}
|
|
||||||
exp.constant *= a;
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator*(double a, const Expr& x)
|
|
||||||
{
|
|
||||||
return x * a;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator/(Var x, double a)
|
|
||||||
{
|
|
||||||
return Expr(x) / a;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr operator/(const Expr& x, double a)
|
|
||||||
{
|
|
||||||
Expr exp = x;
|
|
||||||
for (int c = 0; c < exp.coeffs.size(); c++) {
|
|
||||||
exp.coeffs[c] /= a;
|
|
||||||
}
|
|
||||||
exp.constant /= a;
|
|
||||||
return exp;
|
|
||||||
}
|
|
||||||
|
|
||||||
Model::Model():
|
Model::Model():
|
||||||
cn(0),
|
cn(0),
|
||||||
@ -168,15 +37,14 @@ Var* Model::addVars(int num)
|
|||||||
|
|
||||||
void Model::addConstr(const Expr& expr, ConstrOper sense, double rhs)
|
void Model::addConstr(const Expr& expr, ConstrOper sense, double rhs)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (sense == ConstrOper::LESS_EQUAL) {
|
if (sense == ConstrOper::LESS_EQUAL) {
|
||||||
matrix.push_back(vector<double>(1, rhs - expr.constant));
|
mt.push_back(vector<double>(1, rhs - expr.constant));
|
||||||
matrix.back().insert(matrix.back().end(), expr.coeffs.begin(), expr.coeffs.end());
|
mt.back().insert(mt.back().end(), expr.coeffs.begin(), expr.coeffs.end());
|
||||||
}
|
}
|
||||||
else if (sense == ConstrOper::GREATER_EQUAL) {
|
else if (sense == ConstrOper::GREATER_EQUAL) {
|
||||||
matrix.push_back(vector<double>(1, expr.constant - rhs));
|
mt.push_back(vector<double>(1, expr.constant - rhs));
|
||||||
for (int coeff : expr.coeffs) {
|
for (int coeff : expr.coeffs) {
|
||||||
matrix.back().push_back(-coeff);
|
mt.back().push_back(-coeff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -184,8 +52,8 @@ void Model::addConstr(const Expr& expr, ConstrOper sense, double rhs)
|
|||||||
addConstr(expr, ConstrOper::GREATER_EQUAL, rhs);
|
addConstr(expr, ConstrOper::GREATER_EQUAL, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int c = matrix.back().size(); c <= cn; c++) {
|
for (int c = mt.back().size(); c <= cn; c++) {
|
||||||
matrix.back().push_back(0);
|
mt.back().push_back(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,47 +61,48 @@ void Model::setObjective(Expr obje, int _sense)
|
|||||||
{
|
{
|
||||||
assert(_sense == 1 || _sense == -1);
|
assert(_sense == 1 || _sense == -1);
|
||||||
if (sense == 0) {
|
if (sense == 0) {
|
||||||
matrix.insert(matrix.begin(), obje.coeffs);
|
mt.insert(mt.begin(), obje.coeffs);
|
||||||
matrix.front().insert(matrix.front().begin(), -obje.constant);
|
mt.front().insert(mt.front().begin(), -obje.constant);
|
||||||
for (int c = obje.coeffs.size() + 1; c <= cn; c++) {
|
for (int c = obje.coeffs.size() + 1; c <= cn; c++) {
|
||||||
matrix.front().push_back(0);
|
mt.front().push_back(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
matrix.front().front() = -obje.constant;
|
mt.front().front() = -obje.constant;
|
||||||
for (int c = 0; c < obje.coeffs.size(); c++) {
|
for (int c = 0; c < cn; c++) {
|
||||||
matrix.front()[c + 1] = obje.coeffs[c];
|
if (c < obje.coeffs.size()) {
|
||||||
|
mt.front()[c + 1] = obje.coeffs[c];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mt.front()[c] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int c = obje.coeffs.size() + 1; c <= cn; c++) {
|
|
||||||
matrix.front()[c] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
sense = _sense;
|
sense = _sense;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::print()
|
void Model::print()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < matrix.size(); i++) {
|
for (size_t i = 0; i < mt.size(); i++) {
|
||||||
for (size_t j = 0; j < matrix[0].size(); j++) {
|
for (size_t j = 0; j < mt[0].size(); j++) {
|
||||||
cout << matrix[i][j] << "\t";
|
cout << mt[i][j] << "\t";
|
||||||
}
|
}
|
||||||
cout << endl;
|
cout << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rtn Model::optimize()
|
rtn Model::optimize()
|
||||||
{
|
{
|
||||||
bn = matrix.size();
|
bn = mt.size();
|
||||||
for (int row = 1; row < bn; row++) {
|
for (int row = 1; row < bn; row++) {
|
||||||
matrix.front().push_back(0);
|
mt.front().push_back(0);
|
||||||
for (int col = 1; col < bn; col++) {
|
for (int col = 1; col < bn; col++) {
|
||||||
matrix[row].push_back(col == row ? 1 : 0);
|
mt[row].push_back(col == row ? 1 : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cn = matrix.front().size();
|
cn = mt.front().size();
|
||||||
for (int i = 0; i < cn; i++) {
|
for (int i = 0; i < cn; i++) {
|
||||||
matrix.front()[i] = sense * matrix.front()[i];
|
mt.front()[i] = sense * mt.front()[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 1; i < bn; i++) {
|
for (size_t i = 1; i < bn; i++) {
|
||||||
@ -243,7 +112,7 @@ Rtn Model::optimize()
|
|||||||
// === <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 (matrix[row].front() < 0) {
|
if (mt[row].front() < 0) {
|
||||||
initial_feasible = false;
|
initial_feasible = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -251,29 +120,29 @@ Rtn Model::optimize()
|
|||||||
|
|
||||||
// === <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 = matrix.front();
|
vector<double> coeff = mt.front();
|
||||||
matrix.front() = vector<double>(cn, .0);
|
mt.front() = vector<double>(cn, .0);
|
||||||
matrix.front().push_back(1);
|
mt.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++) {
|
||||||
matrix[row].push_back(-1);
|
mt[row].push_back(-1);
|
||||||
if (t.first == -1 || matrix[row].front() < matrix[t.first].front()) {
|
if (t.first == -1 || mt[row].front() < mt[t.first].front()) {
|
||||||
t.first = row;
|
t.first = row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_gaussian(t);
|
_gaussian(t);
|
||||||
if (fabs(_simplex()) > 1e-10) {
|
if (fabs(_simplex()) > 1e-10) {
|
||||||
rtn = Rtn::INFEASIBLE;
|
rtn_ = INFEASIBLE;
|
||||||
return rtn;
|
return rtn_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 < matrix.front().size(); col++) {
|
for (int col = 1; col < mt.front().size(); col++) {
|
||||||
if (fabs(matrix.front()[col]) > 1e-10) {
|
if (fabs(mt.front()[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;
|
||||||
@ -282,33 +151,33 @@ Rtn Model::optimize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int row = 0; row < bn; row++) {
|
for (int row = 0; row < bn; row++) {
|
||||||
matrix[row].pop_back();
|
mt[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++) {
|
||||||
matrix.front()[col] = coeff[col];
|
mt.front()[col] = coeff[col];
|
||||||
}
|
}
|
||||||
for (int row = 1; row <= basic.size(); row++) {
|
for (int row = 1; row <= basic.size(); row++) {
|
||||||
int norm = matrix.front()[basic[row - 1]];
|
int norm = mt.front()[basic[row - 1]];
|
||||||
for (int col = 0; col < cn; col++) {
|
for (int col = 0; col < cn; col++) {
|
||||||
matrix.front()[col] -= norm * matrix[row][col];
|
mt.front()[col] -= norm * mt[row][col];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = -sense * _simplex();
|
res_ = -sense * _simplex();
|
||||||
for (int row = 1; row < bn; row++) {
|
for (int row = 1; row < bn; row++) {
|
||||||
if (basic[row - 1] - 1 < cn - bn) {
|
if (basic[row - 1] - 1 < cn - bn) {
|
||||||
vars[basic[row - 1] - 1].val = matrix[row].front();
|
vars[basic[row - 1] - 1].val = mt[row].front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rtn;
|
return rtn_;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Model::get(DoubleAttr attr)
|
double Model::get(DoubleAttr attr)
|
||||||
{
|
{
|
||||||
return res;
|
return res_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Model::get(IntAttr attr)
|
int Model::get(IntAttr attr)
|
||||||
@ -320,20 +189,20 @@ double Model::_simplex()
|
|||||||
{
|
{
|
||||||
pair<size_t, size_t> t;
|
pair<size_t, size_t> t;
|
||||||
while (1) {
|
while (1) {
|
||||||
rtn = _pivot(t);
|
rtn_ = _pivot(t);
|
||||||
if (rtn == Rtn::OPTIMAL || rtn == Rtn::UNBOUNDED) {
|
if (rtn_ == OPTIMAL || rtn_ == UNBOUNDED) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_gaussian(t);
|
_gaussian(t);
|
||||||
}
|
}
|
||||||
return matrix.front().front();
|
return mt.front().front();
|
||||||
}
|
}
|
||||||
|
|
||||||
Rtn Model::_pivot(pair<size_t, size_t>& p)
|
rtn Model::_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 = matrix.front();
|
vector<double> coef = mt.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 i = 1; i < coef.size(); i++) {
|
||||||
@ -343,29 +212,29 @@ Rtn Model::_pivot(pair<size_t, size_t>& p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cmin >= 0) {
|
if (cmin >= 0) {
|
||||||
return Rtn::OPTIMAL;
|
return OPTIMAL;
|
||||||
}
|
}
|
||||||
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 = matrix[row].front() / matrix[row][p.second];
|
double tmp = mt[row].front() / mt[row][p.second];
|
||||||
if (matrix[row][p.second] > 0 && bmin > tmp) {
|
if (mt[row][p.second] > 0 && bmin > tmp) {
|
||||||
bmin = tmp;
|
bmin = tmp;
|
||||||
p.first = row;
|
p.first = row;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abs(bmin - INT_MAX) < 1e-10) {
|
if (abs(bmin - INT_MAX) < 1e-10) {
|
||||||
return Rtn::UNBOUNDED;
|
return UNBOUNDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto iter = basic.begin(); iter != basic.end(); iter++) {
|
for (auto iter = basic.begin(); iter != basic.end(); iter++) {
|
||||||
if (matrix[p.first][*iter] != 0) {
|
if (mt[p.first][*iter] != 0) {
|
||||||
*iter = p.second;
|
*iter = p.second;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(basic[p.first - 1] == p.second);
|
assert(basic[p.first - 1] == p.second);
|
||||||
return Rtn::PIVOT;
|
return PIVOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::_gaussian(pair<size_t, size_t> p)
|
void Model::_gaussian(pair<size_t, size_t> p)
|
||||||
@ -373,9 +242,9 @@ void Model::_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 = matrix[x][y];
|
double norm = mt[x][y];
|
||||||
for (size_t col = 0; col < matrix[x].size(); col++) {
|
for (size_t col = 0; col < mt[x].size(); col++) {
|
||||||
matrix[x][col] /= norm;
|
mt[x][col] /= norm;
|
||||||
}
|
}
|
||||||
|
|
||||||
// === <20><><EFBFBD><EFBFBD><EFBFBD>б任 ===
|
// === <20><><EFBFBD><EFBFBD><EFBFBD>б任 ===
|
||||||
@ -383,100 +252,13 @@ void Model::_gaussian(pair<size_t, size_t> p)
|
|||||||
if (row == x) {
|
if (row == x) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (matrix[row][y] != 0) {
|
if (mt[row][y] != 0) {
|
||||||
double norm = matrix[row][y];
|
double norm = mt[row][y];
|
||||||
for (size_t col = 0; col < matrix[x].size(); col++) {
|
for (size_t col = 0; col < mt[x].size(); col++) {
|
||||||
matrix[row][col] = matrix[row][col] - norm * matrix[x][col];
|
mt[row][col] = mt[row][col] - norm * mt[x][col];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
basic[x - 1] = y; // <20><>Ԫ
|
basic[x - 1] = y; // <20><>Ԫ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Expr::Expr(double constant)
|
|
||||||
:constant(constant)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr::Expr(Var var, double coeff)
|
|
||||||
{
|
|
||||||
this->coeffs.resize(var.col + 1);
|
|
||||||
this->coeffs[var.col] = coeff;
|
|
||||||
this->constant = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr Expr::operator=(const Expr& rhs)
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Expr::operator+=(const Expr& expr)
|
|
||||||
{
|
|
||||||
coeffs.resize(std::max(coeffs.size(), expr.coeffs.size()));
|
|
||||||
for (int c = 0; c < expr.coeffs.size(); c++) {
|
|
||||||
coeffs[c] += expr.coeffs[c];
|
|
||||||
}
|
|
||||||
constant += expr.constant;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Expr::operator-=(const Expr& expr)
|
|
||||||
{
|
|
||||||
coeffs.resize(std::max(coeffs.size(), expr.coeffs.size()));
|
|
||||||
for (int c = 0; c < expr.coeffs.size(); c++) {
|
|
||||||
coeffs[c] -= expr.coeffs[c];
|
|
||||||
}
|
|
||||||
constant -= expr.constant;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Expr::operator*=(double mult)
|
|
||||||
{
|
|
||||||
for (int c = 0; c < coeffs.size(); c++) {
|
|
||||||
coeffs[c] *= mult;
|
|
||||||
}
|
|
||||||
constant *= mult;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Expr::operator/=(double a)
|
|
||||||
{
|
|
||||||
for (int c = 0; c < coeffs.size(); c++) {
|
|
||||||
coeffs[c] /= a;
|
|
||||||
}
|
|
||||||
constant /= a;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr Expr::operator+(const Expr& rhs)
|
|
||||||
{
|
|
||||||
coeffs.resize(std::max(coeffs.size(), rhs.coeffs.size()));
|
|
||||||
for (int c = 0; c < rhs.coeffs.size(); c++) {
|
|
||||||
coeffs[c] += rhs.coeffs[c];
|
|
||||||
}
|
|
||||||
constant += rhs.constant;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expr Expr::operator-(const Expr& rhs)
|
|
||||||
{
|
|
||||||
coeffs.resize(std::max(coeffs.size(), rhs.coeffs.size()));
|
|
||||||
for (int c = 0; c < rhs.coeffs.size(); c++) {
|
|
||||||
coeffs[c] -= rhs.coeffs[c];
|
|
||||||
}
|
|
||||||
constant -= rhs.constant;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
double Var::get(DoubleAttr attr)
|
|
||||||
{
|
|
||||||
switch (attr) {
|
|
||||||
case DoubleAttr::Coeff:
|
|
||||||
return coeffs;
|
|
||||||
case DoubleAttr::X:
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Var::get(IntAttr attr)
|
|
||||||
{
|
|
||||||
return col;
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user