void generateSimplexTab(const std::vector<Constraint<ArgType>>& constraints, const ObjectiveFunction<ArgType, RetType, CoeffType>& function, Matrix<CoeffType>& simplexTab) { unsigned long cols = simplexTab.getColumnsNumber(), rows = simplexTab.getRowsNumber(), constrNum = constraints.size(), argsNum = function.size(); if(constrNum + 1 != rows || argsNum + constrNum + 2 != cols) throw "simplexTab has not proper size"; for (unsigned long i = 0; i < constrNum; i++) //generuje część odpowiedzialna za ograniczenia pod argumentami for (unsigned long j = 0; j < argsNum; j++) simplexTab(i, j) = constraints[i].getCoeff(j); for (unsigned long j = 0; j < argsNum; j++) // generuje dolną część tablicy pod argumentami simplexTab(rows - 1, j) = -function.getCoeff(j); for (unsigned long j = 0; j < constrNum; j++) // generuje część związaną ze zmiennymi dodatkowymi simplexTab(j, j + argsNum) = 1; for (unsigned long j = 0; j < constrNum; j++) // część pod p - same zera simplexTab(j, argsNum + constrNum) = 0; for (unsigned long j = 0; j < constrNum; j++) // ostatnia kolumna, kolumna B simplexTab(j, argsNum + constrNum + 1) = constraints[j].getB(); for (unsigned long j = argsNum; j < argsNum + constrNum - 1; j++) //ostatni wiersz pod zmienn. dodatk. - same zera simplexTab(rows - 1, j) = 0; simplexTab(rows - 1, cols - 2) = 1; simplexTab(rows - 1, cols - 1) = 0; }
FunctionArguments<ArgType> simplex( const std::vector<Constraint<ArgType>>& constraints, const ObjectiveFunction<ArgType, RetType, CoeffType>& function) { if(constraints.size() == 0) throw "No constraints"; if(constraints[0].size() != function.size()) throw "Size of constraints not equal to function size"; Matrix<CoeffType> simplexTab(constraints.size() + 1, function.size() + constraints.size() + 2); unsigned long cols = simplexTab.getColumnsNumber(), rows = simplexTab.getRowsNumber(), constrNum = constraints.size(), argsNum = function.size(); generateSimplexTab(constraints, function, simplexTab); std::map<unsigned long,unsigned long> slackSwaped; while (simplexTab.countIfInRange(rows - 1, 0, rows - 1, cols - 1, [](const CoeffType& x) { return x<0;})) { unsigned long pivotColumn, row; simplexTab.findMinimumInRange(rows - 1, 0, rows - 1, cols - 3, row, pivotColumn); row = findMinInColumnBDiv(simplexTab, pivotColumn); slackSwaped[row]=pivotColumn; simplexTab.multiplyRow(1/simplexTab(row,pivotColumn),row); for(unsigned long j=0;j<rows;j++) if(j!=row) simplexTab.addRow(-simplexTab(j,pivotColumn),row,j); } std::cout<<simplexTab; FunctionArguments<ArgType> bestSolution; bestSolution.size(argsNum); for(unsigned long j=0;j<constrNum;j++) bestSolution.setArg(slackSwaped[j],simplexTab(j,cols-1)); return bestSolution; }