微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

vlsi放置中的单元格重叠去除

如何解决vlsi放置中的单元格重叠去除

下面的代码去除位于网格内的单元格之间的重叠。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define TRUE 1
#define FALSE 0
//coordinate representation
struct Point
{
    double x;
    double y;
};
//block representation with 4 coordinates
struct Block
{
    unsigned int id;
    struct Point bottomLeft,topLeft,bottomright,topRight;
    double width,height;
    double whitespace;
};
struct Overlap
{
    double overlapLength;
    struct Block *b1,*b2;
} OL[1000];
struct Block *b;
struct Block ROW1,ROW2,ROW3;

int comparator(const void *p,const void *q)
{
    return (((struct Overlap *)p)->overlapLength -
            (((struct Overlap *)q)->overlapLength));
}

//intialise Blocks using bottom left x,y coordinate
void intialiseBlock(struct Block *B)
{
    B->topLeft.x = B->bottomLeft.x;
    B->topLeft.y = B->height + B->bottomLeft.y;
    B->bottomright.x = B->width + B->bottomLeft.x;
    B->bottomright.y = B->bottomLeft.y;
    B->topRight.x = B->width + B->bottomLeft.x;
    B->topRight.y = B->height + B->bottomLeft.y;
}

//update coordinate
void move(double xDelta,double yDelta,struct Point *p)
{
    // Parameter values are increments to the current coordinates
    p->x += xDelta;
    p->y += yDelta;
}

//calculate and return distance between 2 points
double distance(const struct Point aPoint,const struct Point bPoint)
{
    return sqrt((aPoint.x - bPoint.x) * (aPoint.x - bPoint.x) +
                (aPoint.y - bPoint.y) * (aPoint.y - bPoint.y));
}

//generate width of cell using number of cells
double computeCellWidth(int ncell)
{
    double width = (0.8 * 400) / ncell;
    return width;
}

//create a
unsigned int rand_interval(unsigned int min,unsigned int max)
{
    int r;
    const unsigned int range = 1 + max - min;
    const unsigned int buckets = RAND_MAX / range;
    const unsigned int limit = buckets * range;

    /* Create equal size buckets all in a row,then fire randomly towards
   * the buckets until you land in one of them. All buckets are equally
   * likely. If you land off the end of the line of buckets,try again. */
    do
    {
        r = rand();
    } while (r >= limit);

    return min + (r / buckets);
}

//place blocks in appropriate rows
void placeVertical(struct Block *b,int n,struct Block ROW1,struct Block ROW2,struct Block ROW3)
{
    for (int i = 0; i < n; i++)
    {
        double distanceFromBottom = 0.0;
        double distanceFromTop = 0.0;
        // check if Inside Row1 and Row2
        if ((b[i].bottomLeft.y < ROW1.topLeft.y) && (b[i].topLeft.y > ROW1.topLeft.y))
        {
            //printf("ROW1 and ROW2 Executed\n");
            distanceFromBottom = ROW1.topLeft.y - b[i].bottomLeft.y;
            distanceFromTop = b[i].height - distanceFromBottom;

            if (distanceFromBottom > distanceFromTop)
            {
                move(0,-distanceFromTop,&b[i].bottomLeft);
                move(0,&b[i].topLeft);
                move(0,&b[i].bottomright);
                move(0,&b[i].topRight);
            }
            else
            {
                move(0,distanceFromBottom,&b[i].topRight);
            }
        }
        // check if Inside Row2 and Row3
        else if ((b[i].bottomLeft.y < ROW2.topLeft.y) && (b[i].topLeft.y > ROW2.topLeft.y))
        {
            //System.out.println("ROW2 and ROW3 Executed");
            distanceFromBottom = ROW2.topLeft.y - b[i].bottomLeft.y;
            distanceFromTop = b[i].height - distanceFromBottom;
            if (distanceFromBottom > distanceFromTop)
            {
                move(0,&b[i].topRight);
            }
        }
        else if ((b[i].bottomLeft.y >= ROW1.bottomLeft.y) && (b[i].topLeft.y <= ROW1.topLeft.y))
        {
            // do nothing in ROW1
        }
        else if ((b[i].bottomLeft.y >= ROW2.bottomLeft.y) && (b[i].topLeft.y <= ROW2.topLeft.y))
        {
            // do nothing in ROW2
        }
        else // ((b[i].bottomLeft.y >=
        // ROW2.bottomLeft.y)&&(b[i].topLeft.y <=
        // ROW2.topLeft.y))
        {
            // do nothing in ROW3
        }
    }
}

