Exemplo n.º 1
0
    //Compute SolverIteration from preceding iteration
    private static SolverIteration ComputeIteration(SolverIteration previous)
    {
        SolverIteration iteration = previous.Copy();

        var column = IncomingVariable(iteration.DecisionVariables);

        var row = LeavingVariable(GetColumn(iteration.InputGrid, column),
                                  iteration.BaseVariables);

        var variable = iteration.InputGrid[row][column];
        var rowArray = iteration.InputGrid[row];

        for (int i = 0; i < rowArray.Length; i++)
        {
            rowArray[i] /= variable;
        }

        iteration.BaseVariables[row] /= variable;

        for (int i = 0; i < iteration.InputGrid.Length; i++)
        {
            if (i == row)
            {
                continue;
            }
            var value = iteration.InputGrid[i][column];
            for (int j = 0; j < iteration.InputGrid[i].Length; j++)
            {
                iteration.InputGrid[i][j] -= value * iteration.InputGrid[row][j];
            }
            iteration.BaseVariables[i] -= value * iteration.BaseVariables[row];
        }

        var val = iteration.DecisionVariables[column];

        for (int i = 0; i < iteration.DecisionVariables.Length; i++)
        {
            iteration.DecisionVariables[i] -=
                val * iteration.InputGrid[row][i];
        }

        iteration.Bases[row] = iteration.Variables[column];

        iteration.Z = 0;
        for (var i = 0; i < iteration.Bases.Length; i++)
        {
            var baseVar = iteration.Bases[i];
            iteration.Z += GetVariableObjective(baseVar, iteration) * iteration.BaseVariables[i];
        }

        previous.SelectedGridPositions = (row, column);

        return(iteration);
    }
Exemplo n.º 2
0
    //Remove artificial variable indexes after two-phases finishes
    public static SolverIteration RemoveIndexes(SolverIteration iteration, int cutoffIndex)
    {
        var cutIteration = iteration.Copy();

        var variables          = iteration.Variables.Take(cutoffIndex).ToArray();
        var objectiveVariables = iteration.ObjectiveVariables.Take(cutoffIndex)
                                 .ToArray();
        var decisionVariables = iteration.DecisionVariables.Take(cutoffIndex)
                                .ToArray();
        var inputGrid = new List <BigRational[]>();

        for (int i = 0; i < iteration.InputGrid.Length; i++)
        {
            inputGrid.Add(iteration.InputGrid[i].Take(cutoffIndex).ToArray());
        }

        cutIteration.Variables          = variables;
        cutIteration.ObjectiveVariables = objectiveVariables;
        cutIteration.DecisionVariables  = decisionVariables;
        cutIteration.InputGrid          = inputGrid.ToArray();
        return(cutIteration);
    }
Exemplo n.º 3
0
    //Run two-phases simplex algorithm starting from an initial SolverIteration
    public static SolvedModel TwoPhases(SolverIteration initialIteration, List <Constraint> constraints)
    {
        var twoPhasesInitialIteration = initialIteration.Copy();
        int artificialCutoff          = -1;

        for (int i = 0; i < initialIteration.Variables.Length; i++)
        {
            if (initialIteration.Variables[i].Type == VariableType.Artificial)
            {
                artificialCutoff = i;
                break;
            }
        }

        if (artificialCutoff == -1)
        {
            throw new ArgumentException();
        }

        var twoPhasesObjective = Enumerable.Repeat <BigRational>(
            BigRational.One, twoPhasesInitialIteration.Variables.Length).ToArray();

        for (int i = 0; i < artificialCutoff; i++)
        {
            twoPhasesObjective[i] = 0;
        }

        twoPhasesInitialIteration.ObjectiveVariables = twoPhasesObjective;

        var twoPhaseBases = twoPhasesInitialIteration
                            .Variables.Skip(
            twoPhasesInitialIteration.Variables.Length - twoPhasesInitialIteration.Bases.Length)
                            .ToArray();

        twoPhasesInitialIteration.Bases = twoPhaseBases;

        for (int i = 0; i < twoPhasesInitialIteration.Variables.Length; i++)
        {
            BigRational Zj = BigRational.Zero;

            for (int j = 0; j < twoPhasesInitialIteration.Bases.Length; j++)
            {
                var rowVariable       = twoPhasesInitialIteration.Bases[j];
                var rowObjectiveIndex = Array.IndexOf(twoPhasesInitialIteration.Variables, rowVariable);
                var rowObjective      = twoPhasesInitialIteration.ObjectiveVariables[rowObjectiveIndex];
                Zj += twoPhasesInitialIteration.InputGrid[j][i] * rowObjective;
            }

            twoPhasesInitialIteration.DecisionVariables[i] = twoPhasesInitialIteration.ObjectiveVariables[i] - Zj;
        }

        twoPhasesInitialIteration.Z = 0;
        for (var i = 0; i < twoPhasesInitialIteration.Bases.Length; i++)
        {
            var baseVar     = twoPhasesInitialIteration.Bases[i];
            var columnIndex = Array.IndexOf(twoPhasesInitialIteration.Variables, baseVar);
            twoPhasesInitialIteration.Z += twoPhasesInitialIteration.BaseVariables[i] * twoPhasesInitialIteration.ObjectiveVariables[columnIndex];
        }

        var solvedTwoPhases = Simplex(twoPhasesInitialIteration, constraints);

        solvedTwoPhases.TwoPhasesIterations = solvedTwoPhases.SimplexIterations;
        solvedTwoPhases.SimplexIterations   = new List <SolverIteration>();

        if (solvedTwoPhases.Result != SolvedResult.Optimized)
        {
            return(solvedTwoPhases);
        }
        if (solvedTwoPhases.Z != 0)
        {
            solvedTwoPhases.Result = SolvedResult.Unbounded;
            return(solvedTwoPhases);
        }
        var finalIteration = solvedTwoPhases.TwoPhasesIterations.Last();

        for (int i = 0; i < finalIteration.Bases.Length; i++)
        {
            if (finalIteration.Bases[i].Type == VariableType.Artificial &&
                finalIteration.BaseVariables[i] > 0)
            {
                solvedTwoPhases.Result = SolvedResult.Infeasible;
                return(solvedTwoPhases);
            }
        }

        finalIteration = RemoveIndexes(
            finalIteration.Copy(), artificialCutoff);

        finalIteration.ObjectiveVariables = initialIteration.ObjectiveVariables.Take(artificialCutoff).ToArray();
        finalIteration.Z = 0;
        for (var i = 0; i < finalIteration.Bases.Length; i++)
        {
            var baseVar     = finalIteration.Bases[i];
            var columnIndex = Array.IndexOf(finalIteration.Variables, baseVar);
            if (columnIndex == -1)
            {
                finalIteration.Z += 0;
            }
            else
            {
                finalIteration.Z += finalIteration.BaseVariables[i] * finalIteration.ObjectiveVariables[columnIndex];
            }
        }

        for (int i = 0; i < finalIteration.Variables.Length; i++)
        {
            var zj = -GetColumn(finalIteration.InputGrid, i).Sum();
            var cj = finalIteration.ObjectiveVariables[i];
            finalIteration.DecisionVariables[i] =
                -GetColumn(finalIteration.InputGrid, i).Sum() - finalIteration.ObjectiveVariables[i];
        }

        var simplexResult = Simplex(finalIteration, constraints);

        simplexResult.TwoPhasesIterations = solvedTwoPhases.TwoPhasesIterations;
        return(simplexResult);
    }