Пример #1
0
    private void runModel(List <Employee> employees, List <Shift> shifts)
    {
        StreamWriter writer = File.CreateText(@"C:\Users\user\Desktop\cplex log\result9.txt");

        try
        {
            Cplex model = new Cplex();

            model.SetOut(writer);

            //------------------------------
            //---Variable initialization-----
            //------------------------------
            //Assignment variables
            IDictionary <string, IIntVar> assignVars = new Dictionary <string, IIntVar>();
            employees.ForEach(employee =>
            {
                shifts.ForEach(shift =>
                {
                    string name = getAssignVarName(employee, shift);
                    assignVars.Add(name, model.BoolVar(name));
                });
            });

            //Total assignment hours
            INumVar totalAssignHourVar = model.NumVar(0, Double.MaxValue, getTotalAssignVarName());

            //----------------------------------
            //---Constraints initialization-----
            //-----------------------------------

            //1) Min rest constraint
            //2) Goal total assigned hours constraint
            ILinearNumExpr sumAssignHourExpr = model.LinearNumExpr();
            sumAssignHourExpr.AddTerm(-1.0, totalAssignHourVar);
            employees.ForEach(employee =>
            {
                shifts.ForEach(shift1 =>
                {
                    ILinearNumExpr sumOverlapExpr = model.LinearNumExpr();
                    string name1       = getAssignVarName(employee, shift1);
                    IIntVar assignVar1 = assignVars[name1];
                    sumOverlapExpr.AddTerm(1.0, assignVar1);
                    shifts.ForEach(shift2 =>
                    {
                        if (shift1 != shift2 && this.isDurationOverlap(shift1, shift2))
                        {
                            string name2 = getAssignVarName(employee, shift2);
                            sumOverlapExpr.AddTerm(1.0, assignVars[name2]);
                        }
                    });
                    model.AddLe(sumOverlapExpr, 1.0, "MinRestConst");

                    sumAssignHourExpr.AddTerm((shift1.end - shift1.begin).TotalMinutes, assignVar1);
                });
            });

            //3) No overassignment constraint
            shifts.ForEach(shift =>
            {
                ILinearNumExpr sumAssigsExpr = model.LinearNumExpr();
                employees.ForEach(employee =>
                {
                    string name1       = getAssignVarName(employee, shift);
                    IIntVar assignVar1 = assignVars[name1];
                    sumAssigsExpr.AddTerm(1.0, assignVar1);
                });
                model.AddLe(sumAssigsExpr, shift.shiftNumber, "NoOverAssignConst");
            });
            model.AddEq(sumAssignHourExpr, 0.0, "TotalAssignedHourConst");
            INumVar[] goalVars = { totalAssignHourVar };
            double[]  coeffs   = { 1.0 };
            model.AddMaximize(model.ScalProd(goalVars, coeffs));

            model.ExportModel(@"C:\Users\user\Desktop\cplex log\model1.lp");
            bool feasible = model.Solve();
            if (feasible)
            {
                double objVal = model.ObjValue;
                model.Output().WriteLine("Solution value = " + model.ObjValue);
                shifts.ForEach(shift =>
                {
                    ILinearNumExpr sumAssigsExpr = model.LinearNumExpr();
                    employees.ForEach(employee =>
                    {
                        string name = getAssignVarName(employee, shift);
                    });
                    model.AddLe(sumAssigsExpr, shift.shiftNumber, "NoOverAssignConst");
                });
            }
            else
            {
            }
        }
        catch (System.Exception ex)
        {
            Response.ContentType = "application/json; charset=utf-8";
            Response.Write(ex.Message);
            Response.End();
        }
        writer.Close();
    }
