예제 #1
0
        // gets the best position for the rect on the board
        // the rect given to this method does not have to be initialized on 0/0
        public void GetValidPositions(List<Rect> rectList, Rect rect, Boolean evolution)
        {
            // position = position of rect 0/0
            Position position = new Position();
            position.edgeLeftUp.x = 0;
            position.edgeLeftUp.y = rect.height;
            position.edgeRightDown.x = rect.width;
            position.edgeRightDown.y = 0;

            // largest part of this method, recursive
            ManagePosition(rectList, rect, position, evolution);
        }
예제 #2
0
        // returns the position numbers of the rects in RectListBoard where collisions where detected
        // RectListBoard = list of the board where the collision is searched (and where the rect should be placed)
        // rect = the rect to be placed
        public List<int> GetCollisions(List<Rect> rectListBoard, Rect rect)
        {
            List<int> collisionList = new List<int>();

            // coordinates of the existing rect
            float x1;
            float x2;
            float y1;
            float y2;

            // coordinates of the new rect
            float u1;
            float u2;
            float v1;
            float v2;

            for(int i = 0; i < rectListBoard.Count; i++)
            {
                x1 = rectListBoard[i].edgeLeftUp.x;
                x2 = rectListBoard[i].edgeRightDown.x;
                y1 = rectListBoard[i].edgeRightDown.y;
                y2 = rectListBoard[i].edgeLeftUp.y;

                u1 = rect.edgeLeftUp.x;
                u2 = rect.edgeRightDown.x;
                v1 = rect.edgeRightDown.y;
                v2 = rect.edgeLeftUp.y;

                // collision detection
                if((
                   (u1 < x1 && x1 < u2) ||
                   (u1 < x2 && x2 < u2) ||
                   (x1 < u1 && u1 < x2) ||
                   (x1 < u2 && u2 < x2) ||
                   (x1 == u1 && x2 == u2)) &&
                   (
                   (v1 < y1 && y1 < v2) ||
                   (v1 < y2 && y2 < v2) ||
                   (y1 < v1 && v1 < y2) ||
                   (y1 < v2 && v2 < y2) ||
                   (y1 == v1 && y2 == v2))
                   )
                {
                    collisionList.Add(i);
                }
            }

            return collisionList;
        }
        public void CreateRects(int minRects, int maxRects, Benchmark benchmark)
        {
            int rectID = 1;
            Random random = new Random();
            for (int i = 0; i < benchmark.boardList.Count; i++)
            {
                int numberOfRequiredRects = random.Next(minRects, maxRects + 1);

                // "convert" the board to a rect, meaning adding a rect to the board with the size of the board
                Rect rect = new Rect();
                rect.height = benchmark.boardList[i].height;
                rect.width = benchmark.boardList[i].width;
                rect.size = rect.height * rect.width;
                rect.edgeLeftUp = new MyPoint(0, rect.height);
                rect.edgeRightDown = new MyPoint(rect.width, 0);
                benchmark.boardList[i].RectList.Add(rect);

                // split the largest rect of the rectList until number of rects = required number of rects
                for (int j = 1; j < numberOfRequiredRects; j++)
                {
                    Rect largestRect = new Rect();
                    Rect rectOne = new Rect();
                    Rect rectTwo = new Rect();

                    Boolean nullCoordsOccured = true;
                    while(nullCoordsOccured == true)
                    {
                        // 1. find largest rect
                        largestRect = benchmark.boardList[i].RectList[0];
                        for (int k = 0; k < benchmark.boardList[i].RectList.Count; k++)
                        {
                            if (benchmark.boardList[i].RectList[k].size > largestRect.size)
                            {
                                largestRect = benchmark.boardList[i].RectList[k];
                            }
                        }
                        // 2. decide if to split horizontal or vertical
                        Boolean splitVertical;

                        if (random.Next(0, 2) == 0)
                        {
                            splitVertical = false;
                        }
                        else
                        {
                            splitVertical = true;
                        }
                        // 3. create two new rects out of the largest one and add them to the rect list
                        rectOne = new Rect();
                        rectTwo = new Rect();

                        if (splitVertical)
                        {
                            double largestRectWidthDouble = Convert.ToDouble(largestRect.width);
                            // new width between 10% and 90% of largestRect's width
                            // several conversions have to be done to use Ceiling and random for integer
                            int newWidth = Convert.ToInt32(Math.Ceiling(largestRectWidthDouble * (Convert.ToDouble(random.Next(1, 10)) / 10)));
                            if (newWidth == largestRect.width)
                            {
                                // this would not create 2 new rects. retry
                                nullCoordsOccured = true;
                            }
                            else
                            {
                                rectOne.height = largestRect.height;
                                rectTwo.height = largestRect.height;
                                rectOne.width = newWidth;
                                rectTwo.width = largestRect.width - newWidth;

                                rectOne.edgeLeftUp = largestRect.edgeLeftUp;
                                rectOne.edgeRightDown = new MyPoint(largestRect.edgeLeftUp.x + rectOne.width, largestRect.edgeRightDown.y);

                                rectTwo.edgeLeftUp = new MyPoint(rectOne.edgeRightDown.x, rectOne.edgeLeftUp.y);
                                rectTwo.edgeRightDown = largestRect.edgeRightDown;

                                nullCoordsOccured = false;

                            }
                        }
                        // if split horizontal
                        else
                        {
                            double largestRectHeightDouble = Convert.ToDouble(largestRect.height);
                            // new height between 10% and 90% of largestRect's height
                            // several conversions have to be done to use Ceiling and random for integer
                            int newHeight = Convert.ToInt32(Math.Ceiling(largestRectHeightDouble * (Convert.ToDouble(random.Next(1, 10)) / 10)));
                            if (newHeight == largestRect.height)
                            {
                                // this would not create 2 new rects. retry
                                nullCoordsOccured = true;
                            }
                            else
                            {
                                rectOne.height = newHeight;
                                rectTwo.height = largestRect.height - newHeight;
                                rectOne.width = largestRect.width;
                                rectTwo.width = largestRect.width;

                                rectOne.edgeLeftUp = largestRect.edgeLeftUp;
                                rectOne.edgeRightDown = new MyPoint(largestRect.edgeRightDown.x, largestRect.edgeLeftUp.y - rectOne.height);

                                rectTwo.edgeLeftUp = new MyPoint(rectOne.edgeLeftUp.x, rectOne.edgeRightDown.y);
                                rectTwo.edgeRightDown = largestRect.edgeRightDown;

                                nullCoordsOccured = false;
                            }
                        }
                    }

                    // add rect data
                    rectOne.size = rectOne.height * rectOne.width;
                    rectTwo.size = rectTwo.height * rectTwo.width;

                    // add rects to list
                    benchmark.boardList[i].RectList.Add(rectOne);
                    benchmark.boardList[i].RectList.Add(rectTwo);

                    // 4. remove the largest rect from the rect list
                    benchmark.boardList[i].RectList.Remove(largestRect);
                }

                // add rectIDs
                for (int j = 0; j < benchmark.boardList[i].RectList.Count; j++)
                {
                    benchmark.boardList[i].RectList[j].rectID = rectID;
                    rectID++;
                }

                // add number of rects and number of boards
                benchmark.numberOfRects = 0;
                for(int l = 0; l < benchmark.boardList.Count; l++)
                {
                    benchmark.numberOfRects += benchmark.boardList[i].RectList.Count;
                }
                benchmark.numberOfBoards = benchmark.boardList.Count;

            }
            // for testing:
            //1. size test
            String success = "success";
            for (int i = 0; i < benchmark.boardList.Count; i++)
            {
                int size = benchmark.boardList[i].size;
                for (int j = 0; j < benchmark.boardList[i].RectList.Count; j++)
                {
                    size -= benchmark.boardList[i].RectList[j].size;
                }
                if (size != 0)
                {
                    success = "fail";
                }
            }
            // 2. > 236 test
            for (int i = 0; i < benchmark.boardList.Count; i++)
            {
                for (int j = 0; j < benchmark.boardList[i].RectList.Count; j++)
                {
                    /*
                    if (benchmark.boardList[i].RectList[j].edgeLeftUp.y > 236)
                    {
                        int s = 1;
                    }
                    */
                }
            }
        }
        // creates a basic solution without rects placed, according to the benchmark
        public void CreateBasicSolution(Base global, Benchmark benchmark)
        {
            Solution solution = new Solution();

            // set solution ID
            string path = Environment.CurrentDirectory;
            // without bin\Debug
            path = path.Substring(0, path.Length - 9) + "Resources\\SolutionNr.txt";
            solution.SolutionID = Convert.ToInt32(System.IO.File.ReadAllText(path));

            // set creationTime
            solution.creationTime = DateTime.Now;

            // set Benchmark to solution
            solution.benchmark = benchmark;
            solution.usedBenchmarkID = benchmark.benchmarkID;

            // add boards
            solution.BoardList = new List<Board>();

            for (int i = 0; i < benchmark.boardList.Count; i++)
            {
                Board board = new Board();
                board.boardID = i + 1;
                board.height = benchmark.boardList[0].height;
                board.width = benchmark.boardList[0].width;
                board.isCollectionBoard = false;
                board.size = board.height * board.width;

                solution.BoardList.Add(board);
            }
            // add collection board
            Board collectionBoard = new Board();
            collectionBoard.boardID = solution.BoardList.Count + 1;
            collectionBoard.height = benchmark.boardList[0].height;
            collectionBoard.width = benchmark.boardList[0].width * 2;
            collectionBoard.isCollectionBoard = true;
            collectionBoard.size = collectionBoard.height * collectionBoard.width;

            solution.BoardList.Add(collectionBoard);

            // add rects to collection board, sorted from largest to smallest and height > width (change these parameters if necessary)
            // also remove the coordinates from the rects
            for(int i = 0; i < benchmark.boardList.Count; i++)
            {
                for(int j = 0; j < benchmark.boardList[i].RectList.Count; j++)
                {
                    Rect rect = new Rect();
                    rect.rectID = benchmark.boardList[i].RectList[j].rectID;
                    rect.size = benchmark.boardList[i].RectList[j].size;
                    if(benchmark.boardList[i].RectList[j].height < benchmark.boardList[i].RectList[j].width)
                    {
                        rect.height = benchmark.boardList[i].RectList[j].width;
                        rect.width = benchmark.boardList[i].RectList[j].height;
                    }
                    else
                    {
                        rect.height = benchmark.boardList[i].RectList[j].height;
                        rect.width = benchmark.boardList[i].RectList[j].width;
                    }
                    rect.edgeLeftUp = new MyPoint(0,0);
                    rect.edgeRightDown = new MyPoint(0,0);

                    collectionBoard.RectList.Add(rect);
                }
            }

            // sort the rects in rect list from largest size to smallest size (new version; old version below)
            Tools tools = new Tools();
            tools.QuickSortRectBySizeDec(0, collectionBoard.RectList.Count - 1, collectionBoard.RectList);

            // old version, new version = using quicksort
            /*
            // sort the rect list
            List<Rect> rectList = new List<Rect>();
            // as long as rects exist
            while (collectionBoard.RectList.Count > 0)
            {
                // search the largest rect (by size), then add to rectList and remove from collectionBoard List
                Rect largestRect = collectionBoard.RectList[0];
                for (int i = 1; i < collectionBoard.RectList.Count; i++)
                {
                    if(collectionBoard.RectList[i].size > largestRect.size)
                    {
                        largestRect = collectionBoard.RectList[i];
                    }
                }
                rectList.Add(largestRect);
                collectionBoard.RectList.Remove(largestRect);
            }
            collectionBoard.RectList = rectList;
            */

            // add the remaining parameters to solution
            solution.numberOfRects = collectionBoard.RectList.Count;
            solution.percentageFilledArea = 0;

            global.solution = solution;
            global.emptySolution = tools.CloneSolution(solution);

            // cl values
            ClassificationNumbers clNumbers = new ClassificationNumbers(global);
            clNumbers.GetAndShowAllClassificationNumbers();
        }
