Beispiel #1
0
        public Instance Match(Instance instance, string path, bool print)
        {
            Instance oldcopy = instance.Copy();

            if (!System.IO.Directory.Exists(path) && print)
                System.IO.Directory.CreateDirectory(path);

            if (print)
            {
                Bitmap Bmp1 = instance.Draw();
                Bmp1.Save(path + "/0Start.bmp");
                Bmp1.Dispose();
            }

            instance = GetReduced(instance);

            if (print)
            {
                Bitmap Bmp2 = instance.Draw();
                Bmp2.Save(path + "/1Reduced.bmp");
                Bmp2.Dispose();
            }

            if (print)
            {
                Bitmap Bmp3 = instance.Draw();
                Bmp3.Save(path + "/2Inflated.bmp");
                Bmp3.Dispose();
            }


            // check for applicant-complete matching
            instance = GetApplicantComplete(instance);

            if (instance == null)
            {

                if (print)
                {
                    Bitmap Result = new Bitmap(1000, 1000);
                    Graphics G = Graphics.FromImage(Result);
                    Pen P = new Pen(new SolidBrush(Color.Black));
                    G.DrawString("No Popular Matching", new Font("Arial", 36), new SolidBrush(Color.Black), 100, 100);
                    Result.Save(path + "/3NoPop.bmp");
                    G.Dispose();
                    Result.Dispose();
                }
                return null;
            }
            else
            {
                if (print)
                {
                    Bitmap Bmp4 = instance.Draw();
                    Bmp4.Save(path + "/3ApplicantComplete.bmp");
                    Bmp4.Dispose();
                }
            }

            List<int>[] FPosts = new List<int>[instance.Posts.Length];

            for (int i = 0; i < instance.Posts.Length; i++)
            {
                FPosts[i] = new List<int>();
            }

            for (int i = 0; i < instance.Applicants.Length; i++)
            {
                FPosts[instance.Applicants[i].Priorities.ElementAt(0).Target].Add(i);
            }

            for (int i = 0; i < instance.Posts.Length; i++)
            {
                if (FPosts[i].Count > 0 && instance.Posts[i].NrMatchings == 0)
                {
                    instance.DeleteMatch(FPosts[i][0]);
                    instance.AddMatch(i, FPosts[i][0]);
                }
            }

            if (print)
            {
                Bitmap Bmp4 = instance.Draw();
                Bmp4.Save(path + "/4AllFPostsMatched.bmp");
                Bmp4.Dispose();
            }

            return instance;
        }
Beispiel #2
0
        /// <summary>
        /// Completess the applicant-complete matching, by traversing the disjoint cycle and taking every second edge.
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="start"></param>
        /// <returns></returns>
        private Instance GoPath(Instance instance, int start)
        {
            if (instance.Applicants[start].Matched)
                return instance;
            else
            {
                int Target = -1;
                if (!instance.Posts[instance.Applicants[start].Priorities.ElementAt(0).Target].Full)
                {
                    instance.AddMatch(instance.Applicants[start].Priorities.ElementAt(0).Target, start);
                    Target = instance.Applicants[start].Priorities.ElementAt(0).Target;

                }
                else
                {
                    if (!instance.Posts[instance.Applicants[start].Priorities.ElementAt(1).Target].Full)
                    {
                        instance.AddMatch(instance.Applicants[start].Priorities.ElementAt(1).Target, start);
                        Target = instance.Applicants[start].Priorities.ElementAt(1).Target;
                    }
                    else
                        return instance;
                }

                for (int j = 0; j < instance.Applicants.Length; j++)
                {
                    if (instance.Applicants[j].Priorities.ElementAt(0).Target == Target || instance.Applicants[j].Priorities.ElementAt(1).Target == Target)
                    {
                        if (!instance.Applicants[j].Matched)
                            instance = GoPath(instance, j);
                    }
                }
            }
            return instance;
        }
