예제 #1
0
        public override SpecificLayout GetBestLayout(LayoutQuery query)
        {
            if (this.true_queryResults == null)
            {
                this.Initialize();
            }
            numQueries++;
            if (numQueries % 10000 == 0)
            {
                double rate = (double)numComputations / (double)numQueries;
                System.Diagnostics.Debug.WriteLine("Overall LayoutCache miss rate: " + numComputations + " of " + numQueries + " = " + rate);
                if (rate < 0.02)
                {
                    System.Diagnostics.Debug.WriteLine("Surprisingly high layoutcache hit rate");
                }
            }

            SpecificLayout fastResult = this.GetBestLayout_Quickly(query);

            if (query.Debug)
            {
                SpecificLayout correctResult = this.Query_SubLayout(query);
                if (correctResult != null && !query.Accepts(correctResult))
                {
                    ErrorReporter.ReportParadox("Error: LayoutCache was given an incorrect response by its sublayout");
                }
                bool correct = true;
                if (query.PreferredLayout(correctResult, fastResult) != correctResult)
                {
                    ErrorReporter.ReportParadox("Error: layout cache returned incorrect (superior) result");
                    query.ProposedSolution_ForDebugging = fastResult;
                    correct = false;
                }
                if (query.PreferredLayout(fastResult, correctResult) != fastResult)
                {
                    ErrorReporter.ReportParadox("Error: layout cache returned incorrect (inferior) result");
                    query.ProposedSolution_ForDebugging = correctResult;
                    correct = false;
                }
                if (!correct)
                {
                    this.GetBestLayout_Quickly(query);
                    this.Query_SubLayout(query);
                }
                this.debugCheck(new LayoutQuery_And_Response(query, fastResult));
                return(this.prepareLayoutForQuery(correctResult, query));
            }
            //this.debugCheck(new LayoutQuery_And_Response(query, fastResult));
            if (fastResult != null)
            {
                fastResult = fastResult.Clone();
            }
            return(this.prepareLayoutForQuery(fastResult, query));
        }
예제 #2
0
        public override SpecificLayout GetBestLayout(LayoutQuery query)
        {
            SpecificLayout best_specificLayout = null;
            SpecificLayout debugResult         = query.ProposedSolution_ForDebugging;

            if (debugResult != null)
            {
                debugResult = debugResult.Clone();
            }
            List <LayoutChoice_Set> good_sourceLayouts = new List <LayoutChoice_Set>();
            LayoutQuery             originalQuery      = query;

            foreach (LayoutChoice_Set layoutSet in this.layoutOptions)
            {
                if (best_specificLayout != null)
                {
                    // make the query more strict, so we will only ever get dimensions that are at least as good as this
                    // TODO: figure out why it's not better to use OptimizedPastExample
                    query = query.OptimizedUsingExample(best_specificLayout);
                }
                SpecificLayout currentLayout;
                if (query.Debug)
                {
                    // if the proposed layout is an option, then be sure to consider it
                    if (debugResult != null && debugResult.GetAncestors().Contains(layoutSet))
                    {
                        query.ProposedSolution_ForDebugging = debugResult;
                        currentLayout = layoutSet.GetBestLayout(query);
                        query.ProposedSolution_ForDebugging = debugResult;
                        return(this.prepareLayoutForQuery(currentLayout, query));
                    }
                }
                currentLayout = layoutSet.GetBestLayout(query);

                if (currentLayout != null && query.PreferredLayout(currentLayout, best_specificLayout) == currentLayout)
                {
                    // keep track of this query (which must be the best so far)
                    best_specificLayout = currentLayout;
                    good_sourceLayouts.Add(layoutSet);

                    if (query.Debug && query.ProposedSolution_ForDebugging != null)
                    {
                        if (query.PreferredLayout(query.ProposedSolution_ForDebugging, best_specificLayout) != query.ProposedSolution_ForDebugging)
                        {
                            ErrorReporter.ReportParadox("Error; query " + query + " prefers " + best_specificLayout + " over proposed debug solution " + query.ProposedSolution_ForDebugging);
                            LayoutQuery debugQuery = query.DebugClone();
                            layoutSet.GetBestLayout(debugQuery);
                        }
                    }
                }
            }
            originalQuery.ProposedSolution_ForDebugging = debugResult;
            return(this.prepareLayoutForQuery(best_specificLayout, originalQuery));
        }
