Пример #1
0
        /// <summary>
        /// metóda pre získanie zadania úlohy lineárneho programovania z okna
        /// </summary>
        /// <param name="variablesCount">počet premenných</param>
        /// <returns>zadanie úlohy lineárneho programovania</returns>
        public LPTreeBody GetTaskInput(int variablesCount)
        {
            LinearTaskInputWindow dlg = new LinearTaskInputWindow(variablesCount);
            bool? result = dlg.ShowDialog();
            if (result == true)
            {
                myTaskType = dlg.TaskType;
                myTaskFunction = (Equation)dlg.CriterialFunction.Clone();
                myTaskConditions = (EquationsCollection)dlg.ConditionFunctions;

                LPTreeBody tree = new LPTreeBody(dlg.CriterialFunction, dlg.ConditionFunctions, dlg.TaskType);
                return tree;
            }

            return null;
        }
Пример #2
0
 /// <summary>
 /// metóda pre pridanie rovnice - ohraničenia
 /// </summary>
 /// <param name="theEquation">ohraničenie</param>
 public void InsertEquation(Equation theEquation)
 {
     myConditions.Add(theEquation);
 }
Пример #3
0
        private int myVariablesCount = 0; //pocet premennych

        #endregion Fields

        #region Constructors

        /// <summary>
        /// konštruktor
        /// </summary>
        /// <param name="theType">typ úlohy</param>
        /// <param name="theFunction">kriteriálna funkcia</param>
        public Simplex(LinearTypes theType, Equation theFunction)
        {
            myFunction = theFunction;
            myVariablesCount = myFunction.LeftSide.Count;
            myType = theType;
        }
Пример #4
0
 /// <summary>
 /// metóda pre transformáciu problému do kanonického tvaru
 /// </summary>
 public void TransformToCanonicalForm()
 {
     // Zmena problemu na maximalizacny.
     if (myType == LinearTypes.Minimalization)
     {
         myType = LinearTypes.Maximalization;
         myFunction.Multiply(-1);
     }
     // Zmena nerovnosti na rovnosti.
     myConditions.RemoveInequality();
     myTempFunction = myConditions.HelpFunction;
     // Zmena koeficientov na pravej strane na nezaporne.
     foreach (Equation item in myConditions)
     {
         if (item.RightSide < 0)
         {
             item.Multiply(-1);
         }
     }
     // Doplnenie 0 do kriteriálnej funkcie
     for (int i = 0; i < myConditions[0].LeftSide.Count - myVariablesCount; i++)
     {
         myFunction.AddVariable(0);
     }
 }
Пример #5
0
        /// <summary>
        /// metóda pre riešenie úlohy simplexovou metódou
        /// </summary>
        /// <returns>riešenie</returns>
        public Solution Solve()
        {
            TransformToCanonicalForm();
            myFunction.Multiply(-1); //transformacia krit. fcie do tvaru z-ax-...=0

            myTempFunction = myConditions.HelpFunction;

            if (myTempFunction.LeftSide.Count > 0)
            {
                if (IsSolveWithHelpFunction() == false)
                {
                    return null;
                }
            }

            while (!IsOptimal()) //test optimality
            {
                int minIndex = FindIndexOfMinimalCoefInFunction(); //vyhladanie min prvku v spodnom riadku

                PivotResult pivotResult = FindPivot(minIndex); //urcenie pivota + jeho polohy
                if (pivotResult == null)
                {
                    return null;
                }
                Equation pivotEq = myConditions[pivotResult.Index]; //vyber ohranicenia, v ktorom je pivot
                foreach (Equation item in myConditions) //prenasobenie ohraniceni - eliminacia na 0
                {
                    if (item != pivotEq)
                    {
                        item.Combine(pivotEq, -item.LeftSide[minIndex] / pivotResult.Pivot);
                    }
                }
                myFunction.Combine(pivotEq, -myFunction.LeftSide[minIndex] / pivotResult.Pivot); //prenasobenie kf - eliminacia na 0
                pivotEq.Multiply((double)1 / pivotResult.Pivot); //prenasobenie ohranicenia, v ktorom je pivot jeho prvratenou hodnotou - eliminacia na 1
            }

            Solution solution = RetrieveSolution(myVariablesCount);
            return solution;
        }
Пример #6
0
 /// <summary>
 /// konštruktor
 /// </summary>
 /// <param name="function">kriteriálna funkcia</param>
 /// <param name="conditions">ohraničenia</param>
 /// <param name="type">typ úlohy lineárneho programovania</param>
 public LPTreeBody(Equation function, EquationsCollection conditions, LinearTypes type)
 {
     myRoot = new LPTreeItem(function, type, conditions);
     myUnprocessedItems.Add(myRoot);
 }
