From 3b36e04bc4e0ef7ac3c968eb854f266946516b52 Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sat, 5 Nov 2016 18:28:07 +0100 Subject: Initial --- .gitignore | 4 + Makefile | 24 +++++ lp.cpp | 19 ++++ problem.cpp | 311 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ problem.h | 126 ++++++++++++++++++++++++ 5 files changed, 484 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 lp.cpp create mode 100644 problem.cpp create mode 100644 problem.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..70014ba --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +lp +*.dSYM +.DS_Store diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a8bf246 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +CXX = g++ +CXXFLAGS = -Wall -Wextra -std=c++11 -fwrapv +ifneq ($(DEBUG),) + CXXFLAGS += -g +else + CXXFLAGS += -O2 +endif +BIN = lp + +.PHONY: all clean remake + +all: $(BIN) + +clean: + rm -rf $(BIN) *.o *.dSYM + +remake: clean all + + +$(BIN): $(patsubst %.cpp,%.o,$(wildcard *.cpp)) + $(CXX) -o $@ $^ + +%.o: %.cpp $(wildcard *.h) + $(CXX) $(CXXFLAGS) -c -o $@ $< diff --git a/lp.cpp b/lp.cpp new file mode 100644 index 0000000..2a4a283 --- /dev/null +++ b/lp.cpp @@ -0,0 +1,19 @@ +#include +#include "problem.h" + +using namespace std; + +int main(){ + Problem problem(cin); + cout< vec=problem.solutionVars(); + cout<<"variable values:"; + for(double v : vec)cout<<' '< +#include +#include +#include "problem.h" + +#define DEBUG + +using namespace std; + +Problem::Problem(istream &in){ + in>>*this; +} + +template +void rowopadd(int n,T &dst,const U &src,double times){ + for(int i=0;i +void rowopmult(int n,T &dst,double times){ + for(int i=0;i +int min_index(const vector &v){ + if(v.size()==0)throw logic_error("No minimum element in empty vector"); + int mi=0; + int size=v.size(); + for(int i=1;i origzfunc=zfunc; + for(int j=0;j=0&&vartype[j]==VT_ART;j--){ + removefrombasis(j); + nart++; + } + vartype.resize(nvars-nart); + zfunc.resize(nvars-nart); + restr.resize(nvars-nart,restr.height()); + +#ifdef DEBUG + cerr<<" === SOLVING ORIGINAL PROBLEM ==="<=0)break; //optimal solution found + int pivotrestr=-1; + for(int i=0;i>(istream &in,Problem &prob){ + string type; + in>>type; + bool negate=false; + if(type=="max")negate=true; + else if(type!="min")throw invalid_argument("Invalid LP problem type"); + int nvars,nrestr; + in>>nvars>>nrestr; + if(nvars<=0)throw invalid_argument("Invalid number of variables"); + if(nrestr<=0)throw invalid_argument("Invalid number of restrictions"); + prob.vartype.clear(); prob.vartype.resize(nvars); + prob.zfunc.clear(); prob.zfunc.resize(nvars); + prob.restr.clear(); prob.restr.resize(nvars,nrestr); + prob.bvec.clear(); prob.bvec.resize(nrestr); + prob.basis.clear(); prob.basis.resize(nrestr,-1); + for(int i=0;i addslack(nrestr,0),addart(nrestr,0); + for(int i=0;i="; + else if(type==">=")type="<="; + } + if(type=="<="){ + addslack[i]=1; + } else if(type==">="){ + addslack[i]=-1; + addart[i]=1; + } else if(type=="="){ + addart[i]=1; + } else { + throw invalid_argument("Invalid restriction type"); + } + } + for(int i=0;i +#include +#include + +using namespace std; + +template +class Matrix{ + vector> mat; //list of rows + int W=0,H=0; + +public: + template + class RowAccess{ + vector &row; + public: + RowAccess(vector &row):row(row){} + T& operator[](int x){return row[x];} + const T& operator[](int x) const {return row[x];} + T& front(){return row.front();} + const T& front() const {return row.front();} + T& back(){return row.back();} + const T& back() const {return row.back();} + }; + + template + class ConstRowAccess{ + const vector &row; + public: + ConstRowAccess(const vector &row):row(row){} + const T& operator[](int x) const {return row[x];} + const T& front() const {return row.front();} + const T& back() const {return row.back();} + }; + + Matrix() = default; + + Matrix(int W,int H) + :W(W),H(H){ + mat.resize(H); + for(auto &row : mat){ + row.resize(W); + } + } + + void addrow(){ + mat.emplace_back(W,T()); + H++; + } + + void addcolumn(){ + for(auto &row : mat){ + row.emplace_back(); + } + W++; + } + + void resize(int w,int h){ + if(hH){ + mat.resize(h); + for(int i=H;i operator[](int y){ + return RowAccess(mat[y]); + } + + ConstRowAccess operator[](int y) const { + return ConstRowAccess(mat[y]); + } + + int width() const {return W;} + + int height() const {return H;} +}; + +class Problem{ + enum VarType{ + VT_NORMAL=0, + VT_SLACK, + VT_ART, + }; + vector vartype; + vector zfunc; + double zvalue=0; + Matrix restr; + vector bvec; + vector basis; + + void removefrombasis(int varidx); + void solve_noart(); + +public: + Problem(const Problem&) = default; + Problem(istream &in); + + void solve(); + double solutionValue() const; + vector solutionVars() const; + + friend istream& operator>>(istream &in,Problem &prob); + friend ostream& operator<<(ostream &os,const Problem &prob); +}; + +istream& operator>>(istream &in,Problem &prob); +ostream& operator<<(ostream &os,const Problem &prob); -- cgit v1.2.3-70-g09d2