Beispiel #3
0
        public Instance Match(Instance instance, string path, bool print)
        {
            try
            {
                LP = "";
                if (!System.IO.Directory.Exists(path) && print)
                    System.IO.Directory.CreateDirectory(path);

                GRBEnv env = new GRBEnv("mip1.log");
                GRBModel model = new GRBModel(env);

                List<LPEdge> LPEdges = new List<LPEdge>();


                if (print)
                {
                    instance.Draw().Save(path + "/0Start.bmp");
                }

                int EdgeCounter = 0;
                foreach (Instance.Applicant a in instance.Applicants)
                {
                    EdgeCounter += a.Priorities.Count;
                    foreach (Instance.Priority Prio in a.Priorities)
                    {
                        {
                            LPEdges.Add(new LPEdge(a, instance.Posts[Prio.Target], Prio.Rank));
                            if (Prio.Rank == 0)
                                instance.Posts[Prio.Target].IsF = 1;
                        }
                    }

                }
                // Create variables

                GRBVar[] Edges = new GRBVar[EdgeCounter];

                for (int i = 0; i < Edges.Length; i++)
                {
                    Edges[i] = model.AddVar(0.0, 1.0, 0.0, GRB.BINARY, "ve" + i.ToString());
                }

                // Integrate new variables

                model.Update();

                if (print)
                    LP += "Applicant Matching Conditions:" + Environment.NewLine;

                foreach (Instance.Applicant a in instance.Applicants)
                {
                    GRBLinExpr Temp = new GRBLinExpr();
                    for (int i = 0; i < LPEdges.Count; i++)
                    {
                        if (LPEdges[i].Applicant == a)
                        {
                            Temp += Edges[i];
                            if (print)
                                LP += "(a" + LPEdges[i].Applicant.ID + ", p" + LPEdges[i].Post.ID + ") + ";
                        }
                    }
                    model.AddConstr(Temp == 1.0, "a" + a.ID.ToString());
                    if (print)
                        LP += " = 1;" + Environment.NewLine;
                }

                if (print)
                    LP += Environment.NewLine + "Post Matching Conditions:" + Environment.NewLine;
                
                foreach (Instance.Post p in instance.Posts)
                {
                    GRBLinExpr Temp = new GRBLinExpr();
                    for (int i = 0; i < LPEdges.Count; i++)
                    {
                        if (LPEdges[i].Post == p)
                        {
                            Temp += Edges[i];
                            if (print)
                                LP += "(a" + LPEdges[i].Applicant.ID + ", p" + LPEdges[i].Post.ID + ") + ";
                        }
                    }
                    model.AddConstr(Temp <= 1.0, "p" + p.ID.ToString());
                    if (print)
                        LP += " <= 1;" + Environment.NewLine;
                }

                if (print)
                    LP += Environment.NewLine + "First Choice Conditions:" + Environment.NewLine;

                for (int i = 0; i < LPEdges.Count; i++)
                {
                    LPEdge le1 = LPEdges[i];

                    if (le1.Post.IsF == 1 && le1.Rank != 0)
                    {
                        model.AddConstr(Edges[i] <= 0, "s" + i.ToString());
                        if (print)
                            LP += "(a" + LPEdges[i].Applicant.ID + ", p" + LPEdges[i].Post.ID + ") <= 0;" + Environment.NewLine;

                        for (int j = 0; j < LPEdges[i].Applicant.Priorities.Count; j++)
                        {
                            if (LPEdges[i].Applicant.Priorities[j].Target == LPEdges[i].Post.ID && LPEdges[i].Rank == LPEdges[i].Applicant.Priorities[j].Rank)
                            {
                                LPEdges[i].Applicant.Priorities.RemoveAt(j);
                            }
                        }
                    }
                }

                if (print)
                    LP += Environment.NewLine + "Second Choice Conditions:" + Environment.NewLine;

                for (int i = 0; i < LPEdges.Count; i++)
                {
                    LPEdge le1 = LPEdges[i];

                    foreach (LPEdge le2 in LPEdges)
                    {
                        if (le2 != le1 && le2.Post.IsF == 0 && le1.Applicant == le2.Applicant && le2.Rank != 0 && le2.Rank < le1.Rank)
                        {
                            model.AddConstr(Edges[i] <= 0, "s" + i.ToString());
                            if (print)
                                LP += "(a" + LPEdges[i].Applicant.ID + ", p" + LPEdges[i].Post.ID + ") <= 0;" + Environment.NewLine;
                            for (int j = 0; j < LPEdges[i].Applicant.Priorities.Count; j++)
                            {
                                if (LPEdges[i].Applicant.Priorities[j].Target == LPEdges[i].Post.ID && LPEdges[i].Rank == LPEdges[i].Applicant.Priorities[j].Rank)
                                {
                                    LPEdges[i].Applicant.Priorities.RemoveAt(j);
                                }
                            }
                            break;
                        }
                    }
                }

                if (print)
                    LP += Environment.NewLine + "First Post Conditions:" + Environment.NewLine;

                foreach (Instance.Post p in instance.Posts)
                {
                    if (p.IsF == 1)
                    {
                        GRBLinExpr Temp = new GRBLinExpr();
                        for (int i = 0; i < LPEdges.Count; i++)
                        {
                            if (LPEdges[i].Post == p)
                            {
                                Temp += Edges[i];
                                if (print)
                                    LP += "(a" + LPEdges[i].Applicant.ID + ", p" + LPEdges[i].Post.ID + ") + ";
                            }
                        }
                        model.AddConstr(Temp >= 1.0, "f" + p.ID.ToString());
                        if (print)
                            LP += ">= 1;" + Environment.NewLine;
                    }
                }


                // Optimize model

                model.Optimize();

                if (print)
                {
                    instance.Draw().Save(path + "/1Reduced.bmp");
                }

                for (int i = 0; i < Edges.Length; i++)
                {
                    if (Edges[i].Get(GRB.DoubleAttr.X) == 1)
                    {
                        instance.AddMatch(LPEdges[i].Post.ID, LPEdges[i].Applicant.ID);
                    }
                }

                if (print)
                {
                    instance.Draw().Save(path + "/2Matched.bmp");
                }

                // Dispose of model and env

                model.Dispose();
                env.Dispose();

                return instance;

            }
            catch (GRBException e)
            {
                Console.WriteLine("Error code: " + e.ErrorCode + ". " + e.Message);
                return null;
            }
        }
