/// <summary>
    /// Evaluates the similarity between two maps using the graph sampling evaluation of biagioni and eriksson.
    /// Parameters are hardcoded, based on the ones we used in the corresponding research.
    /// </summary>
    /// <param name="GT">The ground truth map</param>
    /// <param name="CT">the constructed map.</param>
    /// <param name="amount">the amount of neighbourhood evaluations we average over</param>
    /// <returns>A precision and recall value indicating the similarity between the maps.</returns>
    public (float, float) EvalMap(Map GT, Map CT, int amount)
    {
        float precision = 0;
        float recall    = 0;

        for (int k = 0; k < amount; k++)
        {
            Coordinate originGT = rand.GetRandomPointOnRoad(rand.GetWeightedRandomRoad(GT));
            Coordinate originCT = CT.GetClosestPoint(originGT.location);

            /* An extra step that is sometimes used in the literature when ground truth map is not pruned.
             * while (Vector3.Distance(originCT.location, originGT.location) > 50)
             * {
             *  originGT = rand.GetRandomCoordinate(rand.GetWeightedRandomRoad(GT));
             *  originCT = CT.GetClosestPoint(originGT.location);
             * }
             */

            List <Vector3> pointsGT = sampleNeighbourhood.GetNeighbourhood(GT, originGT, 500, 30);
            List <Vector3> pointsCT = sampleNeighbourhood.GetNeighbourhood(CT, originCT, 500, 30);

            MaxFlow flow = new MaxFlow(pointsGT.Count + pointsCT.Count + 2);

            for (int i = 0; i < pointsCT.Count; i++)
            {
                flow.AddEdge(0, i + 1, 1);
            }

            for (int i = 0; i < pointsCT.Count; i++)
            {
                Vector3 pointCT = pointsCT[i];

                for (int j = 0; j < pointsGT.Count; j++)
                {
                    Vector3 pointGT = pointsGT[j];
                    if (Vector3.Distance(pointCT, pointGT) < 20)
                    {
                        flow.AddEdge(i + 1, j + pointsCT.Count + 1, 1);
                    }
                }
            }

            for (int i = 0; i < pointsGT.Count; i++)
            {
                flow.AddEdge(i + pointsCT.Count + 1, 1 + pointsCT.Count + pointsGT.Count, 1);
            }

            float matching = flow.FindMaximumFlow(0, 1 + pointsCT.Count + pointsGT.Count).Item1;
            precision += pointsCT.Count > 0 ? matching / pointsCT.Count : 0;
            recall    += pointsGT.Count > 0 ? matching / pointsGT.Count : 0;
        }

        return(precision / amount, recall / amount);
    }
    /// <summary>
    /// Visualizes and evaluates a single random neighbourhood.
    /// </summary>
    /// <param name="GT">Ground truth map</param>
    /// <param name="CT">contructed map</param>
    /// <param name="originDistanceCondition"></param>
    /// <param name="matchDistance"></param>
    /// <returns></returns>
    public (float, float) EvalNeighbourhood(Map GT, Map CT)
    {
        Coordinate originGT = rand.GetRandomPointOnRoad(rand.GetWeightedRandomRoad(GT));
        Coordinate originCT = CT.GetClosestPoint(originGT.location);

        /* An extra step that is sometimes used in the literature when ground truth map is not pruned.
         * while (Vector3.Distance(originCT.location, originGT.location) > 50)
         * {
         *  originGT = rand.GetRandomCoordinate(rand.GetWeightedRandomRoad(GT));
         *  originCT = CT.GetClosestPoint(originGT.location);
         * }
         */

        List <Vector3> pointsGT = sampleNeighbourhood.GetNeighbourhood(GT, originGT, 150, 30);
        List <Vector3> pointsCT = sampleNeighbourhood.GetNeighbourhood(CT, originCT, 150, 30);

        MaxFlow flow = new MaxFlow(pointsGT.Count + pointsCT.Count + 2);

        for (int i = 0; i < pointsCT.Count; i++)
        {
            flow.AddEdge(0, i + 1, 1);           // source edges
        }
        for (int i = 0; i < pointsCT.Count; i++) // edges between CT and GT
        {
            Vector3 pointCT = pointsCT[i];

            for (int j = 0; j < pointsGT.Count; j++)
            {
                Vector3 pointGT = pointsGT[j];
                if (Vector3.Distance(pointCT, pointGT) < 20)
                {
                    flow.AddEdge(i + 1, j + pointsCT.Count + 1, 1);
                }
            }
        }

        for (int i = 0; i < pointsGT.Count; i++)
        {
            flow.AddEdge(i + pointsCT.Count + 1, 1 + pointsCT.Count + pointsGT.Count, 1);                                      // sink edges
        }
        float matching;

        int[,] graph;
        (matching, graph) = flow.FindMaximumFlow(0, 1 + pointsCT.Count + pointsGT.Count);

        float prec   = pointsCT.Count > 0 ? matching / pointsCT.Count : 0;
        float recall = pointsGT.Count > 0 ? matching / pointsGT.Count : 0;

        return(prec, recall);
    }