예제 #5
0
        public Solution Greedy(Boolean evolution, Solution solutionEvo)
        {
            Base global = Base.GetInstance();
            Solution solution;
            if(evolution)
            {
                solution = solutionEvo;
            }
            else
            {
                solution = global.solution;
            }

            ClassificationNumbers classificationNumbers = new ClassificationNumbers(global);

            // preparations
            if(!evolution)
            {
                global.runningProcess.state = 1;
            }
            Tools tools = new Tools();

            // START one time:
            if (evolution || global.runningProcess.firstStep)
            {
                // next rect to pick of the list: the first one (default)
                if(!evolution)
                {
                    global.runningProcess.nextStep = 0;
                }
                else
                {
                    global.nextStepGreedyEvo = 0;
                }

                global.positionsManaged = new List<Position>();
                global.positionsValid = new List<Position>();

                if((global.Verschnittoptimierung.radioButton_largestSideInc.Checked && !evolution) ||
                    (evolution && global.selectedGreedy == 1) ||
                    (evolution && global.selectedGreedy == 2) ||
                    (evolution && global.selectedGreedy == 9) ||
                    (evolution && global.selectedGreedy == 10)
                    )
                {
                    // sort rects from min largest side to max largest side
                    tools.QuickSortRectByLargestSizeInc(0,
                        solution.BoardList[solution.BoardList.Count - 1].RectList.Count - 1, solution.BoardList[solution.BoardList.Count - 1].RectList);
                }
                else if((global.Verschnittoptimierung.radioButton_largestSideDec.Checked && !evolution) ||
                    (evolution && global.selectedGreedy == 3) ||
                    (evolution && global.selectedGreedy == 4) ||
                    (evolution && global.selectedGreedy == 11) ||
                    (evolution && global.selectedGreedy == 12)
                    )
                {
                    // sort rects from min largest side to max largest side
                    tools.QuickSortRectByLargestSideDec(0,
                        solution.BoardList[solution.BoardList.Count - 1].RectList.Count - 1, solution.BoardList[solution.BoardList.Count - 1].RectList);
                }
                else if((global.Verschnittoptimierung.radioButton_sizeInc.Checked) ||
                    (evolution && global.selectedGreedy == 5) ||
                    (evolution && global.selectedGreedy == 6) ||
                    (evolution && global.selectedGreedy == 13) ||
                    (evolution && global.selectedGreedy == 14)
                    )
                {
                    // sort rects from min size to max size
                    tools.QuickSortRectBySizeInc(0,
                        solution.BoardList[solution.BoardList.Count - 1].RectList.Count - 1, solution.BoardList[solution.BoardList.Count - 1].RectList);
                }
                else if((global.Verschnittoptimierung.radioButton_sizeDec.Checked) ||
                    (evolution && global.selectedGreedy == 7) ||
                    (evolution && global.selectedGreedy == 8) ||
                    (evolution && global.selectedGreedy == 15) ||
                    (evolution && global.selectedGreedy == 16)
                    )
                {
                    // sort rects from max size to min size
                    tools.QuickSortRectBySizeDec(0,
                        solution.BoardList[solution.BoardList.Count - 1].RectList.Count - 1, solution.BoardList[solution.BoardList.Count - 1].RectList);
                }
                if(!evolution)
                {
                    global.runningProcess.firstStep = false;
                }
            }
            // END one time

            // for each rect on collectionBoard
            for (int i = (evolution ? global.nextStepGreedyEvo : global.runningProcess.nextStep);
                i < solution.BoardList[solution.BoardList.Count - 1].RectList.Count;)
            {
                if(!evolution)
                {
                    global.runningProcess.state = 1;
                }

                // sort boards from max free space to least free space
                List<int> boardNrSorted = tools.SortBoardsBySize(solution.BoardList);

                // for each board try to place the rect
                for (int j = 0; j < boardNrSorted.Count - 1; j++)
                {
                    // try place the rect
                    // 1. is the space as area enough for the board? (without finding a specific place)
                    // calculate boardSizeEffective
                    int boardSizeEffective = solution.BoardList[boardNrSorted[j]].size;
                    for (int k = 0; k < solution.BoardList[boardNrSorted[j]].RectList.Count; k++)
                    {
                        boardSizeEffective -= solution.BoardList[boardNrSorted[j]].RectList[k].size;
                    }
                    if (boardSizeEffective < solution.BoardList[solution.BoardList.Count - 1].RectList[i].size)
                    {
                        // rect is too large, cannot be placed on any of the boards.
                        // has to remain on the collectionBoard
                        if(!evolution)
                        {
                            classificationNumbers.GetAndShowAllClassificationNumbers();
                        }
                        break;
                    }

                    // 2. try to place the rect in the selected board
                    // clone the rect
                    Rect rect = new Rect();
                    rect.edgeLeftUp = new MyPoint();
                    rect.edgeRightDown = new MyPoint();
                    rect.rectID = solution.BoardList[solution.BoardList.Count - 1].RectList[i].rectID;
                    rect.size = solution.BoardList[solution.BoardList.Count - 1].RectList[i].size;
                    rect.width = solution.BoardList[solution.BoardList.Count - 1].RectList[i].width;
                    rect.height = solution.BoardList[solution.BoardList.Count - 1].RectList[i].height;
                    /*
                    rect.edgeLeftUp.x = solution.BoardList[solution.BoardList.Count - 1].RectList[i].edgeLeftUp.x;
                    rect.edgeLeftUp.y = solution.BoardList[solution.BoardList.Count - 1].RectList[i].edgeLeftUp.y;
                    rect.edgeRightDown.x = solution.BoardList[solution.BoardList.Count - 1].RectList[i].edgeRightDown.x;
                    rect.edgeRightDown.y = solution.BoardList[solution.BoardList.Count - 1].RectList[i].edgeRightDown.y;
                    */

                    // reset values in global
                    global.positionsManaged = new List<Position>();
                    global.positionsValid = new List<Position>();
                    global.bestPositionSet = false;

                    // TODO: this part(vertical, then horizontal / or only one if equal) should be moved to GetValidPos()
                    // first vertical, then horizontal
                    if (rect.width == rect.height)
                    {
                        rect.edgeLeftUp.x = 0;
                        rect.edgeLeftUp.y = rect.height;
                        rect.edgeRightDown.x = rect.width;
                        rect.edgeRightDown.y = 0;

                        GetValidPositions(solution.BoardList[boardNrSorted[j]].RectList, rect, evolution);
                    }
                    else
                    {
                        // 1. vertical
                        if (rect.width > rect.height)
                        {
                            int helper = rect.width;
                            rect.width = rect.height;
                            rect.height = helper;
                        }
                        rect.edgeLeftUp.x = 0;
                        rect.edgeLeftUp.y = rect.height;
                        rect.edgeRightDown.x = rect.width;
                        rect.edgeRightDown.y = 0;

                        GetValidPositions(solution.BoardList[boardNrSorted[j]].RectList, rect, evolution);
                        // 2. horizontal
                        if (rect.height > rect.width)
                        {
                            int helper = rect.width;
                            rect.width = rect.height;
                            rect.height = helper;
                        }
                        rect.edgeLeftUp.x = 0;
                        rect.edgeLeftUp.y = rect.height;
                        rect.edgeRightDown.x = rect.width;
                        rect.edgeRightDown.y = 0;

                        GetValidPositions(solution.BoardList[boardNrSorted[j]].RectList, rect, evolution);
                    }

                    // select the best position of the valid ones
                    SelectBestPosition(evolution);

                    Boolean rectPlaced = false;

                    if (global.bestPositionSet == true)
                    {
                        // 1. show valid positions

                        // 2. show best position

                        // 3. place best position
                        rect.edgeLeftUp.x = global.bestPosition.edgeLeftUp.x;
                        rect.edgeLeftUp.y = global.bestPosition.edgeLeftUp.y;
                        rect.edgeRightDown.x = global.bestPosition.edgeRightDown.x;
                        rect.edgeRightDown.y = global.bestPosition.edgeRightDown.y;

                        solution.BoardList[boardNrSorted[j]].RectList.Add(rect);
                        //solution.BoardList[solution.BoardList.Count - 1].RectList.Remove(rect);
                        solution.BoardList[solution.BoardList.Count - 1].RectList.RemoveAt(i);

                        // ....
                        rectPlaced = true;
                        // show can't be called from here

                        if(!evolution)
                        {
                            // check for best solution and set if necessary
                            tools.CheckForBestSolution();

                            // show solution
                            Show show = new Show(global);
                            show.ShowSolution(global.solution);
                        }
                    }

                    // last rect tried?
                    if (solution.BoardList[solution.BoardList.Count - 1].RectList.Count == 0 ||
                        (solution.BoardList[solution.BoardList.Count - 1].RectList.Count - 1) < (evolution ? global.nextStepGreedyEvo : global.runningProcess.nextStep))
                    {
                        if(!evolution)
                        {
                            global.runningProcess.existing = false;
                            global.runningProcess.state = 0;
                            classificationNumbers.GetAndShowAllClassificationNumbers();
                        }
                        break;
                    }

                    if (rectPlaced)
                    {
                        if(!evolution)
                        {
                            global.runningProcess.state = 0;
                            classificationNumbers.GetAndShowAllClassificationNumbers();
                        }
                        break;
                    }
                    if (!rectPlaced)
                    {
                        if(!evolution)
                        {
                            global.runningProcess.nextStep++;
                        }
                        else
                        {
                            global.nextStepGreedyEvo++;
                        }
                        i++;

                        if ((solution.BoardList[solution.BoardList.Count - 1].RectList.Count - 1) < (evolution ? global.nextStepGreedyEvo : global.runningProcess.nextStep))
                        {
                            if(!evolution)
                            {
                                global.runningProcess.existing = false;
                                global.runningProcess.state = 0;
                                classificationNumbers.GetAndShowAllClassificationNumbers();
                            }
                            break;
                        }
                    }
                }

                if(!evolution && global.runningProcess.stepType == 0)
                {
                    global.runningProcess.state = 0;
                    classificationNumbers.GetAndShowAllClassificationNumbers();
                    break;
                }
            }
            if(!evolution)
            {
                global.runningProcess.state = 0;
                classificationNumbers.GetAndShowAllClassificationNumbers();
            }
            return solution;
        }