Пример #2
0
        /// <summary>
        /// return a list of words that can be played, left over letters are the last word
        /// </summary>
        /// <param name="chips">All of the chips to conisder, first ones are on the board</param>
        /// <param name="numberOnBoard">The number of leading chips are on the board already</param>
        /// <returns></returns>
        public static List <Chip[]> Solve(List <Chip> chips, int numberOnBoard, bool suppress = true)
        {
            if (chips == null || chips.Count == 0)
            {
                Utility.Warning("Chips is null or empty!");
                return(null);
            }

            int chip_count = chips.Count;
            int word_count = chip_count / 3 + 1;

            Cplex model = new Cplex();

            IIntVar[]   X  = model.BoolVarArray(chip_count);    // should we place the ith chip
            IIntVar[][] Y  = new IIntVar[chip_count][];         // which word do we place the ith chip on
            IIntVar[]   WO = model.BoolVarArray(word_count);    // flag for if the jth word is an order word or not
            IIntVar[]   WC = model.BoolVarArray(word_count);    // flag for if the jth word is a color word or not
            IIntVar[]   WN = model.BoolVarArray(word_count);    // flag for if the jth word is not used or is used
            IIntVar[][] UO = new IIntVar[word_count][];         // what is the number associated with this word (used only if a color word)
            IIntVar[][] UC = new IIntVar[word_count][];         // what is the color associated with this word (used only if a order word)
            IIntVar[][] PC = new IIntVar[word_count][];         // if i maps to word j and j is a color word, this will be 1 at [j][i]
            IIntVar[][] PO = new IIntVar[word_count][];         // if i maps to word j and j is a order word, this will be 1 at [j][i] (if and only if)

            // Initialize
            for (int i = 0; i < chip_count; i++)
            {
                Y[i] = model.BoolVarArray(word_count);
            }

            for (int i = 0; i < word_count; i++)
            {
                UC[i] = model.BoolVarArray(Chip.COLORCOUNT);
            }

            for (int i = 0; i < word_count; i++)
            {
                UO[i] = model.BoolVarArray(Chip.NUMBERCOUNT);
            }

            for (int i = 0; i < word_count; i++)
            {
                PC[i] = model.BoolVarArray(chip_count);
            }

            for (int i = 0; i < word_count; i++)
            {
                PO[i] = model.BoolVarArray(chip_count);
            }

            // for each word which chips map to it
            IIntVar[][] Yt = new IIntVar[word_count][];
            for (int i = 0; i < word_count; i++)
            {
                Yt[i] = new IIntVar[chip_count];
                for (int j = 0; j < chip_count; j++)
                {
                    Yt[i][j] = Y[j][i];
                }
            }

            // maximize the number of placed chips
            model.AddMaximize(model.Sum(X));

            // if we place i, we need to map it to some word
            for (int i = 0; i < chip_count; i++)
            {
                model.AddLe(X[i], model.Sum(Y[i]));
            }

            // we can map to at most 1 value
            for (int i = 0; i < chip_count; i++)
            {
                model.AddLe(model.Sum(Y[i]), 1);
            }

            // if any chip maps to word j, turn the not used flag off
            for (int j = 0; j < word_count; j++)
            {
                for (int i = 0; i < chip_count; i++)
                {
                    model.AddLe(Y[i][j], model.Diff(1, WN[j]));
                }
            }

            // if a word is used, make sure it has at least 3 chips
            for (int j = 0; j < word_count; j++)
            {
                model.AddLe(model.Prod(3, model.Diff(1, WN[j])), model.Sum(Yt[j]));
            }

            // first 'numberOnBoard' chips are on the board and thus must be placed
            for (int i = 0; i < numberOnBoard; i++)
            {
                model.AddEq(X[i], 1);
            }

            // each word is either an order word or a color word
            for (int i = 0; i < word_count; i++)
            {
                model.AddEq(model.Sum(WO[i], WC[i], WN[i]), 1);
            }

            // if i maps to word j and j is a color word make sure PC[j][i] is 1
            for (int j = 0; j < word_count; j++)
            {
                for (int i = 0; i < chip_count; i++)
                {
                    model.AddGe(model.Sum(1, PC[j][i]), model.Sum(WC[j], Y[i][j]));
                }
            }

            // if i maps to word j and j is a order word, PO will be 1 at [j][i] (if and only if)
            for (int j = 0; j < word_count; j++)
            {
                for (int i = 0; i < chip_count; i++)
                {
                    model.AddGe(model.Sum(1, PO[j][i]), model.Sum(WO[j], Y[i][j]));
                    model.AddLe(PO[j][i], WO[j]);
                    model.AddLe(PO[j][i], Y[i][j]);
                }
            }

            // ************************************************
            // ************ TYPE CONSTRAINTS ******************
            // ************************************************

            for (int i = 0; i < chip_count; i++)
            {
                for (int j = 0; j < word_count; j++)
                {
                    // if this is a color word and a chip maps to it then the numbers of each chip on this word must match
                    for (int k = 0; k < Chip.NUMBERCOUNT; k++)
                    {
                        var bnd = model.Sum(WO[j], model.Diff(1, Y[i][j]));
                        model.AddLe(model.Diff(UO[j][k], chips[i].number[k] ? 1 : 0), bnd);
                        model.AddLe(model.Diff(chips[i].number[k] ? 1 : 0, UO[j][k]), bnd);
                    }

                    // if this is a order word and a chip maps to it then the colors of each chip on this word must match
                    for (int k = 0; k < Chip.COLORCOUNT; k++)
                    {
                        var bnd = model.Sum(WC[j], model.Diff(1, Y[i][j]));
                        model.AddLe(model.Diff(UC[j][k], chips[i].color[k] ? 1 : 0), bnd);
                        model.AddLe(model.Diff(chips[i].color[k] ? 1 : 0, UC[j][k]), bnd);
                    }
                }
            }

            // if this is a color word, ensure that at most one of each color is allowed
            for (int j = 0; j < word_count; j++)
            {
                for (int k = 0; k < Chip.COLORCOUNT; k++)
                {
                    int[] colstack = new int[chip_count];
                    for (int i = 0; i < chip_count; i++)
                    {
                        colstack[i] = chips[i].color[k] ? 1 : 0;
                    }

                    model.Add(model.IfThen(model.Eq(WC[j], 1), model.Le(model.ScalProd(colstack, PC[j]), 1)));
                }
            }

            // ensure that the numbers in an order word are sequential
            for (int j = 0; j < word_count; j++)
            {
                IIntVar[] V = model.BoolVarArray(Chip.NUMBERCOUNT);
                for (int k = 0; k < Chip.NUMBERCOUNT; k++)
                {
                    int[] numstack = new int[chip_count];
                    for (int i = 0; i < chip_count; i++)
                    {
                        numstack[i] = chips[i].number[k] ? 1 : 0;
                    }

                    // if this is an order word put the binary numbers into a vector of flags for those numbers
                    model.Add(model.IfThen(model.Eq(WO[j], 1), model.Eq(model.ScalProd(numstack, PO[j]), V[k])));
                }

                // for each number either the next flag is strictly larger, meaning the start of the sequence
                // or every flag after a decrease is 0, the end of a sequence
                for (int i = 0; i < Chip.NUMBERCOUNT - 1; i++)
                {
                    IIntVar Z = model.BoolVar();
                    model.AddLe(model.Diff(V[i], V[i + 1]), Z);

                    for (int k = i + 1; k < Chip.NUMBERCOUNT; k++)
                    {
                        model.AddLe(V[k], model.Diff(1, Z));
                    }
                }
            }

            List <Chip[]> words = new List <Chip[]>();

            if (suppress)
            {
                model.SetOut(null);
            }

            Utility.Log("Thinking...");

            if (model.Solve())
            {
                for (int j = 0; j < word_count; j++)
                {
                    if (model.GetValue(WN[j]) > 0.5)
                    {
                        continue;
                    }

                    List <Chip> word  = new List <Chip>();
                    double[]    flags = model.GetValues(Yt[j]);
                    for (int i = 0; i < chip_count; i++)
                    {
                        if (flags[i] > 0.5)
                        {
                            word.Add(chips[i]);
                        }
                    }

                    // if this is a color word else it is an order word
                    if (model.GetValue(WC[j]) > 0.5)
                    {
                        words.Add(word.OrderBy(p => Array.IndexOf(p.color, true)).ToArray());
                    }
                    else
                    {
                        words.Add(word.OrderBy(p => Array.IndexOf(p.number, true)).ToArray());
                    }
                }
            }
            else
            {
                Utility.Warning("No possible moves found!");
            }

            model.Dispose();

            Chip[] notplayed = chips.Where(p => !words.Any(q => q.Contains(p))).ToArray();
            words.Add(notplayed);

            return(words);
        }