예제 #3
0
        private SpecificLayout GetBestLayout_Quickly(LayoutQuery query)
        {
            SpecificLayout result = null;

            // A layout of size 0 in one dimension doesn't get any points for being nonzero in the other dimension
            if ((query.MaxHeight == 0) != (query.MaxWidth == 0))
            {
                result = this.GetBestLayout_Quickly(this.SizeZeroQuery);
                if (query.Accepts(result))
                {
                    return(result);
                }
                return(null);
            }

            // check whether we've previously saved the result
            if (!query.Debug)
            {
                if (this.true_queryResults.TryGetValue(query, out result) || this.inferred_queryResults.TryGetValue(query, out result))
                {
                    if (result != null)
                    {
                        return(result);
                    }
                    return(null);
                }
            }
            // the result wasn't saved, so we need to delegate the layout query
            // However, we might first be able to make the query more strict

            LayoutQuery_And_Response broadened = this.Find_LargerQuery(query);

            if (broadened != null)
            {
                if (query.Debug)
                {
                    LayoutQuery debugQuery = query.Clone();
                    debugQuery.Debug = true;
                    SpecificLayout correct_subLayout = this.Query_SubLayout(debugQuery);
                    if (broadened.Query.PreferredLayout(broadened.Response, correct_subLayout) != broadened.Response)
                    {
                        ErrorReporter.ReportParadox("Error; incorrect result for broadened query: broadened query " + broadened.Query + " returned " + broadened.Response +
                                                    " whereas the response from the sublayout for debug query " + debugQuery + " is " + correct_subLayout);
                        LayoutQuery debugQuery2 = broadened.Query.DebugClone();
                        debugQuery2.ProposedSolution_ForDebugging = correct_subLayout;
                        this.GetBestLayout(debugQuery2);
                    }
                }
                return(this.inferredLayout(query, broadened.Response));
            }
            LayoutQuery_And_Response shrunken = this.FindExample(query);

            if (query.Debug)
            {
                if (shrunken != null)
                {
                    LayoutQuery debugQuery = shrunken.Query.Clone();
                    debugQuery.Debug = true;
                    SpecificLayout correct_subLayout = this.Query_SubLayout(debugQuery);
                    if (shrunken.Query.PreferredLayout(shrunken.Response, correct_subLayout) != shrunken.Response)
                    {
                        ErrorReporter.ReportParadox("Error; incorrect result for shrunken query");
                    }
                }
            }

            if (shrunken != null)
            {
                // If the existing example is already at the extreme, then use it
                if (query.MaximizesScore())
                {
                    if (shrunken.Response.Width >= query.MaxWidth && shrunken.Response.Height >= query.MaxHeight)
                    {
                        return(this.inferredLayout(query, shrunken.Response));
                    }
                }
                if (query.MinimizesWidth())
                {
                    if (shrunken.Response.Width <= 0)
                    {
                        return(this.inferredLayout(query, shrunken.Response));
                    }
                }
                if (query.MinimizesHeight())
                {
                    if (shrunken.Response.Height <= 0)
                    {
                        return(this.inferredLayout(query, shrunken.Response));
                    }
                }
            }
            // if we couldn't immediately return a result using the cache, we can still put a bound on the results we might get
            // They have to be at least as good as the sample we found
            if (shrunken != null)
            {
                // First, see if we can improve past what we currently have
                LayoutQuery strictlyImprovedQuery = query.OptimizedPastExample(shrunken.Response);
                bool        allowCache            = !strictlyImprovedQuery.Accepts(shrunken.Response);

                // Ask the sublayout for this result (or use the cache if we've already asked)
                if (allowCache)
                {
                    result = this.GetBestLayout_Quickly(strictlyImprovedQuery);
                }
                else
                {
                    result = this.Query_SubLayout(strictlyImprovedQuery);
                }
                if (result == null)
                {
                    result = shrunken.Response;
                }
                return(this.inferredLayout(query, result));
            }
            else
            {
                result = this.Query_SubLayout(query);
            }

            if (result == null)
            {
                if (shrunken != null && query.Accepts(shrunken.Response))
                {
                    ErrorReporter.ReportParadox("Error: cache contains an acceptable value for the current query, but the layout claims there are none");
                    result = shrunken.Response;
                }
            }

            // record that this is the exact answer to this query
            LayoutQuery_And_Response queryAndResponse = new LayoutQuery_And_Response(query, result);

            this.orderedResponses.Add(queryAndResponse);


            //this.debugCheck(queryAndResponse);

            if (result != null)
            {
                result = result.Clone();
            }
            return(result);
        }