예제 #6
0
        // one step for a single position
        public void ManagePosition(List<Rect> rectList, Rect rect, Position position, Boolean evolution)
        {
            Base global = Base.GetInstance();
            // 1.1 position out of borders? (boardHeight<rectY etc.)
            // TODO: general board width/height not set, therefore using height/width of the first board in the solution
            if (position.edgeLeftUp.y > global.solution.BoardList[0].height || position.edgeRightDown.x > global.solution.BoardList[0].width)
            {
                return;
            }

            // 1.2 position already managed? (already tried in another recursive call)
            for(int i = 0; i < global.positionsManaged.Count; i++)
            {
                // if yes, stop this method
                if (position.IsEqualPositionAs(global.positionsManaged[i]))
                {
                    return;
                }
            }
            // if no (then the method reaches this point), add to positions managed
            global.positionsManaged.Add(position);

            // 2. collision?
            Collision collision = new Collision();
            Rect rectCopy = new Rect();
            rectCopy.edgeLeftUp.x = position.edgeLeftUp.x;
            rectCopy.edgeLeftUp.y = position.edgeLeftUp.y;
            rectCopy.edgeRightDown.x = position.edgeRightDown.x;
            rectCopy.edgeRightDown.y = position.edgeRightDown.y;
            rectCopy.height = rect.height;
            rectCopy.width = rect.width;
            rectCopy.rectID = rect.rectID;
            List<int> collisionListNr = collision.GetCollisions(rectList, rectCopy);

            if(collisionListNr.Count == 0)
            {
                // 3. add to valid positions
                global.positionsValid.Add(position);
                if(!evolution && global.Verschnittoptimierung.radioButton_FirstFitFilling.Checked ||
                    global.selectedGreedy <= 8
                    )
                {
                    return;
                }
            }
            else
            {
                // for all collisions
                for (int i = 0; i < collisionListNr.Count; i++)
                {
                    // move up and try again
                    // 1. move up
                    Position positionUp = new Position();
                    positionUp.SetToPosition(position);
                    positionUp.edgeRightDown.y = rectList[collisionListNr[i]].edgeLeftUp.y;
                    float height = position.edgeLeftUp.y - position.edgeRightDown.y;
                    positionUp.edgeLeftUp.y = positionUp.edgeRightDown.y + height;
                    // 2. try again
                    this.ManagePosition(rectList, rect, positionUp, evolution);

                    // move right and try again
                    // 1. move right
                    Position positionRight = new Position();
                    positionRight.SetToPosition(position);
                    positionRight.edgeLeftUp.x = rectList[collisionListNr[i]].edgeRightDown.x;
                    float width = position.edgeRightDown.x - position.edgeLeftUp.x;
                    positionRight.edgeRightDown.x = positionRight.edgeLeftUp.x + width;
                    // 2. try again
                    this.ManagePosition(rectList, rect, positionRight, evolution);
                }
            }
        }