Пример #3
0
        /// <summary>
        /// Getting maximum congruency for naming parameter sets A or B. Linear Programming optimization model.
        /// Eq. (4) and Table II in DOI:10.1109/CEC.2019.8790261
        /// The matrices need to be manually entered here in the script (cTopA, cTopB, cBtmA, cBtmB)
        /// </summary>
        internal static void IdentifyTwoBestParameterSets(string caseSolver)
        {
            Cplex cpl = new Cplex();

            int N = 7;

            //string caseSolver = "ES"; //"SGA" (default), "ES", "PSO", "FIPS"

            int[] cTopA;
            int[] cTopB;
            int[] cBtmA;
            int[] cBtmB;
            switch (caseSolver)
            {
            default:
                cTopA = new int[] { 11, 1, 1, 13, 0, 0, 2 };
                cTopB = new int[] { 0, 5, 3, 0, 5, 5, 5 };
                cBtmA = new int[] { 2, 12, 12, 0, 14, 14, 9 };
                cBtmB = new int[] { 4, 0, 1, 4, 0, 0, 0 };
                break;

            case "ES":
                cTopA = new int[] { 4, 6, 9, 3, 11, 11, 5 };
                cTopB = new int[] { 2, 3, 1, 3, 1, 3, 3 };
                cBtmA = new int[] { 4, 5, 2, 8, 0, 0, 6 };
                cBtmB = new int[] { 3, 1, 3, 2, 5, 3, 2 };
                break;

            case "PSO":
                cTopA = new int[] { 1, 3, 2, 3, 3, 7, 5 };
                cTopB = new int[] { 12, 11, 3, 1, 7, 8, 5 };
                cBtmA = new int[] { 7, 5, 6, 5, 5, 1, 3 };
                cBtmB = new int[] { 0, 1, 9, 11, 5, 4, 7 };
                break;

            case "FIPS":
                cTopA = new int[] { 6, 6, 7, 3, 5, 0, 8 };
                cTopB = new int[] { 4, 6, 6, 9, 5, 9, 1 };
                cBtmA = new int[] { 4, 4, 3, 7, 5, 10, 2 };
                cBtmB = new int[] { 6, 4, 4, 1, 5, 1, 9 };
                break;
            }


            INumVar[]      xTopA = new INumVar[N];
            INumVar[]      xBtmB = new INumVar[N];
            INumVar[]      xTopB = new INumVar[N];
            INumVar[]      xBtmA = new INumVar[N];
            ILinearNumExpr value = cpl.LinearNumExpr();

            for (int n = 0; n < N; n++)
            {
                xTopA[n] = cpl.BoolVar();
                xBtmB[n] = cpl.BoolVar();
                xTopB[n] = cpl.BoolVar();
                xBtmA[n] = cpl.BoolVar();
                cpl.AddEq(cpl.Sum(xTopB[n], xTopA[n]), 1);
                cpl.AddEq(cpl.Sum(xBtmA[n], xBtmB[n]), 1);
                cpl.AddEq(cpl.Sum(xTopA[n], xBtmA[n]), 1);
                cpl.AddEq(cpl.Sum(xTopB[n], xBtmB[n]), 1);
                value.AddTerm(xTopA[n], cTopA[n]);
                value.AddTerm(xTopB[n], cTopB[n]);
                value.AddTerm(xBtmA[n], cBtmA[n]);
                value.AddTerm(xBtmB[n], cBtmB[n]);
            }

            cpl.AddMaximize(value);
            cpl.Solve();

            Console.WriteLine("Parameter Grouping for Solver: {0}", caseSolver);
            for (int n = 0; n < N; n++)
            {
                Console.WriteLine("n: {0}", n);
                Console.WriteLine("xtopA: ;{0};, _____, xTopB: ;{1};", cpl.GetValue(xTopA[n]), cpl.GetValue(xTopB[n]));
                Console.WriteLine("xbtmB: ;{0};, _____, xBtmA: ;{1};", cpl.GetValue(xBtmB[n]), cpl.GetValue(xBtmA[n]));
            }
            Console.WriteLine("cost: {0}", cpl.GetObjValue());
            Console.ReadKey();
        }