Пример #7
0
 /// <summary>
 /// metóda pre vytvorenie kópie objektu
 /// </summary>
 /// <returns>kópia objektu</returns>
 public object Clone()
 {
     Equation eq = new Equation(new double[] { }, myType.Clone().ToString(), myRightSide);
     foreach (double item in myLeftSide)
     {
         eq.AddVariable(item);
     }
     return eq;
 }
Пример #8
0
        /// <summary>
        /// metóda pre súčet dvoch rovníc
        /// </summary>
        /// <param name="theEquation">rovnica, ktorá má byť pripočítaná k pôvodnej rovnici</param>
        /// <param name="theFactor">koeficient, ktorým je potrebné pripočítavanú rovnicu vynásobiť</param>
        public void Combine(Equation theEquation, double theFactor)
        {
            //premenná pre uloženie počtu premenných na ľavej strane
            int leftSideLength = theEquation.LeftSide.Count > this.LeftSide.Count ? theEquation.LeftSide.Count : this.LeftSide.Count;

            for (int i = 0; i < leftSideLength; i++)
            {
                double secondValue = 0;
                if (i < theEquation.LeftSide.Count)
                {
                    secondValue = theEquation.LeftSide[i] * theFactor;
                }
                if (i < this.LeftSide.Count)
                {
                    this.LeftSide[i] += secondValue;
                }
            }

            this.myRightSide += theFactor * theEquation.RightSide;
        }
Пример #9
0
        /// <summary>
        /// konštuktor
        /// </summary>
        /// <param name="function">kriteriálna funkcia</param>
        /// <param name="type">typ úlohy lineárneho programovaina</param>
        /// <param name="conditions">ohraničenia</param>
        public LPTreeItem(Equation function, LinearTypes type, EquationsCollection conditions)
        {
            myConditions = conditions;
            myFunction = function;
            myType = type;

            myFunctionBackup = (Equation)function.Clone();
            foreach (Equation item in conditions)
            {
                myConditionsBackup.Add((Equation)item.Clone());
            }

            Simplex simplex = new Simplex(myType, myFunction);
            simplex.InsertEquations(myConditions);
            Solution solution = simplex.Solve();
            myNodeSolution = solution;

            if (solution != null)
            {
                myHasSolution = true;
                double val = double.MinValue;
                int index = -1;
                for (int i = 0; i < solution.Count; i++)
                {
                    if (Math.Abs(Math.Round(solution[i]) - solution[i]) > 0.000005)
                    {
                        val = solution[i];
                        index = i;
                        break;
                    }
                }

                // Ak nie je nájdené riešenie celočíselné:
                if (val > double.MinValue + 0.000005)
                {
                    int left = (int)Math.Floor(val);
                    int right = (int)Math.Ceiling(val);

                    // príprava ľavej strany ohraničenia
                    List<double> leftSide = new List<double>();
                    for (int i = 0; i < myFunctionBackup.LeftSide.Count; i++)
                    {
                        if (i == index)
                        {
                            leftSide.Add(1);
                        }
                        else
                        {
                            leftSide.Add(0);
                        }
                    }

                    // príprava ohraničenia pre ľavého syna
                    EquationsCollection leftConditions = (EquationsCollection)myConditionsBackup.Clone();
                    leftConditions.Add(new Equation(leftSide, "<=", left));

                    // príprava ohraničenia pre pravého syna
                    EquationsCollection rightConditions = (EquationsCollection)myConditionsBackup.Clone();
                    rightConditions.Add(new Equation(leftSide, ">=", right));

                    // vytvorenie potomkov
                    myLeftChild = new LPTreeItem((Equation)myFunctionBackup.Clone(), myType, (EquationsCollection)leftConditions.Clone());
                    myRightChild = new LPTreeItem((Equation)myFunctionBackup.Clone(), myType, (EquationsCollection)rightConditions.Clone());

                    myUpperBound = myFunction.RightSide;
                }
                else
                {
                    // Ak je nájdené riešenie celočíselné:
                    myLowerBound = (int)myFunction.RightSide;
                    myUpperBound = (int)myFunction.RightSide;
                    myIsFinalNode = true;
                }
            }
        }
Пример #10
0
 /// <summary>
 /// metóda pre výpočet dolnej medze
 /// </summary>
 /// <param name="function">kriteriálna funkcia</param>
 /// <param name="solution">riešenie bez zaokrúhlenia</param>
 /// <returns>dolná medza daného uzla</returns>
 public double CountLowerBound(Equation function, Solution solution)
 {
     double lowerBoundFromRounding = 0;
     Solution roundedSolution = new Solution();
     foreach (double i in solution)
     {
         roundedSolution.Add(Math.Round(i));
     }
     foreach (double i in solution)
     {
         foreach (double j in function.LeftSide)
         {
             if (solution.IndexOf(i)==function.LeftSide.IndexOf(j))
             {
                 lowerBoundFromRounding += j * i;
             }
         }
     }
     return lowerBoundFromRounding;
 }