예제 #7
0
        public Solution CloneSolution(Solution solution)
        {
            Solution solutionClone = new Solution();
            solutionClone.SolutionID = solution.SolutionID;
            solutionClone.usedBenchmarkID = solution.usedBenchmarkID;
            solutionClone.numberOfBoards = solution.numberOfBoards;
            solutionClone.numberOfRects = solution.numberOfRects;
            solutionClone.creationTime = solution.creationTime;
            solutionClone.percentageFilledArea = solution.percentageFilledArea;
            solutionClone.numberRectsPlaced = solution.numberRectsPlaced;
            solutionClone.numberRectsLeft = solution.numberRectsLeft;
            solutionClone.benchmark = solution.benchmark;

            solutionClone.BoardList = new List<Board>();

            for (int i = 0; i < solution.BoardList.Count; i++)
            {
                Board board = new Board();
                board.boardID = solution.BoardList[i].boardID;
                board.height = solution.BoardList[i].height;
                board.width = solution.BoardList[i].width;
                board.size = solution.BoardList[i].size;
                board.isCollectionBoard = solution.BoardList[i].isCollectionBoard;

                board.edgeLeftUp = new MyPoint();
                board.edgeLeftUp.x = (solution.BoardList[i].edgeLeftUp != null)? solution.BoardList[i].edgeLeftUp.x : 0;
                board.edgeLeftUp.y = (solution.BoardList[i].edgeLeftUp != null)? solution.BoardList[i].edgeLeftUp.y : 0;
                board.edgeRightDown = new MyPoint();
                board.edgeRightDown.x = (solution.BoardList[i].edgeRightDown != null) ? solution.BoardList[i].edgeRightDown.x : 0;
                board.edgeRightDown.y = (solution.BoardList[i].edgeRightDown != null) ? solution.BoardList[i].edgeRightDown.y : 0;

                for (int j = 0; j < solution.BoardList[i].RectList.Count; j++)
                {
                    Rect rect = new Rect();
                    rect.rectID = solution.BoardList[i].RectList[j].rectID;
                    rect.width = solution.BoardList[i].RectList[j].width;
                    rect.height = solution.BoardList[i].RectList[j].height;
                    rect.size = solution.BoardList[i].RectList[j].size;

                    rect.edgeLeftUp = new MyPoint();
                    rect.edgeLeftUp.x = (solution.BoardList[i].RectList[j].edgeLeftUp != null)? solution.BoardList[i].RectList[j].edgeLeftUp.x : 0;
                    rect.edgeLeftUp.y = (solution.BoardList[i].RectList[j].edgeLeftUp != null)? solution.BoardList[i].RectList[j].edgeLeftUp.y : 0;
                    rect.edgeRightDown = new MyPoint();
                    rect.edgeRightDown.x = (solution.BoardList[i].RectList[j].edgeRightDown != null)? solution.BoardList[i].RectList[j].edgeRightDown.x : 0;
                    rect.edgeRightDown.y = (solution.BoardList[i].RectList[j].edgeRightDown != null)? solution.BoardList[i].RectList[j].edgeRightDown.y : 0;

                    board.RectList.Add(rect);
                }
                solutionClone.BoardList.Add(board);
            }

            return solutionClone;
        }