vector<int> rightSideView(TreeNode* root) { vector<int>v; if (root == NULL) return v; int tmp = 1; v.push_back(root->val); getRightSide(v, tmp + 1, root->right); getRightSide(v, tmp + 1, root->left); return v; }
void getRightSide(vector<int> &v, int tmp, TreeNode* root) { if (root == NULL) { return; } int len = v.size(); if (tmp > len) { v.push_back(root->val); } getRightSide(v, tmp + 1, root->right); getRightSide(v, tmp + 1, root->left); return; }
SimplexResult Tableau::endPhase1() { const int constraintCount = getConstraintCount(); for(int row = 1; row <= constraintCount; row++) { const int bv = m_table[row].m_basisVariable; if(bv >= getArtificialColumn(1)) { trace(TRACE_WARNINGS,_T("endPhase1:Artificial variabel %s not eliminated. Value=%lg"), getVariableName(bv).cstr(),getDouble(getRightSide(row))); traceTableau(); if(getRightSide(row) == 0) { return SIMPLEX_NO_SOLUTION_FOUND; } else { return SIMPLEX_NO_SOLUTION; } } } // Delete all artificial variables m_artificialCount = 0; // Restore original costFactors int col; for(col = 1; col <= getXCount(); col++) { objectFactor(col) = m_costFactor[col]; } for(int index = 1; col <= (int)m_slackCount; index++) { objectFactor(getSlackColumn(index)) = 0; } return SIMPLEX_SOLUTION_OK; }
SimplexResult Tableau::dualSimplex() { const int constraintCount = getConstraintCount(); const int width = getWidth(); for(int iteration = 1;; iteration++) { if(isTracing(TRACE_ITERATIONS)) { trace(_T("Dual simplex. Iteration %d."), iteration); traceTableau(); // traceBasis(_T("Current basis:")); } int pivotRow; Real minR = 1; for(int row = 1; row <= constraintCount; row++) { // find pivot row if(getRightSide(row) < minR) { pivotRow = row; minR = getRightSide(row); } } if(minR >= 0) { // Every rightside is nonNegative return SIMPLEX_SOLUTION_OK; } int pivotColumn = -1; Real minRatio = 0; const CompactArray<Real> &tableRow = m_table[pivotRow].m_a; for(int col = 1; col <= width; col++) { // find pivot col const Real &a = tableRow[col]; if(a < 0) { Real ratio = -getObjectFactor(col)/a; if(pivotColumn == -1 || ratio < minRatio) { minRatio = ratio; pivotColumn = col; } } } // printf(_T("pivotColumn:%d\n"),pivotColumn); if(pivotColumn == -1) { return SIMPLEX_NO_SOLUTION; } pivot(pivotRow,pivotColumn,false); } }
CompactArray<BasisVariable> Tableau::getBasisVariables() const { CompactArray<BasisVariable> result; for(int r = 1; r <= getConstraintCount(); r++) { const int index = m_table[r].m_basisVariable; result.add(BasisVariable(getVariablePrefix(index), index, getRightSide(r), (index <= getXCount()) ? getCostFactor(index) : 0)); } return result; }
bool Tableau::isPrimalFeasible() const { const int constraintCount = getConstraintCount(); for(int row = 1; row <= constraintCount; row++) { if(getRightSide(row) < 0) { return false; } } return true; }
String Tableau::toString(int fieldSize, int decimals) const { const String matrixFormatString = format(_T("%%%d.%dlg "), fieldSize, decimals); const TCHAR *matrixFormat = matrixFormatString.cstr(); const int width = getWidth(); const int constraintCount = getConstraintCount(); #define NEWLINE _T('\n') const String separatorLine = format(_T("%s\n"), spaceString(12 + (width+1) * (fieldSize+1) + 3,_T('_')).cstr()); String result; result += format(_T("%-23sB %-*s"), format(_T("size:%dx%d"),getConstraintCount(),getWidth()).cstr(),fieldSize-8,EMPTYSTRING); for(int col = 1; col <= width; col++) { result += format(_T("%*s "), fieldSize, getVariableName(col).cstr()); } result += NEWLINE; result += separatorLine; result += format(_T("%-*s"), 17+fieldSize, _T("Orig. cost: ")); for(int col = 1; col <= getXCount(); col++) { result += format(matrixFormat, getDouble(m_costFactor[col])); } result += NEWLINE; result += _T("ObjectValue:"); result += format(matrixFormat, getDouble(getObjectValue())); result += _T(" "); // filler instead of relation for(int col = 1; col <= width; col++) { result += format(matrixFormat, getDouble(getObjectFactor(col))); } result += NEWLINE; result += separatorLine; const bool printOriginalRelation = (m_slackCount == 0); for(int r = 1; r <= constraintCount; r++ ) { const TableauRow &row = m_table[r]; result += format(_T("%3d %-6s ="),r, getVariableName(row.m_basisVariable).cstr()); result += format(matrixFormat,getDouble(getRightSide(r))); result += format(_T(" %-2s "), printOriginalRelation ? getRelationString(reverseRelation(row.m_relation)) : _T("=")); for(int col = 1; col <= width; col++) { result += format(matrixFormat,getDouble(row.m_a[col])); } result += NEWLINE; } return result; }
void Tableau::preparePhase1() { m_slackCount = getInequalityCount(); m_artificialCount = getConstraintCount(); const int constraintCount = getConstraintCount(); int slackIndex = 1; for(int row = 1; row <= constraintCount; row++) { for(UINT index = 1; index <= m_slackCount; index++) { // Clear Slack matrix slackVar(row,index) = 0; } for(UINT index = 1; index <= m_artificialCount; index++) { // Clear Artificial matrix artificalVar(row,index) = 0; } artificalVar(row,row) = 1; Real slackFactor = getSlackFactor(m_table[row].m_relation); if(slackFactor != 0) { // Set Slack[row,slackIndex] slackVar(row,slackIndex) = slackFactor; slackIndex++; } if(getRightSide(row) < 0) { multiplyRow(row,-1); } } // Set temporary object function, with cost factors = 1 for all artificial variables and 0 for the other variables for(int row = 1; row <= constraintCount; row++) { int c = m_table[row].m_basisVariable = getArtificialColumn(row); objectFactor(c) = 1; } for(int col = 1; col <= getXCount(); col++) { objectFactor(col) = 0; } for(UINT index = 1; index <= m_slackCount; index++) { objectFactor(getSlackColumn(index)) = 0; } }
void Tableau::pivot(size_t pivotRow, size_t pivotColumn, bool primalSimplex) { TableauRow &row = m_table[pivotRow]; const int leaveBasis = row.m_basisVariable; const int enterBasis = (int)pivotColumn; row.m_basisVariable = (int)pivotColumn; const Real &factor = row.m_a[pivotColumn]; const String enteringVarName = getVariableName(enterBasis); const String leavingVarName = getVariableName(leaveBasis); if(isTracing(TRACE_PIVOTING)) { if(primalSimplex) { trace(_T("pivot(%2s,%2s). %s -> %s. Cost[%s]:%-15.10lg Tab[%2s,%2s]=%-15.10lg Minimum:%-15.10lg") ,FSZ(pivotRow),FSZ(pivotColumn) ,enteringVarName.cstr(),leavingVarName.cstr() ,enteringVarName.cstr(),getDouble(getObjectFactor(pivotColumn)) ,FSZ(pivotRow),FSZ(pivotColumn),getDouble(factor) ,getDouble(getObjectValue())); } else { trace(_T("pivot(%2s,%2s). %s -> %s. %s=B[%2s]:%-15.10lg Tab[%2s,%2s]=%-15.10lg Minimum:%-15.10lg") ,FSZ(pivotRow),FSZ(pivotColumn) ,enteringVarName.cstr(),leavingVarName.cstr() ,leavingVarName.cstr(),FSZ(pivotRow),getDouble(getRightSide(pivotRow)) ,FSZ(pivotRow),FSZ(pivotColumn),getDouble(factor) ,getDouble(getObjectValue())); } } multiplyRow(pivotRow,1.0/factor); for(int dstRow = 0; dstRow <= getConstraintCount(); dstRow++) { if(dstRow != (int)pivotRow) { addRowsToGetZero(dstRow,pivotRow,pivotColumn); } } }
void RectangleSDL::move(Box2D *limit) { colliding = false; if ( hor ) { if ( getRightSide() + speed >= limit->getRightSide() ) { hor = false; colliding = true; } else { addX(speed); } } else { if ( getLeftSide() - speed <= limit->getLeftSide() ) { hor = true; colliding = true; } else { addX(-speed); } } if ( vert ) { if ( getBottomSide() + speed >= limit->getBottomSide() ) { vert = false; colliding = true; } else { addY(speed); } } else { if ( getTopSide() - speed <= limit->getTopSide() ) { vert = true; colliding = true; } else { addY(-speed); } } }
// Parameter phase only for tracing SimplexResult Tableau::primalSimplex(int phase) { const int width = getWidth(); const int constraintCount = getConstraintCount(); for(int r = 1; r <= constraintCount; r++) { const TableauRow &row = m_table[r]; const int bv = row.m_basisVariable; const Real &a = row.m_a[bv]; if(a == 0) { continue; } Real factor = getObjectFactor(bv) / a; if(factor == 0) { trace(TRACE_WARNINGS,_T("Warning:Cost factor[%s] = 0."), getVariableName(bv).cstr()); continue; } for(int col = 0; col <= width; col++) { objectFactor(col) -= row.m_a[col] * factor; } objectFactor(bv) = 0; } bool looping = false; for(int iteration = 1;; iteration++) { if(isTracing(TRACE_ITERATIONS)) { trace(_T("Phase %d. Iteration %d"), phase, iteration); traceTableau(); // traceBasis(_T("Current basis:")); } int pivotColumn; Real minCost = 1; if(looping) { for(int col = 1; col <= width; col++) { // Apply Bland's anti-cycling rule step 1. const Real &cc = objectFactor(col); if(cc < -EPS) { minCost = cc; pivotColumn = col; break; } } } else { // else find pivot column the old way for(int col = 1; col <= width; col++) { const Real &cc = objectFactor(col); if(cc < minCost) { minCost = cc; pivotColumn = col; } } } if(minCost >= -EPS) { return SIMPLEX_SOLUTION_OK; // Optimal value found } int pivotRow = -1; Real minRatio = 0; if(looping) { // apply Bland's anti-cycling rule step 2. for(int r = 1; r <= constraintCount; r++) { const Real &ar = m_table[r].m_a[pivotColumn]; if(ar > 10*EPS) { const Real &br = getRightSide(r); const Real ratio = br / ar; if((pivotRow == -1) || (ratio < minRatio)) { minRatio = ratio; pivotRow = r; } } } if(pivotRow >= 0) { int minIndex = -1; for(int r = 1; r <= constraintCount; r++) { const Real &ar = m_table[r].m_a[pivotColumn]; if(ar > 10*EPS) { const Real &br = getRightSide(r); const Real ratio = br / ar; if(ratio == minRatio) { const int index = m_table[r].m_basisVariable; if(minIndex == -1 || index < minIndex) { minIndex = index; pivotRow = r; } } } } } } else { // else find pivot row the old way for(int r = 1; r <= constraintCount; r++) { const Real &ar = m_table[r].m_a[pivotColumn]; if(ar > EPS) { const Real &br = getRightSide(r); const Real ratio = br / ar; if(pivotRow == -1 || ratio < minRatio) { minRatio = ratio; pivotRow = r; } } } } if(pivotRow == -1) { return SIMPLEX_SOLUTION_UNLIMITED; } // Check for degeneracy traceDegeneracy(pivotRow, pivotColumn, minRatio); DictionaryKey dictKey(this); if(m_dictionarySet.contains(dictKey)) { looping = true; trace(TRACE_WARNINGS, _T("Looping. Applying Blands anti cycling rule.")); } else { m_dictionarySet.add(dictKey); } pivot(pivotRow,pivotColumn,true); } }
void Tableau::addConstraint(size_t xIndex, SimplexRelation relation, const Real &rightSide) { if(xIndex < 1 || (int)xIndex >= getXCount()) { throwException(_T("addConstraint:Invalid xIndex=%s. Valid interval=[1..%s]"), FSZ(xIndex), FSZ(getXCount())); } Real currentValue = 0; int bvRow = -1; for(size_t i = 1; i < m_table.size(); i++) { if(m_table[i].m_basisVariable == (int)xIndex) { currentValue = getRightSide(i); bvRow = (int)i; break; } } String varName = getVariableName(xIndex); switch(relation) { case EQUALS : if(currentValue == rightSide) { trace(_T("addConstraint:No need to add constraint %s = %-16lg. %s already has the specified value."), varName.cstr(), getDouble(rightSide), varName.cstr()); return; } else if(currentValue < rightSide) { relation = GREATERTHAN; } else { relation = LESSTHAN; } break; case LESSTHAN : if(currentValue <= rightSide) { trace(_T("addConstraint:No need to add constraint %s <= %-16lg. %s=%-16lg."), varName.cstr(), getDouble(rightSide), varName.cstr(), getDouble(currentValue)); return; } break; case GREATERTHAN: if(currentValue >= rightSide) { trace(_T("addConstraint:No need to add constraint %s >= %-16lg. %s=%-16lg."), varName.cstr(), getDouble(rightSide), varName.cstr(), getDouble(currentValue)); return; } break; } if(isTracing(TRACE_ITERATIONS)) { trace(_T("Add constraint %s %s %lg"), varName.cstr(), getRelationString(relation), getDouble(rightSide)); } m_table.add(TableauRow(getMaxColumnCount())); const int newRowIndex = getConstraintCount(); addSlackColumn(); TableauRow &newRow = m_table[newRowIndex]; newRow.m_a[xIndex] = 1; slackVar(newRowIndex,m_slackCount) = getSlackFactor(relation); setRightSide(newRowIndex,rightSide); newRow.m_basisVariable = getSlackColumn(m_slackCount); objectFactor(newRow.m_basisVariable) = 1; // if(isTracing()) trace(_T("addConstraint before normalizing:\n %s"),toString().cstr()); if(bvRow >= 0) { addRowsToGetZero(newRowIndex,bvRow,xIndex); } if(getRightSide(newRowIndex) > 0) multiplyRow(newRowIndex,-1); // objectValue() += getRightSide(newRowIndex); }
String Grammar::getProductionString(int prod) const { return getSymbol(m_productions[prod].m_leftSide).m_name + _T(" -> ") + getRightSide(prod); }
bool getFromRestPiece(int x, int y) { int iCornor = 0; // id: from 0 to 3 int iSide = 4; // id: from 4 to ((LWR - 1) * 4 - 1) int iCenter = (LWR - 1) * 4; // id: from (LWR - 1) * 4 to LWR * LWR if (puzzle_board[x][y] != 0) { // already have a piece in this position return false; } if (x == 0 && y == 0) { // left-up corner of the board // cannot reach this position cout << "SYSTEM ERROR: DFS error." << endl; exit(-6); } else if (x == 0 && y == LWR - 1) { // right-up corner of the board toast[x][y] = DOWN; for (iCornor = 0; iCornor < 4; iCornor++) { if (isPieceUsed[iCornor]) continue; if (getLeftSide(iCornor, toast[x][y]) == getRightSide(puzzle_board[x][y - 1], toast[x][y - 1])) { puzzle_board[x][y] = iCornor; isPieceUsed[iCornor] = 1; return true; } } return false; } else if (x == LWR - 1 && y == 0) { // left-down corner of the board toast[x][y] = UP; for (iCornor = 0; iCornor < 4; iCornor++) { if (isPieceUsed[iCornor]) continue; if (getUpSide(iCornor, toast[x][y]) == getDownSide(puzzle_board[x - 1][y], toast[x - 1][y])) { puzzle_board[x][y] = iCornor; isPieceUsed[iCornor] = 1; return true; } } return false; } else if (x == LWR - 1 && y == LWR - 1) { // right-down corner of the board toast[x][y] = RIGHT; for (iCornor = 0; iCornor < 4; iCornor++) { if (isPieceUsed[iCornor]) continue; if (puzzle_board[x - 1][y] != 0 && getUpSide(iCornor, toast[x][y]) == getDownSide(puzzle_board[x - 1][y], toast[x - 1][y])) { puzzle_board[x][y] = iCornor; isPieceUsed[iCornor] = 1; return true; } if (puzzle_board[x][y - 1] != 0 && getLeftSide(iCornor, toast[x][y]) == getRightSide(puzzle_board[x][y - 1], toast[x][y - 1])) { puzzle_board[x][y] = iCornor; isPieceUsed[iCornor] = 1; return true; } } return false; } else if (y == LWR - 1) { // pieces in right sides toast[x][y] = RIGHT; for (iSide = 4; iSide < (LWR - 1) * 4; iSide++) { if (isPieceUsed[iSide]) continue; if (puzzle_board[x - 1][y] != 0 && getUpSide(iSide, toast[x][y]) == getDownSide(puzzle_board[x - 1][y], toast[x - 1][y])) { puzzle_board[x][y] = iSide; isPieceUsed[iSide] = 1; return true; } if (puzzle_board[x][y - 1] != 0 && getLeftSide(iSide, toast[x][y]) == getRightSide(puzzle_board[x][y - 1], toast[x][y - 1])) { puzzle_board[x][y] = iSide; isPieceUsed[iSide] = 1; return true; } } return false; } else if (x == LWR - 1) { // pieces in down sides toast[x][y] = UP; for (iSide = 4; iSide < (LWR - 1) * 4; iSide++) { if (isPieceUsed[iSide]) continue; if (puzzle_board[x - 1][y] != 0 && getUpSide(iSide, toast[x][y]) == getDownSide(puzzle_board[x - 1][y], toast[x - 1][y])) { puzzle_board[x][y] = iSide; isPieceUsed[iSide] = 1; return true; } if (puzzle_board[x][y - 1] != 0 && getLeftSide(iSide, toast[x][y]) == getRightSide(puzzle_board[x][y - 1], toast[x][y - 1])) { puzzle_board[x][y] = iSide; isPieceUsed[iSide] = 1; return true; } } return false; } else if (x == 0) { // pieces in up sides toast[x][y] = DOWN; for (iSide = 4; iSide < (LWR - 1) * 4; iSide++) { if (isPieceUsed[iSide]) continue; if (( y == 1 || puzzle_board[x][y - 1] != 0) && getLeftSide(iSide, toast[x][y]) == getRightSide(puzzle_board[x][y - 1], toast[x][y - 1])) { puzzle_board[x][y] = iSide; isPieceUsed[iSide] = 1; return true; } } return false; } else if (y == 0) { // pieces in left sides toast[x][y] = LEFT; for (iSide = 4; iSide < (LWR - 1) * 4; iSide++) { if (isPieceUsed[iSide]) continue; if (puzzle_board[x - 1][y] != 0 && getUpSide(iSide, toast[x][y]) == getDownSide(puzzle_board[x - 1][y], toast[x - 1][y])) { puzzle_board[x][y] = iSide; isPieceUsed[iSide] = 1; return true; } } return false; } else { // other pieces in the center // toast[x][y] = UP; for (iCenter = (LWR - 1) * 4; iCenter < LWR * LWR; iCenter++) { if (isPieceUsed[iCenter]) continue; for (int it = UP; it < RIGHT; it++) { /*if (puzzle_board[x][y - 1] != 0 && puzzle_board[x - 1][y] != 0) { if (getLeftSide(iCenter, it) == getRightSide(puzzle_board[x][y - 1], toast[x][y - 1]) && getUpSide(iCenter, it) == getDownSide(puzzle_board[x - 1][y], toast[x - 1][y])) { puzzle_board[x][y] = iCenter; toast[x][y] = it; isPieceUsed[iCenter] = 1; return true; } } else if (puzzle_board[x][y - 1] != 0 && getLeftSide(iCenter, it) == getRightSide(puzzle_board[x][y - 1], toast[x][y - 1])) { puzzle_board[x][y] = iCenter; toast[x][y] = it; isPieceUsed[iCenter] = 1; return true; } else if (puzzle_board[x - 1][y] != 0 && getUpSide(iCenter, it) == getDownSide(puzzle_board[x - 1][y], toast[x - 1][y])) { puzzle_board[x][y] = iCenter; toast[x][y] = it; isPieceUsed[iCenter] = 1; return true; }*/ if (puzzle_board[x][y - 1] != 0 && getLeftSide(iCenter, it) == getRightSide(puzzle_board[x][y - 1], toast[x][y - 1])) { puzzle_board[x][y] = iCenter; toast[x][y] = it; isPieceUsed[iCenter] = 1; return true; } if (puzzle_board[x - 1][y] != 0 && getUpSide(iCenter, it) == getDownSide(puzzle_board[x - 1][y], toast[x - 1][y])) { puzzle_board[x][y] = iCenter; toast[x][y] = it; isPieceUsed[iCenter] = 1; return true; } } } return false; } }