Пример #4
0
        private double one_tsp(int dim, int [][] matrix, int [] path)
        {
            int[] lo = new int[dim];

            for (int i = 0; i < dim; i++)
            {
                lo[i] = 1;
            }

            Cplex      cplex   = new Cplex();
            NumVarType varType = NumVarType.Bool;

            INumVar[][] x = new INumVar[dim][];
            for (int i = 0; i < dim; i++)
            {
                x[i] = cplex.NumVarArray(dim, 0, 1);
            }

            for (int i = 0; i < dim; i++)
            {
                for (int j = 0; j < dim; j++)
                {
                    x[i][j] = cplex.BoolVar();
                }
            }

            for (int j = 0; j < dim; j++)
            {
                INumExpr xcolSum = cplex.NumExpr();
                for (int i = 0; i < dim; i++)
                {
                    xcolSum = cplex.Sum(xcolSum, x[i][j]);
                }
                cplex.AddEq(lo[j], xcolSum);
            }

            varType = NumVarType.Float;
            INumVar[] u = new INumVar[dim];
            for (int j = 0; j < dim; j++)
            {
                u[j] = cplex.NumVar(0, 100000);
            }

            for (int j = 1; j < dim; j++)
            {
                cplex.AddGe(u[j], 0);
            }

            for (int i = 1; i < dim; i++)
            {
                for (int j = 1; j < dim; j++)
                {
                    if (i != j)
                    {
                        cplex.AddLe(cplex.Sum(cplex.Diff(u[i], u[j]), cplex.Prod(dim, x[i][j])), dim - 1);
                    }
                }
            }

            for (int i = 0; i < dim; i++)
            {
                INumExpr xrowSum = cplex.NumExpr();
                for (int j = 0; j < dim; j++)
                {
                    xrowSum = cplex.Sum(xrowSum, x[i][j]);
                }
                cplex.AddEq(lo[i], xrowSum);
            }

            INumExpr costSum = cplex.NumExpr();

            for (int i = 0; i < dim; i++)
            {
                for (int j = 0; j < dim; j++)
                {
                    costSum = cplex.Sum(costSum, cplex.Prod(x[i][j], matrix[i][j]));
                }
            }
            cplex.AddMinimize(costSum);

            try
            {
                if (cplex.Solve())
                {
                    //MessageBox.Show("Solution status = " + cplex.GetStatus());
                    //MessageBox.Show("cost = " + cplex.ObjValue);
                    int ipath = 0;
                    int depo  = -1;
                    for (int i = dim - 1; i >= 0; i--)
                    {
                        for (int j = 0; j < dim; j++)
                        {
                            if (Convert.ToInt16(cplex.GetValue(x[i][j])) == 1)
                            {
                                depo = i;
                            }
                        }
                    }
                    path[ipath] = depo;
                    ipath++;
                    while (depo > -1)
                    {
                        for (int j = 0; j < dim; j++)
                        {
                            if (Convert.ToInt16(cplex.GetValue(x[path[ipath - 1]][j])) == 1)
                            {
                                path[ipath] = j;
                                ipath++;
                                if (j == depo)
                                {
                                    depo = -1;
                                }
                                break;
                            }
                        }
                    }
                    return(cplex.ObjValue);
                }
                cplex.End();
            }
            catch (ILOG.Concert.Exception ex)
            {
                System.Console.WriteLine("Concert Error: " + ex);
            }
            return(-1);
        }