//use when floating point operations create run time problems
void linkfloat()
{
    float a = 0.0,*x;
    x = &a;
    a = *x;
}

    
int findOverlaps(struct Block *b,int n)
{
    int k,j,p = 0;
    //struct Overlap OL[200];
    //short flag = FALSE;
    double overlapLength = 0.0;
    for (int i = 0; i < n - 1; i++)
    {
        k = i;
        for (j = i + 1; j < n; j++)
        {
            if (k == j)
                continue;
            overlapLength = 0.0;
            //for ROW1
            if (b[k].bottomLeft.y >= 0 && b[k].topLeft.y <= 100 && b[j].bottomLeft.y >= 0 && b[j].topLeft.y <= 100)
            {
                //if ((b[k].bottomright.x > b[j].bottomLeft.x) && (b[k].bottomright.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
                if ((b[k].bottomLeft.y == b[j].bottomLeft.y) && (b[k].bottomright.x > b[j].bottomLeft.x))
                {
                    overlapLength = b[k].bottomright.x - b[j].bottomLeft.x;
                    OL[p].overlapLength = overlapLength;
                    OL[p].b1 = &b[k];
                    OL[p].b2 = &b[j];
                    p++;
                }
                else if (((b[k].topLeft.y > b[j].bottomLeft.y) && (b[k].topRight.x > b[j].bottomLeft.x)) || ((b[k].bottomLeft.y < b[j].topLeft.y) && (b[k].bottomright.x > b[j].topLeft.x)))
                {
                    //flag = TRUE;
                    overlapLength = b[k].bottomright.x - b[j].bottomLeft.x;
                    OL[p].overlapLength = overlapLength;
                    OL[p].b1 = &b[k];
                    OL[p].b2 = &b[j];
                    p++;
                }
                else
                {
                }
                overlapLength = 0.0;
            }
            //For Row2
            else if (b[k].bottomLeft.y >= 100 && b[k].topLeft.y <= 200 && b[j].bottomLeft.y >= 100 && b[j].topLeft.y <= 200)
            {
                if ((b[k].bottomLeft.y == b[j].bottomLeft.y) && (b[k].bottomright.x > b[j].bottomLeft.x))
                {
                    overlapLength = b[k].bottomright.x - b[j].bottomLeft.x;
                    OL[p].overlapLength = overlapLength;
                    OL[p].b1 = &b[k];
                    OL[p].b2 = &b[j];
                    p++;
                }
                else if (((b[k].topLeft.y > b[j].bottomLeft.y) && (b[k].topRight.x > b[j].bottomLeft.x)) || ((b[k].bottomLeft.y < b[j].topLeft.y) && (b[k].bottomright.x > b[j].topLeft.x)))
                {
                    //flag = TRUE;
                    overlapLength = b[k].bottomright.x - b[j].bottomLeft.x;
                    OL[p].overlapLength = overlapLength;
                    OL[p].b1 = &b[k];
                    OL[p].b2 = &b[j];
                    p++;
                }
                else
                {
                }
                overlapLength = 0.0;
            }
            //For Row3
            else if (b[k].bottomLeft.y >= 200 && b[k].topLeft.y <= 300 && b[j].bottomLeft.y >= 200 && b[j].topLeft.y <= 300)
            {
                if ((b[k].bottomLeft.y == b[j].bottomLeft.y) && (b[k].bottomright.x > b[j].bottomLeft.x))
                {
                    overlapLength = b[k].bottomright.x - b[j].bottomLeft.x;
                    OL[p].overlapLength = overlapLength;
                    OL[p].b1 = &b[k];
                    OL[p].b2 = &b[j];
                    p++;
                }
                else if (((b[k].topLeft.y > b[j].bottomLeft.y) && (b[k].topRight.x > b[j].bottomLeft.x)) || ((b[k].bottomLeft.y < b[j].topLeft.y) && (b[k].bottomright.x > b[j].topLeft.x)))
                {
                    //flag = TRUE;
                    overlapLength = b[k].bottomright.x - b[j].bottomLeft.x;
                    OL[p].overlapLength = overlapLength;
                    OL[p].b1 = &b[k];
                    OL[p].b2 = &b[j];
                    p++;
                }
                else
                {
                }
                overlapLength = 0.0;
            }
            else
            {
                //do nothing
            }
        }
    }
    return p;
}