Beispiel #4
0
        /// <summary>
        /// Check for applicant complete matching
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        private Instance GetApplicantComplete(Instance instance)
        {
            List<int>[] Suitors = new List<int>[instance.Posts.Length];
            for (int i = 0; i < instance.Posts.Length; i++)
            {
                Suitors[i] = new List<int>();
            }

            // create suitors list
            for (int i = 0; i < instance.Applicants.Length; i++)
            {
                for (int j = 0; j < instance.Applicants[i].Priorities.Count; j++)
                {
                    Suitors[instance.Applicants[i].Priorities.ElementAt(j).Target].Add(i);
                }
            }

            int Unmatched = instance.Posts.Length; // # of not full posts
            int UnmatchedApplicants = instance.Applicants.Length; // # unmatched applicants

            for (int i = 0; i < instance.Posts.Length; i++)
            {
                // if a post is connected to only one not matched applicant, match this
                if (Suitors[i].Count == 1 && !instance.Posts[i].Matched && !instance.Applicants[Suitors[i].ElementAt(0)].Matched)
                {
                    instance.Posts[i].Matched = true;
                    instance.AddMatch(i, Suitors[i].ElementAt(0));
                    UnmatchedApplicants--;
                    int Applicant = Suitors[i].ElementAt(0);
                    for (int j = 0; j < instance.Posts.Length; j++)
                    {
                        Suitors[j].Remove(Applicant);
                    }
                }
            }

            for (int i = 0; i < instance.Posts.Length; i++)
            {
                // delete not connected posts
                if (Suitors[i].Count == 0)
                {
                    instance.Posts[i].Matched = true;
                    Unmatched--;
                }
            }


            // check if there is enough space for the remaining applicants
            if (Unmatched < UnmatchedApplicants)
                return null;
            else
            {
                // if yes, walk over the disjoint cycle and take every second edge
                for (int i = 0; i < instance.Applicants.Length; i++)
                {
                    instance = GoPath(instance, i);
                    if (instance == null)
                        instance = null;
                }
            }

            return instance;
        }