/**
         * @param basicMatrixIn the coefficient matrix of constraints
         * @return Array[2][m+1]
         * First row is just reduced cost
         * Second row is dual cost vector
         */
        private static double[][] calLP(double[][] basicMatrixIn, double[] orderNumVec)
        {
            double[][] basicMatrix = cloneMatrix(basicMatrixIn); // LP solve modifies our input array

            int    nVar   = basicMatrix.Length;
            IntPtr solver = Lpsolve.make_lp(0, nVar);

            Lpsolve.set_verbose(solver, 1);

            // add constraints
            for (int r = 0; r < nVar; r++)
            {
                Lpsolve.add_constraint(solver, basicMatrix[r], Lpsolve.lpsolve_constr_types.EQ, orderNumVec[r + 1]);
            }

            // set objective function
            double[] minCoef = new double[nVar + 1]; // coefficients
            for (int i = 0; i < minCoef.Length; i++)
            {
                minCoef[i] = 1;
            }
            minCoef[0] = nVar;
            Lpsolve.set_obj_fn(solver, minCoef);
            Lpsolve.set_minim(solver);

            // solve the problem
            int solFlag = (int)Lpsolve.solve(solver);

            // solution
            double[] rhs = new double[Lpsolve.get_Ncolumns(solver)];
            Lpsolve.get_variables(solver, rhs);
            double[] duals = new double[Lpsolve.get_Ncolumns(solver) + Lpsolve.get_Nrows(solver) + 1];
            Lpsolve.get_dual_solution(solver, duals);

            // delete the problem and free memory
            Lpsolve.delete_lp(solver);

            // Prepare result
            double[][] rst = new double[3][];
            rst[0]    = new double[nVar + 1];
            rst[0][0] = solFlag;

            rst[1]    = new double[nVar + 1];
            rst[1][0] = nVar;
            rhs.CopyTo(rst[1], 1);

            rst[2]    = new double[nVar + 1];
            rst[2][0] = nVar;
            Array.Copy(duals, 1, rst[2], 1, nVar);
            return(rst);
        }