示例#3
0
    // このコードはテンプレートとして使えます。
    // 0 <= v1 < n1, 0 <= v2 < n2
    public static int[][] BipartiteMatching(int n1, int n2, int[][] des)
    {
        var sv = n1 + n2;
        var ev = sv + 1;
        var mf = new MaxFlow(ev + 1);

        for (int i = 0; i < n1; ++i)
        {
            mf.AddEdge(sv, i, 1);
        }
        for (int j = 0; j < n2; ++j)
        {
            mf.AddEdge(n1 + j, ev, 1);
        }
        foreach (var e in des)
        {
            mf.AddEdge(e[0], n1 + e[1], 1);
        }

        mf.Dinic(sv, ev);
        var map = mf.Map;

        var r = new List <int[]>();

        foreach (var se in map[sv])
        {
            if (se.Capacity > 0)
            {
                continue;
            }

            foreach (var e in map[se.To])
            {
                if (e.Capacity == 0)
                {
                    r.Add(new[] { se.To, e.To - n1 });
                    break;
                }
            }
        }
        return(r.ToArray());
    }
示例#4
0
    static object Solve()
    {
        var(h, w, n) = Read3();
        var ps = Array.ConvertAll(new bool[n], _ => Read4());

        var sv = 400;
        var ev = sv + 1;
        var mf = new MaxFlow(ev + 1);

        for (int i = 0; i < h; i++)
        {
            mf.AddEdge(sv, i, 1);
        }
        for (int i = 0; i < w; i++)
        {
            mf.AddEdge(300 + i, ev, 1);
        }

        for (int i = 0; i < n; i++)
        {
            var(a, b, c, d) = ps[i];
            var ri = 100 + i;
            var ci = 200 + i;
            mf.AddEdge(ri, ci, 1);

            for (int j = a - 1; j < c; j++)
            {
                mf.AddEdge(j, ri, 1);
            }
            for (int j = b - 1; j < d; j++)
            {
                mf.AddEdge(ci, 300 + j, 1);
            }
        }

        return(mf.Dinic(sv, ev));
    }
示例#5
0
    static void Main()
    {
        var(n, m) = Read2();
        var s = Array.ConvertAll(new bool[n], _ => Console.ReadLine().ToCharArray());

        var sv = n * m;
        var ev = sv + 1;
        var mf = new MaxFlow(ev + 1);

        var vs0 = new List <int>();
        var vs1 = new HashSet <int>();

        // checker board
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                if (s[i][j] == '#')
                {
                    continue;
                }

                var v = m * i + j;
                if ((i + j) % 2 == 0)
                {
                    mf.AddEdge(sv, v, 1);
                    vs0.Add(v);
                }
                else
                {
                    mf.AddEdge(v, ev, 1);
                    vs1.Add(v);
                }
            }
        }

        foreach (var v in vs0)
        {
            if (vs1.Contains(v - m))
            {
                mf.AddEdge(v, v - m, 1);
            }
            if (vs1.Contains(v + m))
            {
                mf.AddEdge(v, v + m, 1);
            }
            if (v % m != 0 && vs1.Contains(v - 1))
            {
                mf.AddEdge(v, v - 1, 1);
            }
            if (v % m != m - 1 && vs1.Contains(v + 1))
            {
                mf.AddEdge(v, v + 1, 1);
            }
        }

        var M   = mf.Dinic(sv, ev);
        var map = mf.Map;

        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                if (s[i][j] == '#')
                {
                    continue;
                }

                var v = m * i + j;
                if ((i + j) % 2 == 0)
                {
                    var v2 = map[v].FirstOrDefault(e => e.Capacity == 0 && e.To != sv)?.To;
                    if (v2 == null)
                    {
                        continue;
                    }

                    var(i2, j2) = ((int)v2 / m, (int)v2 % m);
                    if (i == i2)
                    {
                        s[i][Math.Min(j, j2)] = '>';
                        s[i][Math.Max(j, j2)] = '<';
                    }
                    else
                    {
                        s[Math.Min(i, i2)][j] = 'v';
                        s[Math.Max(i, i2)][j] = '^';
                    }
                }
            }
        }

        Console.WriteLine(M);
        foreach (var r in s)
        {
            Console.WriteLine(new string(r));
        }
    }