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;
        }
예제 #3
0
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;
}
예제 #4
0
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);
  }
}
예제 #5
0
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;
}
예제 #6
0
bool Tableau::isPrimalFeasible() const {
  const int constraintCount = getConstraintCount();
  for(int row = 1; row <= constraintCount; row++) {
    if(getRightSide(row) < 0) {
      return false;
    }
  }
  return true;
}
예제 #7
0
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;
}
예제 #8
0
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;
  }
}
예제 #9
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);
    }
  }
}
예제 #10
0
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);
		}
	}
}
예제 #11
0
// 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);
  }
}
예제 #12
0
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);
}
예제 #13
0
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;
	}
}