private void CreateLayerWHOptimizationInfos()
        {
            _actualHeight = 0;
            _actualWidth  = 0;
            foreach (IList <SugiVertex> layer in _layers)
            {
                var layerInfo = new WHOptimizationLayerInfo();

                foreach (SugiVertex vertex in layer)
                {
                    ThrowIfCancellationRequested();

                    layerInfo.LayerHeight = Math.Max(vertex.Size.Height, layerInfo.LayerHeight);
                    layerInfo.LayerWidth += vertex.Size.Width;
                    if (_whOptVertexInfos.TryGetValue(vertex, out WHOptimizationVertexInfo vertexInfo) && vertexInfo.ValuePerCost >= 0)
                    {
                        layerInfo.Vertices.Enqueue(vertexInfo);
                    }
                }

                layerInfo.LayerWidth += Math.Max(0, layer.Count - 1) * Parameters.SliceGap;
                _actualWidth          = Math.Max(layerInfo.LayerWidth, _actualWidth);

                var verticesList = new List <WHOptimizationVertexInfo>();
                foreach (WHOptimizationVertexInfo vertexInfo in layerInfo.Vertices)
                {
                    ThrowIfCancellationRequested();

                    if (!double.IsNaN(vertexInfo.ValuePerCost) &&
                        !double.IsPositiveInfinity(vertexInfo.ValuePerCost) &&
                        !double.IsNegativeInfinity(vertexInfo.ValuePerCost))
                    {
                        verticesList.Add(vertexInfo);
                    }
                }

                verticesList.Sort((v1, v2) => Math.Sign(v2.ValuePerCost - v1.ValuePerCost));

                _actualHeight += layerInfo.LayerHeight + Parameters.LayerGap;
                layerInfo.Vertices.Clear();

                foreach (WHOptimizationVertexInfo vertexInfo in verticesList)
                {
                    layerInfo.Vertices.Enqueue(vertexInfo);
                }

                _whOptLayerInfos.Add(layerInfo);
            }

            _actualHeight -= Parameters.LayerGap;
            _actualWidth  -= Parameters.SliceGap;
        }