struct Block *
getBlock(struct Block *b,int id)
{
    int i;
    for (i = 0; i < n; i++)
    {
        if (id == b[i].id)
            return (b + i);
    }
    return NULL;
}

void placeHorizontalGreedy(struct Block *b,int n)
{

    struct Block *t = NULL;
    int p = 0,k = 0;
    p = findOverlaps(b,n);
    qsort(OL,p,sizeof(struct Overlap),comparator);
    while (TRUE)
    {
        t = getBlock(b,12,OL[k].b2->id);
        if (t != NULL)
        {
            //t->bottomLeft.x = t->bottomLeft.x+OL[0].overlapLength;
            if ((t->bottomLeft.x + OL[0].overlapLength + t->width) <= ROW1.bottomright.x)
            {
                move(OL[0].overlapLength,&t->bottomLeft);
                intialiseBlock(t);
            }
        }

        p = findOverlaps(b,n);
        if (p == 0)
            break;
        else
            qsort(OL,comparator);
    }
}

void placeHorizontalNonGreedy(struct Block *b,struct Block ROW3)
{
    int k,p = 0;
    double overlapLength = 0.0;
    for (int i = 0; i < n - 1; i++)
    {
        k = i;
        for (j = i + 1; j < n; j++)
        {
            if (k == j)
                continue;
            overlapLength = 0.0;
            //check if in Row1
            if (b[k].bottomLeft.y >= ROW1.bottomLeft.y && b[k].topLeft.y <= ROW1.topLeft.y && b[j].bottomLeft.y >= ROW1.bottomLeft.y && b[j].topLeft.y <= ROW1.topLeft.y)
            {
                if ((b[k].bottomright.x > b[j].bottomLeft.x) && (b[k].bottomright.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
                {
                    //flag = TRUE;
                    overlapLength = b[k].bottomright.x - b[j].bottomLeft.x;
                    if (overlapLength != 0)
                    {
                        if (b[j].bottomLeft.x + overlapLength + b[j].width <=
                            ROW1.bottomright.x)
                        {
                            b[j].bottomLeft.x += overlapLength;
                            intialiseBlock(&b[j]);
                        }
                        else
                        {
                            b[j].bottomLeft.x =
                                b[j].bottomLeft.x + (ROW1.bottomright.x -
                                                     b[j].bottomright.x);
                        }
                    }
                }
            }
            //check if in Row2
            else if (b[k].bottomLeft.y >= ROW2.bottomLeft.y && b[k].topLeft.y <= ROW2.topLeft.y && b[j].bottomLeft.y >= ROW2.bottomLeft.y && b[j].topLeft.y <= ROW2.topLeft.y)
            {
                if ((b[k].bottomright.x > b[j].bottomLeft.x) && (b[k].bottomright.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
                {
                    //flag = TRUE;
                    overlapLength = b[k].bottomright.x - b[j].bottomLeft.x;
                    if (overlapLength != 0)
                    {
                        if (b[j].bottomLeft.x + overlapLength + b[j].width <=
                            400)
                        {
                            b[j].bottomLeft.x += overlapLength;
                            intialiseBlock(&b[j]);
                        }
                    }
                }
            }
            //check if in Row3
            else if (b[k].bottomLeft.y >= ROW3.bottomLeft.y && b[k].topLeft.y <= ROW3.topLeft.y && b[j].bottomLeft.y >= ROW3.bottomLeft.y && b[j].topLeft.y <= ROW3.topLeft.y)
            {
                if ((b[k].bottomright.x > b[j].bottomLeft.x) && (b[k].bottomright.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
                {
                    //flag = TRUE;
                    overlapLength = b[k].bottomright.x - b[j].bottomLeft.x;
                    if (overlapLength != 0)
                    {
                        if (b[j].bottomLeft.x + overlapLength + b[j].width <=
                            400)
                        {
                            b[j].bottomLeft.x += overlapLength;
                            intialiseBlock(&b[j]);
                        }
                    }
                }
            }
            else
            {
                //printf("Invalid input\n");
                continue;
            }
        }
    }
}

int main()
{
    //struct Block b[16];
    //struct Block b[4];
    //struct Block *b;
    //struct Block ROW1,ROW3;
    //FILE *fp = fopen("/home/jeetu/experimentprograms/recordcoord.txt","w+");
    //FILE *fp = fopen("/home/jeetu/experimentprograms/blockcoordinates.txt","r");
    int ncell = 0,width = 0,i = 0,totalncells = 0,id = 0;
    double distanceFromBottom = 0.0;
    double distanceFromTop = 0.0;
    int x = 0,y = 0,temp = 0,d = 0;
    printf("Enter number of cells: ");
    scanf("%d",&ncell);
    width = computeCellWidth(ncell);
    //width = 40;
    b = (struct Block *)malloc(3 * ncell * sizeof(struct Block));
    //b = (struct Block *)malloc(12 * sizeof(struct Block));
    srand(time(0));

    ROW1.bottomLeft.x = 0;
    ROW1.bottomLeft.y = 0;
    ROW1.height = 100;
    ROW1.width = 400;
    ROW1.whitespace = 40000;
    intialiseBlock(&ROW1);
    ROW2.bottomLeft.x = 0;
    ROW2.bottomLeft.y = 100;
    ROW2.height = 100;
    ROW2.width = 400;
    ROW2.whitespace = 40000;
    intialiseBlock(&ROW2);
    ROW3.bottomLeft.x = 0;
    ROW3.bottomLeft.y = 200;
    ROW3.height = 100;
    ROW3.width = 400;
    ROW3.whitespace = 40000;
    intialiseBlock(&ROW3);

    for (i = 0; i < ncell; i++)
    {
        if (i == 0)
        {
            // x = rand_interval(0,width / 2);
            x = rand() % (width / 2);
            //y = rand_interval(0,70);
            y = rand() % 70;
            temp = x;
        }
        //m = rand();
        else
        {
            x = rand_interval((temp + (int)width / 2),temp + width);
            //x = (rand()%((temp+width)-(temp+width/2)))+(temp+width/2);
            //y = rand_interval(0,70);
            y = rand() % 70;
            temp = x;
        }
        b[totalncells].bottomLeft.x = x;
        b[totalncells].bottomLeft.y = y;
        b[totalncells].width = width;
        b[totalncells].height = 50;
        b[totalncells].id = id;
        //initial white space calculation for ROW1
        if (b[totalncells].bottomLeft.y >= ROW1.bottomLeft.y && b[totalncells].topLeft.y <= ROW1.topLeft.y)
        {
            ROW1.whitespace =
                ROW1.whitespace - b[totalncells].width * b[totalncells].height;
        }
        id++;
        intialiseBlock(&b[totalncells]);
        totalncells++;
        //printf("x=%d\ty=%d\n",x,y);
    }
    temp = 0;
    //Generate random coordinates For Row2
    for (i = 0; i < ncell; i++)
    {
        //int x = 0,m = 0,d = 0;
        if (i == 0)
        {
            /*x = rand_interval(0,width / 2);
         y = rand_interval(100,170); */
            //x = rand() % (width / 2);
            x = rand() % (width / 2);
            y = (rand() % (170 - 100)) + 100;
            temp = x;
        }
        //m = rand();
        else
        {
            /*x = rand_interval((temp + (int)width / 2),400 - (int)width);
         y = rand_interval(100,170); */
            //x = (rand()%((temp+width)-(temp+width/2)))+(temp+width/2);
            x = rand_interval((temp + (int)width / 2),temp + width);
            y = (rand() % (170 - 100)) + 100;
            temp = x;
        }

        b[totalncells].bottomLeft.x = x;
        b[totalncells].bottomLeft.y = y;
        b[totalncells].width = width;
        b[totalncells].height = 50;
        b[totalncells].id = id;
        //initial white space calculation for ROW2
        if (b[totalncells].bottomLeft.y >= ROW2.bottomLeft.y && b[totalncells].topLeft.y <= ROW2.topLeft.y)
        {
            ROW2.whitespace =
                ROW2.whitespace - b[totalncells].width * b[totalncells].height;
        }
        id++;
        intialiseBlock(&b[totalncells]);
        totalncells++;
        //printf("x=%d\ty=%d\n",y);
    }
    temp = 0;
    //Generate random coordinates For Row3
    for (i = 0; i < ncell; i++)
    {
        //int x = rand_interval(0,100 - (int)width);
        //int y = rand_interval(20,25); //cell height is 5 so max will reach 30
        //int x = 0,width / 2);
         y = rand_interval(200,250); */

            x = rand() % (width / 2);
            y = (rand() % (250 - 200)) + 200;
            temp = x;
        }
        //m = rand();
        else
        {
            /*x = rand_interval((temp + (int)width / 2),400 - (int)width);
         y = rand_interval(200,250); */
            x = rand_interval((temp + (int)width / 2),temp + width);
            //x = (rand()%((temp+width)-(temp+width/2)))+(temp+width/2);
            y = (rand() % (250 - 200)) + 200;
            temp = x;
        }
        b[totalncells].bottomLeft.x = x;
        b[totalncells].bottomLeft.y = y;
        b[totalncells].width = width;
        b[totalncells].height = 50;
        b[totalncells].id = id;
        //initial white space calculation for ROW3
        if (b[totalncells].bottomLeft.y >= ROW3.bottomLeft.y && b[totalncells].topLeft.y <= ROW3.topLeft.y)
        {
            ROW3.whitespace =
                ROW3.whitespace - b[totalncells].width * b[totalncells].height;
        }
        id++;
        intialiseBlock(&b[totalncells]);
        totalncells++;
        //printf("x=%d\ty=%d\n",y);
    }
    for (i = 0; i < totalncells; i++)
    {
        //printf("%f %f %f %f\n",b[i].bottomLeft.x,b[i].bottomLeft.y,b[i].width,b[i].height);
        printf("%d\t%d\t%d\t%d\n",(int)b[i].bottomLeft.x,(int)b[i].bottomLeft.y,(int)b[i].width,(int)b[i].height);
    }
    placeVertical(b,totalncells,ROW1,ROW3);
    //placeVerticalWithDensityConstraints(b,ROW3);
    printf("\nAfter vertical Updation\n");
    for (i = 0; i < totalncells; i++)
    {
        printf("%d\t%d\t%d\t%d\n",(int)b[i].height);
    }
    /*placeHorizontalNonGreedy(b,ROW3);
     printf("\nAfter Horizontal Updation(Non greedy)\n");
     for (i = 0; i < 12; i++)
     {
     printf("%d\t%d\t%d\t%d\n",(int)b[i].height);
     } */
    placeHorizontalGreedy(b,totalncells);
    printf("\nAfter Horizontal Updation(Greedy)\n");
    for (i = 0; i < totalncells; i++)
    {
        printf("%d\t%d\t%d\t%d\n",(int)b[i].height);
    }
    return 0;
}

代码说明 在这个程序中,我定义了三个结构 一个代表一个点,一个代表具有4个坐标的矩形块,一个代表一对单元格之间的重叠。 有函数(computeCellWidth)根据公式动态计算单元格的宽度。 单元格将驻留在三行 ROW1、ROW2、ROW3 中。 该程序将首先询问单元格数,这是每行的单元格数。首先随机生成每个单元格的 x,y 坐标。然后 placeVertical() 函数将单元格移动到跨越两行的不同行。然后有一个 placeHorizo​​ntalGreedy() 函数,它将通过首先找到重叠长度然后对它们进行排序并删除重叠最少的单元格之间的重叠来消除单元格之间的重叠,这个过程将继续直到没有重叠或重叠消除不再可能.在这里,我想提醒大家注意,单元格将移向网格右侧以消除重叠。在 placeHorizo​​ntalGreedy() 函数中,我使用了一个变量 p,它将指示每次迭代后的重叠数.对于测试 p 为零的少量单元格工作正常,但不是因为我增加了数字。另外,我如何确保存在重叠但无法去除重叠矿石,这样我就可以停止循环。请帮帮我。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。