Пример #5
0
        private void decomp(int dim, int kts, int[][] dist, List <int> WorkList)
        {
            int[] lo = new int[dim];
            int   dk = dim * kts;

            for (int i = 0; i < dim; i++)
            {
                lo[i] = 1;
            }

            Cplex      cplex   = new Cplex();
            NumVarType varType = NumVarType.Bool;

            INumVar[][] x = new INumVar[dim][];
            for (int i = 0; i < dim; i++)
            {
                x[i] = cplex.NumVarArray(dk, 0, 1);
            }

            for (int i = 0; i < dim; i++)
            {
                for (int j = 0; j < dk; j++)
                {
                    x[i][j] = cplex.BoolVar();
                }
            }

            //****************************************
            //Что тут происходит?
            for (int j = 0; j < dim; j++)
            {
                INumExpr xcolSum = cplex.NumExpr();
                for (int k = 0; k < kts; k++)
                {
                    for (int i = 0; i < dim; i++)
                    {
                        xcolSum = cplex.Sum(xcolSum, x[i][k * dim + j]);
                    }
                }
                cplex.AddEq(lo[j], xcolSum);
            }

            varType = NumVarType.Float;
            INumVar[] u = new INumVar[dk];
            for (int j = 0; j < dk; j++)
            {
                u[j] = cplex.NumVar(0, 100000);
            }

            for (int j = 1; j < dk; j++)
            {
                cplex.AddGe(u[j], 0);
            }

            for (int k = 0; k < kts; k++)
            {
                for (int i = 1; i < dim; i++)
                {
                    for (int j = 1; j < dim; j++)
                    {
                        if (i != j)
                        {
                            if (kts == 1)
                            {
                                cplex.AddLe(cplex.Sum(cplex.Diff(u[k * dim + i], u[k * dim + j]), cplex.Prod(dim, x[i][k * dim + j])), dim - 1);
                            }
                            else
                            {
                                cplex.AddLe(cplex.Sum(cplex.Diff(u[k * dim + i], u[k * dim + j]), cplex.Prod(dim, x[i][k * dim + j])), dim);
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < dim; i++)
            {
                INumExpr xrowSum = cplex.NumExpr();
                for (int j = 0; j < dk; j++)
                {
                    xrowSum = cplex.Sum(xrowSum, x[i][j]);
                }
                cplex.AddEq(lo[i], xrowSum);
            }

            //Условия независимости кластеров
            if (kts > 1)
            {
                int[] a = new int[kts + 1];
                for (int k = 1; k < kts; k++)
                {
                    if (k > 1 && k < kts - 1)
                    {
                        continue;
                    }
                    int p;
                    for (int i = 1; i <= k; i++)
                    {
                        a[i] = i;
                    }
                    p = k;
                    while (p >= 1)
                    {
                        for (int m = 0; m < dim; m++)
                        {
                            INumExpr xcolrowSum = cplex.NumExpr();
                            for (int j = 1; j <= kts; j++)
                            {
                                bool row = false;
                                for (int i = 1; i <= k; i++)
                                {
                                    if (a[i] == j)
                                    {
                                        row = true;
                                    }
                                }
                                if (row)
                                {
                                    for (int t = 0; t < dim; t++)
                                    {
                                        xcolrowSum = cplex.Sum(xcolrowSum, x[m][(j - 1) * dim + t]);
                                    }
                                }
                                else
                                {
                                    for (int t = 0; t < dim; t++)
                                    {
                                        xcolrowSum = cplex.Sum(xcolrowSum, x[t][(j - 1) * dim + m]);
                                    }
                                }
                            }
                            cplex.AddLe(xcolrowSum, lo[m]);
                        }
                        if (a[k] == kts)
                        {
                            p--;
                        }
                        else
                        {
                            p = k;
                        }
                        if (p >= 1)
                        {
                            for (int i = k; i >= p; i--)
                            {
                                a[i] = a[p] + i - p + 1;
                            }
                        }
                    }
                }
            }

            INumExpr costSum = cplex.NumExpr();

            INumExpr[] costSum1 = new INumExpr[kts];

            if (kts == 1)
            {
                for (int i = 0; i < dim; i++)
                {
                    for (int j = 0; j < dim; j++)
                    {
                        costSum = cplex.Sum(costSum, cplex.Prod(x[i][j], dist[i][j]));
                    }
                }
                cplex.AddMinimize(costSum);
            }
            else
            {
                for (int k = 0; k < kts; k++)
                {
                    costSum1[k] = cplex.NumExpr();
                    for (int i = 0; i < dim; i++)
                    {
                        for (int j = 0; j < dim; j++)
                        {
                            costSum1[k] = cplex.Sum(costSum1[k], cplex.Prod(x[i][k * dim + j], dist[i][j]));
                        }
                    }
                    //cplex.AddLe(costSum1[k], costSum);
                }
                costSum = cplex.Max(costSum1);
                cplex.AddMinimize(costSum);
            }

            try
            {
                if (cplex.Solve())
                {
                    textBox1.Text += "lambda = " + cplex.ObjValue + Environment.NewLine;
                    textBox1.Text += DateTime.Now.ToString() + Environment.NewLine;

                    WorkList.Clear();
                    int num_clust = 0;
                    for (int k = 0; k < kts; k++)
                    {
                        int dim1 = 0;
                        for (int i = 0; i < dim; i++)
                        {
                            for (int j = 0; j < dim; j++)
                            {
                                if (Convert.ToInt16(cplex.GetValue(x[i][k * dim + j])) == 1)
                                {
                                    dim1++;
                                }
                            }
                        }

                        if (dim1 > 0)
                        {
                            num_clust++;
                            for (int i = 0; i < dim; i++)
                            {
                                for (int j = 0; j < dim; j++)
                                {
                                    if (Convert.ToInt16(cplex.GetValue(x[i][k * dim + j])) == 1)
                                    {
                                        WorkList.Add(i);
                                        break;
                                    }
                                }
                            }

                            WorkList.Add(-1);
                        }
                    }
                    textBox1.Text += DateTime.Now.ToString() + Environment.NewLine;
                }
                else
                {
                    textBox1.Text += "Нет решения" + Environment.NewLine;
                    textBox1.Text += DateTime.Now.ToString() + Environment.NewLine;
                }
                cplex.End();
            }
            catch (ILOG.Concert.Exception ex)
            {
                textBox1.Text += "Concert Error: " + ex + Environment.NewLine;
                textBox1.Text += DateTime.Now.ToString() + Environment.NewLine;
            }
        }
Пример #6
0
        private void button1_Click(object sender, EventArgs e)
        {
            int[,] A = new int[, ]
            {
                { 1, 1, 1, 1, 0 },
                { 1, 1, 0, 1, 1 },
                { 0, 1, 1, 1, 1 }
            };

            double[] L = new double[] { 8, 5, 7, 8, 4 };

            double G = 10.7;

            double[] N_Max = new double[] { 2, 2, 2 };

            int nbOfWorkers = A.GetLength(0);
            int nbOfTasks   = A.GetLength(1);

            Cplex cplex = new Cplex();

            INumVar[,] X = new INumVar[nbOfWorkers, nbOfTasks];  // C라는 2차원 인덱스가 0이면, 행의 개수을 받겠다
            // C라는 2차원 인덱스가 1이면 열의 개수를 받겠다.
            for (int i = 0; i < A.GetLength(0); i++)
            {
                for (int j = 0; j < A.GetLength(1); j++)
                {
                    X[i, j] = cplex.BoolVar();
                }
            }

            List <INumVar> D_negative = new List <INumVar>();

            for (int i = 0; i < nbOfWorkers; i++)
            {
                D_negative.Add(cplex.NumVar(0, double.MaxValue));
            }


            List <INumVar> D_positive = new List <INumVar>();

            for (int i = 0; i < nbOfWorkers; i++)
            {
                D_positive.Add(cplex.NumVar(0, double.MaxValue));
            }

            //목적함수
            ILinearNumExpr objectiveFunction = cplex.LinearNumExpr();

            for (int i = 0; i < nbOfWorkers; i++)
            {
                objectiveFunction.AddTerm(1, D_negative[i]);
            }

            for (int i = 0; i < nbOfWorkers; i++)
            {
                objectiveFunction.AddTerm(1, D_positive[i]); // C[i, j], X[i, j] 두개를 곱해서 objectiveFunction 에 넣겠다.
            }
            //과제
            for (int i = 0; i < nbOfWorkers; i++)
            {
                ILinearNumExpr constLeft1 = cplex.LinearNumExpr();
                for (int j = 0; j < nbOfTasks; j++)
                {
                    constLeft1.AddTerm(L[j], X[i, j]);
                }
                constLeft1.AddTerm(1, D_negative[i]);
                constLeft1.AddTerm(-1, D_positive[i]);
                cplex.AddEq(constLeft1, G);
            }


            for (int j = 0; j < nbOfTasks; j++)
            {
                ILinearNumExpr constLeft2 = cplex.LinearNumExpr();
                for (int i = 0; i < X.GetLength(0); i++)
                {
                    constLeft2.AddTerm(1, X[i, j]);
                }
                cplex.AddEq(constLeft2, 1);
            }

            for (int i = 0; i < nbOfWorkers; i++)
            {
                for (int j = 0; j < nbOfTasks; j++)
                {
                    cplex.AddLe(X[i, j], A[i, j]);
                }
            }

            for (int i = 0; i < nbOfWorkers; i++)
            {
                ILinearNumExpr constLeft4 = cplex.LinearNumExpr();
                for (int j = 0; j < nbOfTasks; j++)
                {
                    constLeft4.AddTerm(1, X[i, j]);
                }
                cplex.AddLe(constLeft4, N_Max[i]);
            }

            cplex.AddMinimize(objectiveFunction);
            cplex.Solve();

            string solution  = "";
            double tolerance = cplex.GetParam(Cplex.Param.MIP.Tolerances.Integrality); //tolerance를 정의함

            for (int i = 0; i < A.GetLength(0); i++)
            {
                for (int j = 0; j < A.GetLength(1); j++)
                {
                    if (cplex.GetValue(X[i, j]) >= 1 - tolerance)
                    {
                        solution += "(" + (i + 1).ToString() + " ," + (j + 1).ToString() + ")";
                    }
                }
            }

            MessageBox.Show("목적함수 값은 =" + cplex.GetObjValue() + "\r\n" + "선택된 변수는 =" + solution);
        }