Ejemplo n.º 2
0
        private void CreateLayerWHOptInfos(CancellationToken cancellationToken)
        {
            _actualHeight = 0;
            _actualWidth  = 0;
            foreach (var layer in _layers)
            {
                var layerInfo = new WHOptimizationLayerInfo();
                layerInfo.IsInsertedLayer = false;
                foreach (var vertex in layer)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    layerInfo.LayerHeight = Math.Max(vertex.Size.Height, layerInfo.LayerHeight);
                    layerInfo.LayerWidth += vertex.Size.Width;
                    WHOptimizationVertexInfo vertexInfo;
                    if (_whOptVertexInfos.TryGetValue(vertex, out vertexInfo))
                    {
                        if (vertexInfo.ValuePerCost >= 0)
                        {
                            layerInfo.Vertices.Enqueue(vertexInfo);
                        }
                    }
                }
                layerInfo.LayerWidth += Math.Max(0, layer.Count - 1) * Parameters.VertexDistance;
                _actualWidth          = Math.Max(layerInfo.LayerWidth, _actualWidth);
                var vertexList = new List <WHOptimizationVertexInfo>();
                foreach (var v in layerInfo.Vertices)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    if (!double.IsNaN(v.ValuePerCost) && !double.IsPositiveInfinity(v.ValuePerCost) && !double.IsNegativeInfinity(v.ValuePerCost))
                    {
                        vertexList.Add(v);
                    }
                }
                vertexList.Sort(new Comparison <WHOptimizationVertexInfo>(
                                    (v1, v2) => Math.Sign(v2.ValuePerCost - v1.ValuePerCost)));
                _actualHeight += layerInfo.LayerHeight + Parameters.LayerDistance;
                layerInfo.Vertices.Clear();
                foreach (var v in vertexList)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    layerInfo.Vertices.Enqueue(v);
                }
                _whOptLayerInfos.Add(layerInfo);
            }
            _actualHeight -= Parameters.LayerDistance;
            _actualWidth  -= Parameters.VertexDistance;
        }
        private bool DoWHOptimizationStep()
        {
            double desiredWidth = _actualHeight * Parameters.WidthPerHeight;

            int maxWidthLayerIndex = 0;
            var maxWidthLayer      = _whOptLayerInfos[0];

            for (int i = 0; i < _whOptLayerInfos.Count; i++)
            {
                if (_whOptLayerInfos[i].LayerWidth > maxWidthLayer.LayerWidth &&
                    _whOptLayerInfos[i].Vertices.Count > 0 &&
                    _whOptLayerInfos[i].LayerWidth > desiredWidth)
                {
                    maxWidthLayer      = _whOptLayerInfos[i];
                    maxWidthLayerIndex = i;
                }
            }

            if (maxWidthLayer.LayerWidth <= desiredWidth || maxWidthLayer.Vertices.Count <= 0)
            {
                return(false);
            }

            //get a layer nearby the maxWidthLayer
            int insertedLayerIndex = -1;
            WHOptimizationLayerInfo insertedLayerInfo = null;
            IList <SugiVertex>      insertedLayer     = null;

            if (maxWidthLayerIndex < _whOptLayerInfos.Count - 1 &&
                _whOptLayerInfos[maxWidthLayerIndex + 1].IsInsertedLayer &&
                _whOptLayerInfos[maxWidthLayerIndex + 1].LayerWidth < (desiredWidth - maxWidthLayer.Vertices.Peek().Cost))
            {
                insertedLayerIndex = maxWidthLayerIndex + 1;
                insertedLayerInfo  = _whOptLayerInfos[insertedLayerIndex];
                insertedLayer      = _layers[insertedLayerIndex];
            }
            else
            {
                //insert a new layer
                insertedLayerIndex = maxWidthLayerIndex + 1;
                double width = 0;
                double c     = 0;
                if (insertedLayerIndex > 0)
                {
                    foreach (var vertex in _layers[insertedLayerIndex - 1])
                    {
                        width += Math.Max(0, _graph.OutDegree(vertex) - 1) * Parameters.LayerDistance;
                    }
                    c += 1;
                }
                if (insertedLayerIndex < _layers.Count - 1)
                {
                    foreach (var vertex in _layers[insertedLayerIndex])
                    {
                        width += Math.Max(0, _graph.OutDegree(vertex) - 1) * Parameters.LayerDistance;
                    }
                    c += 1;
                }
                if (c > 0)
                {
                    width /= c;
                }

                if (width >= (desiredWidth - _whOptLayerInfos[insertedLayerIndex - 1].Vertices.Peek().Cost))
                {
                    return(false);
                }

                insertedLayerInfo            = new WHOptimizationLayerInfo();
                insertedLayerInfo.LayerWidth = width;
                insertedLayer = new List <SugiVertex>();
                _whOptLayerInfos.Insert(insertedLayerIndex, insertedLayerInfo);
                _layers.Insert(insertedLayerIndex, insertedLayer);

                double height = 0.0;
                while (insertedLayerInfo.LayerWidth < _whOptLayerInfos[insertedLayerIndex - 1].LayerWidth &&
                       _whOptLayerInfos[insertedLayerIndex - 1].Vertices.Count > 0 &&
                       insertedLayerInfo.LayerWidth <= (desiredWidth - _whOptLayerInfos[insertedLayerIndex - 1].Vertices.Peek().Cost))
                {
                    var repositionedVertex = _whOptLayerInfos[insertedLayerIndex - 1].Vertices.Dequeue();
                    insertedLayerInfo.LayerWidth += repositionedVertex.Cost;
                    _whOptLayerInfos[insertedLayerIndex - 1].LayerWidth -= repositionedVertex.Value;
                    _layers[insertedLayerIndex - 1].Remove(repositionedVertex.Vertex);
                    insertedLayer.Add(repositionedVertex.Vertex);
                    height = Math.Max(height, repositionedVertex.Vertex.Size.Height);
                }
                _actualHeight += height + Parameters.LayerDistance;
                _actualWidth   = _whOptLayerInfos.Max(li => li.LayerWidth);
            }


            return(true);
        }
        private bool DoWHOptimizationStep()
        {
            double desiredWidth = _actualHeight * Parameters.WidthPerHeight;

            int maxWidthLayerIndex = 0;
            var maxWidthLayer      = _whOptLayerInfos[0];

            for (int i = 0; i < _whOptLayerInfos.Count; ++i)
            {
                if (_whOptLayerInfos[i].LayerWidth > maxWidthLayer.LayerWidth &&
                    _whOptLayerInfos[i].Vertices.Count > 0 &&
                    _whOptLayerInfos[i].LayerWidth > desiredWidth)
                {
                    maxWidthLayer      = _whOptLayerInfos[i];
                    maxWidthLayerIndex = i;
                }
            }

            if (maxWidthLayer.LayerWidth <= desiredWidth || maxWidthLayer.Vertices.Count <= 0)
            {
                return(false);
            }

            // Insert a new layer
            int    insertedLayerIndex = maxWidthLayerIndex + 1;
            double width = 0;
            double c     = 0;

            if (insertedLayerIndex > 0)
            {
                foreach (SugiVertex vertex in _layers[insertedLayerIndex - 1])
                {
                    width += Math.Max(0, _graph.OutDegree(vertex) - 1) * Parameters.LayerGap;
                }

                ++c;
            }
            if (insertedLayerIndex < _layers.Count - 1)
            {
                foreach (SugiVertex vertex in _layers[insertedLayerIndex])
                {
                    width += Math.Max(0, _graph.OutDegree(vertex) - 1) * Parameters.LayerGap;
                }

                ++c;
            }

            if (c > 0)
            {
                width /= c;
            }

            if (width >= desiredWidth - _whOptLayerInfos[insertedLayerIndex - 1].Vertices.Peek().Cost)
            {
                return(false);
            }

            var insertedLayerInfo = new WHOptimizationLayerInfo();
            var insertedLayer     = new List <SugiVertex>();

            _whOptLayerInfos.Insert(insertedLayerIndex, insertedLayerInfo);
            _layers.Insert(insertedLayerIndex, insertedLayer);

            double height = 0.0;

            while (insertedLayerInfo.LayerWidth < _whOptLayerInfos[insertedLayerIndex - 1].LayerWidth &&
                   _whOptLayerInfos[insertedLayerIndex - 1].Vertices.Count > 0 &&
                   insertedLayerInfo.LayerWidth <= desiredWidth - _whOptLayerInfos[insertedLayerIndex - 1].Vertices.Peek().Cost)
            {
                WHOptimizationVertexInfo repositionedVertex = _whOptLayerInfos[insertedLayerIndex - 1].Vertices.Dequeue();
                insertedLayerInfo.LayerWidth += repositionedVertex.Cost;
                _whOptLayerInfos[insertedLayerIndex - 1].LayerWidth -= repositionedVertex.Value;
                _layers[insertedLayerIndex - 1].Remove(repositionedVertex.Vertex);
                insertedLayer.Add(repositionedVertex.Vertex);
                height = Math.Max(height, repositionedVertex.Vertex.Size.Height);
            }

            _actualHeight += height + Parameters.LayerGap;
            _actualWidth   = _whOptLayerInfos.Max(li => li.LayerWidth);

            return(true);
        }