示例#1
0
bool LegacyMarkedRule::next()
{
	if (markers) {
		while (markers->next()) {
			vkey = markers->getKey();
			computeCell();
			if (!value.isEmpty()) { // if value not null
				return true;
			}
		}
	}
	return false;
}
示例#2
0
bool LegacyRule::next()
{
	for (;;) {
		if (isValidPath) {
			++path;
		} else {
			path = area->pathBegin();
			isValidPath = true;
		}
		if (path == area->pathEnd()) {
			sourceStreamsSP.clear();
			sourceStreams.clear();
			sourceStreamsNext.clear();
			sourceCubeAreas.clear();
			return false;
		}
		vkey = *path;
		computeCell();
		if (generateEmptyResults || !value.isEmpty()) { // if value not null
//			cout << "R\t" << vkey << "\t" << value.getNumeric() << endl;
			return true;
		}
	}
}
示例#3
0
int main(int argc, char **argv) {

    int i, j, z;
    int x, y, size;
    int w_breeding, s_breeding, w_starvation, gen_num;
    char type_code;
    char *file_name;
    FILE * input_file;
    double secs;
    int averow, extra, rank, n_processes, offset, rows;
    int mtype, dest, rowsAux, source;
    int aditional, start_line;

    struct world **proc_world;

    MPI_Init (&argc, &argv);
    MPI_Comm_rank (MPI_COMM_WORLD, &rank); //Rank, an integer, is used in MPI to be a process identifier associated with a communicator
    MPI_Comm_size (MPI_COMM_WORLD, &n_processes); //where size is the total number of processes in the MPI_Comm_world.

    /* Processo Master */
    if (rank == MASTER) {
        secs =  MPI_Wtime();

        if(argc <= 5) {
            printf("ERROR: Expected 5 arguments provided %d.\n", argc);
            printf("Expected:\n./wolves-squirrels-serial <InputFile> <WolfBreedingPeriod> <SquirrelBreedingPeriod> <WolfStarvationPerior> <Generations>\n");
            return -1;
        }

        w_breeding = atoi(argv[2]);
        s_breeding = atoi(argv[3]);
        w_starvation = atoi(argv[4]);
        gen_num = atoi(argv[5]);
        input_file = fopen(argv[1], "r");
        if(input_file == NULL) {
            printf("ERROR: A valid input file is expected. %s is not a valid file.\n", argv[1]);
            return -1;
        }

        /* Talvez dê para melhorar */
        fscanf(input_file, "%d", &size);

        initWorld(size);


        while(fscanf(input_file, "%d %d %c", &x, &y, &type_code) != EOF) {
            world_global[x][y].type = type_code;
            if(world_global[x][y].type == wolf) {
                world_global[x][y].breeding_period = w_breeding;
                world_global[x][y].starvation_period = w_starvation;
            } else if(world_global[x][y].type == squirrel) {
                world_global[x][y].breeding_period = s_breeding;
            }
        }

        fclose(input_file);


        /* Envia parcela a cada processo */
        averow = size / n_processes;
        extra = size % n_processes;
        offset = 0;
        mtype = FROM_MASTER;


        for(dest=1; dest<n_processes; dest++) {

            rowsAux = dest <= extra ? averow+1 : averow;
            MPI_Send(&offset, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
            MPI_Send(&rowsAux, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
            MPI_Send(&size, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);

            for(i=0; i < rowsAux; i++)
                MPI_Send(world_global[offset+i], sizeof(struct world)*size, MPI_BYTE, dest, mtype, MPI_COMM_WORLD);

            offset = offset + rowsAux;
        }

        proc_world = (struct world**) malloc(sizeof(struct world*)*(averow+1));
        for(i = 0; i < averow+1; i++) {
            proc_world[i] = (struct world*) malloc(sizeof(struct world)*size);
            for(j = 0; j < size; j ++) {
                proc_world[i][j].type = empty;
                proc_world[i][j].count = 0;
                proc_world[i][j].breeding_period = 0;
                proc_world[i][j].starvation_period = 0;
                proc_world[i][j].breed = 0;
                for(z=0; z < 5; z++)
                    world_global[i][j].conflicts[z]=NULL;
            }
        }


        for(i=1; i< averow+1; i++)
            proc_world[i] = world_global[offset+i];

#ifdef MPIVERBOSE
        printf("Distribuição: %lf\n", MPI_Wtime() - secs);
        secs = MPI_Wtime();
#endif
        aditional = 1;
    } else if(rank > 0) {

        mtype = FROM_MASTER;
        source = MASTER;
        MPI_Recv(&offset, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
        MPI_Recv(&rowsAux, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
        MPI_Recv(&size, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);

        proc_world = (struct world**) malloc(sizeof(struct world*)*(rowsAux+aditional));


        if(rank == 1) {
            aditional = 1;
            start_line = 0;
        } else {
            aditional = 2;
            start_line = 1;
        }

        for(i = 0; i < rowsAux+aditional; i++) {
            proc_world[i] = (struct world*) malloc(sizeof(struct world)*size);
            for(j = 0; j < size; j ++) {
                proc_world[i][j].type = empty;
                proc_world[i][j].count = 0;
                proc_world[i][j].breeding_period = 0;
                proc_world[i][j].starvation_period = 0;
                proc_world[i][j].breed = 0;
                for(z=0; z < 5; z++)
                    world_global[i][j].conflicts[z]=NULL;
            }
        }

        for(i = start_line; i < rowsAux+start_line; i++) {
            MPI_Recv(proc_world[i], sizeof(struct world)*size, MPI_BYTE, source, mtype, MPI_COMM_WORLD, &status);
        }
    }


#ifdef VERBOSE
//	start = clock();
#endif

    /* Comum a todos os processos */
    MPI_Bcast(&w_breeding, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&s_breeding, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&w_starvation, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&gen_num, 1, MPI_INT, 0, MPI_COMM_WORLD);




#ifdef MPIVERBOSE
//	printf("Leitura: %lf\n", MPI_Wtime() - secs);
//	secs =  MPI_Wtime();
#endif

    /* Generate */
    MPI_Status	*statuses[2];
    MPI_Request *request[2];
    struct world *worldaux1, *worldaux2;

    //worldaux1 = (struct world*) malloc(sizeof(struct world)*size);
    //worldaux2 = (struct world*) malloc(sizeof(struct world)*size);

    while(gen_num != 0) {

        if(rank == 1) {
            for(i = 0; i < size ; i++) {
                proc_world[rowsAux][i].type = empty;
                proc_world[rowsAux][i].count = 0;
                proc_world[rowsAux][i].breeding_period = 0;
                proc_world[rowsAux][i].starvation_period = 0;
                proc_world[rowsAux][i].breed = 0;
                for(z=0; z < 5; z++)
                    world_global[i][j].conflicts[z]=NULL;
            }
        } else if(rank == MASTER) {
            for(i = 0; i < size ; i++) {
                proc_world[0][i].type = empty;
                proc_world[0][i].count = 0;
                proc_world[0][i].breeding_period = 0;
                proc_world[0][i].starvation_period = 0;
                proc_world[0][i].breed = 0;
                for(z=0; z < 5; z++)
                    world_global[i][j].conflicts[z]=NULL;
            }
        } else {
            for(i = 0; i < size ; i++) {
                proc_world[0][i].type = empty;
                proc_world[0][i].count = 0;
                proc_world[0][i].breeding_period = 0;
                proc_world[0][i].starvation_period = 0;
                proc_world[0][i].breed = 0;
                for(z=0; z < 5; z++)
                    world_global[i][j].conflicts[z]=NULL;
                proc_world[rowsAux][i].type = empty;
                proc_world[rowsAux][i].count = 0;
                proc_world[rowsAux][i].breeding_period = 0;
                proc_world[rowsAux][i].starvation_period = 0;
                proc_world[rowsAux][i].breed = 0;
                for(z=0; z < 5; z++)
                    world_global[i][j].conflicts[z]=NULL;
            }
        }

        for(i = (rank==1? 0 : 1); i< (rank==1 ? rowsAux : rowsAux+1) ; i++) {
            for(j=0; j<size; j++) {
                computeCell(i, j, s_breeding, w_breeding, w_starvation, size, rowsAux+aditional, proc_world, rank);
            }
        }


        /*Enviar a  linha de coisas estranhas para o(s) processo(s) da fronteira */
        if(rank == 1) {
            MPI_Irecv(worldaux1, sizeof(struct world)*size, MPI_BYTE, rank+1, 2, MPI_COMM_WORLD, request[0]);
            MPI_Send(proc_world[rowsAux], sizeof(struct world)*size, MPI_BYTE, (rank+1)%n_processes, rank, MPI_COMM_WORLD);
            MPI_Wait(request[0], statuses[0]);

            /* Juntar aos conflictos*/
            for(i=0; i<size; i++) {
                proc_world[rowsAux][i].conflicts[proc_world[rowsAux][i].count] = (conflict*)malloc(sizeof(struct conflicts));
                proc_world[rowsAux][i].conflicts[proc_world[rowsAux][i].count]->type = worldaux1[i].type;
                proc_world[rowsAux][i].conflicts[proc_world[rowsAux][i].count]->breeding_period = worldaux1[i].breeding_period;
                proc_world[rowsAux][i].conflicts[proc_world[rowsAux][i].count]->starvation_period = worldaux1[i].starvation_period;
                proc_world[rowsAux][i].count += 1;
            }
        } else if(rank == MASTER) {
            MPI_Irecv(worldaux1, sizeof(struct world)*size, MPI_BYTE, n_processes-1, n_processes-1, MPI_COMM_WORLD, request[0]);
            MPI_Send(proc_world[averow], sizeof(struct world)*size, MPI_BYTE, n_processes-1, rank, MPI_COMM_WORLD);
            MPI_Wait(request[0], statuses[0]);

            for(i=0; i<size; i++) {
                proc_world[0][i].conflicts[proc_world[0][i].count] = (conflict*)malloc(sizeof(struct conflicts));
                proc_world[0][i].conflicts[proc_world[0][i].count]->type = worldaux1[i].type;
                proc_world[0][i].conflicts[proc_world[0][i].count]->breeding_period = worldaux1[i].breeding_period;
                proc_world[0][i].conflicts[proc_world[0][i].count]->starvation_period = worldaux1[i].starvation_period;
                proc_world[0][i].count += 1;
            }
        } else {
            MPI_Irecv(worldaux1, sizeof(struct world)*size, MPI_BYTE, rank+1%n_processes, rank+1%n_processes, MPI_COMM_WORLD, request[0]);
            MPI_Irecv(worldaux2, sizeof(struct world)*size, MPI_BYTE, rank-1%n_processes, rank-1%n_processes, MPI_COMM_WORLD, request[1]);
            MPI_Send(proc_world[rowsAux], sizeof(struct world)*size, MPI_BYTE, (rank+1)%n_processes, rank, MPI_COMM_WORLD);
            MPI_Send(proc_world[rowsAux], sizeof(struct world)*size, MPI_BYTE, (rank-1)%n_processes, rank, MPI_COMM_WORLD);
            MPI_Wait(request[0], statuses[0]);
            MPI_Wait(request[1], statuses[1]);

            for(i=0; i<size; i++) {
                proc_world[0][i].conflicts[proc_world[0][i].count] = (conflict*)malloc(sizeof(struct conflicts));
                proc_world[0][i].conflicts[proc_world[0][i].count]->type = worldaux1[i].type;
                proc_world[0][i].conflicts[proc_world[0][i].count]->breeding_period = worldaux1[i].breeding_period;
                proc_world[0][i].conflicts[proc_world[0][i].count]->starvation_period = worldaux1[i].starvation_period;
                proc_world[0][i].count += 1;
            }

            for(i=0; i<size; i++) {
                proc_world[rowsAux][i].conflicts[proc_world[rowsAux][i].count] = (conflict*)malloc(sizeof(struct conflicts));
                proc_world[rowsAux][i].conflicts[proc_world[rowsAux][i].count]->type = worldaux1[i].type;
                proc_world[rowsAux][i].conflicts[proc_world[rowsAux][i].count]->breeding_period = worldaux1[i].breeding_period;
                proc_world[rowsAux][i].conflicts[proc_world[rowsAux][i].count]->starvation_period = worldaux1[i].starvation_period;
                proc_world[rowsAux][i].count += 1;
            }
        }

        /* fix do pequeno mundo do processo */
        fixWorld(size, w_starvation, w_breeding, rowsAux, proc_world, rank);

        gen_num--;
    }


    /* Receber tudo no master */

#ifdef VERBOSE
    end = clock();
    printf("Elapsed Time : %lf\n", (double)(end-start) / CLOCKS_PER_SEC);
#endif

    MPI_Finalize();

    /* Output */
    //printWorldFormatted(size);

    return 0;
}
示例#4
0
//=================================================================================
void computeCell(float *xcoord, float *ycoord, float *zcoord,
                 int *coordInBox, int numCoordInBox,
                 float bbx1, float bby1, float bbz1,
                 float bbx2, float bby2, float bbz2,
                 int maxCoord, int *replBy, int &numCoordToRemove)
{
    int i, j;
    int v, w;
    float rx, ry, rz;
    float obx1, oby1, obz1;
    float obx2, oby2, obz2;
    int numCoordInCell[8];
    int *coordInCell[8];

    // too many Coords in my box -> split octree box deeper
    if (numCoordInBox > maxCoord)
    {
        // yes we have
        rx = (bbx1 + bbx2) / 2.0f;
        ry = (bby1 + bby2) / 2.0f;
        rz = (bbz1 + bbz2) / 2.0f;

        // go through the coordinates and sort them in the right cell

        for (i = 0; i < 8; i++)
        {
            coordInCell[i] = new int[numCoordInBox];
            numCoordInCell[i] = 0;
        }

        for (i = 0; i < numCoordInBox; i++)
        {
            v = coordInBox[i];
            w = getOctant(xcoord[v], ycoord[v], zcoord[v], rx, ry, rz);
            coordInCell[w][numCoordInCell[w]] = v;
            numCoordInCell[w]++;
        }

        // we're recursive - hype
        for (i = 0; i < 8; i++)
        {
            if (numCoordInCell[i])
            {
                if (numCoordInCell[i] > numCoordInBox / 4)
                {
                    // we decide to compute the new BoundingBox instead of
                    // just splitting the parent-Box
                    boundingBox(&xcoord, &ycoord, &zcoord, coordInCell[i],
                                numCoordInCell[i], &obx1, &oby1, &obz1,
                                &obx2, &oby2, &obz2);
                }
                else
                    getOctantBounds(i, rx, ry, rz, bbx1, bby1, bbz1,
                                    bbx2, bby2, bbz2,
                                    &obx1, &oby1, &obz1, &obx2, &oby2, &obz2);

                computeCell(xcoord, ycoord, zcoord, coordInCell[i],
                            numCoordInCell[i], obx1, oby1, obz1,
                            obx2, oby2, obz2, maxCoord, replBy, numCoordToRemove);
            }
            delete[] coordInCell[i];
        }
    }

    //// directly compare in box
    else if (numCoordInBox > 1)
    {
        // check these vertices
        for (i = 0; i < numCoordInBox - 1; i++)
        {
            v = coordInBox[i];
            rx = xcoord[v];
            ry = ycoord[v];
            rz = zcoord[v];
            // see if this one is doubled
            for (j = i + 1; j < numCoordInBox; j++)
            {
                w = coordInBox[j];

                if (xcoord[w] == rx && // @@@@ add distance fkt here if necessary
                    ycoord[w] == ry && zcoord[w] == rz)
                {
                    // this one is double
                    if (v < w)
                        replBy[w] = v;
                    else
                        replBy[v] = w;
                    numCoordToRemove++;
                    // break out
                    j = numCoordInBox;
                }
            }
        }
    }

    // done
    return;
}
示例#5
0
//=================================================================================
void computeCell(float *xcoord, float *ycoord, float *zcoord,
                 int *coordInBox, int numCoordInBox,
                 float bbx1, float bby1, float bbz1,
                 float bbx2, float bby2, float bbz2,
                 int optimize, float maxDistanceSqr, int maxCoord)
{
    int i, j;
    int v, w;
    float rx, ry, rz;
    float obx1, oby1, obz1;
    float obx2, oby2, obz2;
    int numCoordInCell[8];
    int *coordInCell[8];

    // check if we have to go any further
    if (numCoordInBox > maxCoord)
    {
        // yes we have
        rx = (bbx1 + bbx2) / 2.0f;
        ry = (bby1 + bby2) / 2.0f;
        rz = (bbz1 + bbz2) / 2.0f;

        if (optimize)
        {
            // we have to mess with memory
            for (i = 0; i < 8; i++)
                numCoordInCell[i] = 0;
            for (i = 0; i < numCoordInBox; i++)
            {
                v = coordInBox[i];
                numCoordInCell[getOctant(xcoord[v], ycoord[v], zcoord[v], rx, ry, rz)]++;
            }
            for (i = 0; i < 8; i++)
            {
                if (numCoordInCell[i])
                    coordInCell[i] = new int[numCoordInCell[i]];
                else
                    coordInCell[i] = NULL;
            }
        }
        else
            for (i = 0; i < 8; i++)
                coordInCell[i] = new int[numCoordInBox];

        // go through the coordinates and sort them in the right cell
        for (i = 0; i < 8; i++)
            numCoordInCell[i] = 0;
        for (i = 0; i < numCoordInBox; i++)
        {
            v = coordInBox[i];
            w = getOctant(xcoord[v], ycoord[v], zcoord[v], rx, ry, rz);
            if (coordInCell[w] != NULL)
            {
                coordInCell[w][numCoordInCell[w]] = v;
                numCoordInCell[w]++;
            }
        }

        // we're recursive - hype
        for (i = 0; i < 8; i++)
        {
            if (numCoordInCell[i])
            {
                if (numCoordInCell[i] > numCoordInBox / 4)
                {
                    // we decide to compute the new BoundingBox instead of
                    // just splitting the parent-Box
                    boundingBox(&xcoord, &ycoord, &zcoord, coordInCell[i],
                                numCoordInCell[i], &obx1, &oby1, &obz1,
                                &obx2, &oby2, &obz2);
                }
                else
                    getOctantBounds(i, rx, ry, rz, bbx1, bby1, bbz1,
                                    bbx2, bby2, bbz2,
                                    &obx1, &oby1, &obz1, &obx2, &oby2, &obz2);
                computeCell(xcoord, ycoord, zcoord, coordInCell[i],
                            numCoordInCell[i], obx1, oby1, obz1,
                            obx2, oby2, obz2, optimize, maxDistanceSqr, maxCoord);
            }
            delete[] coordInCell[i];
        }
    }
    else if (numCoordInBox > 1)
    {
        // check these vertices
        for (i = 0; i < numCoordInBox - 1; i++)
        {
            v = coordInBox[i];
            rx = xcoord[v];
            ry = ycoord[v];
            rz = zcoord[v];
            // see if this one is doubled
            for (j = i + 1; j < numCoordInBox; j++)
            {
                w = coordInBox[j];
                if (isEqual(xcoord[w], ycoord[w], zcoord[w], rx, ry, rz, maxDistanceSqr))
                {
                    // this one is double
                    if (v < w)
                    {
                        replBy[w] = v;
                        //coordToRemove[0][numCoordToRemove] = w;  // was w
                        //coordToRemove[1][numCoordToRemove] = v;  // was v
                    }
                    else
                    {
                        replBy[v] = w;
                        //coordToRemove[0][numCoordToRemove] = w;  // was w
                        //coordToRemove[1][numCoordToRemove] = v;  // was v
                    }
                    numCoordToRemove++;
                    // break out
                    j = numCoordInBox;
                }
            }
        }
    }

    // done
    return;
}
示例#6
0
coDistributedObject *checkUSG(coDistributedObject *DistrObj, const coObjInfo &outInfo)
{
    coDistributedObject *NewDistrObj = NULL;
    // temp
    int *elemList; //tl

    float bbx1, bby1, bbz1;
    float bbx2, bby2, bbz2;

    int *coordInBox;
    int numCoordInBox;

    // counters
    int num_elem, i;

    int num_coord;
    int num_conn;

    float *xcoord, *ycoord, *zcoord;
    int *connList; // vl

    int maxCoord;

    // check for errors
    if (DistrObj == NULL)
    {
        //Covise::sendError("No distributed object at checkUSG();");
        return 0;
    }

    // get parameters
    maxCoord = 50;

    // get input
    if (coDoPolygons *poly_in = dynamic_cast<coDoPolygons *>(DistrObj))
    {
        num_coord = poly_in->getNumPoints();
        num_conn = poly_in->getNumVertices();
        poly_in->getAddresses(&xcoord, &ycoord, &zcoord, &connList, &elemList);
    }
    else if (coDoLines *lines_in = dynamic_cast<coDoLines *>(DistrObj))
    {
        num_coord = lines_in->getNumPoints();
        num_conn = lines_in->getNumVertices();
        lines_in->getAddresses(&xcoord, &ycoord, &zcoord, &connList, &elemList);
    }
    else if (coDoUnstructuredGrid *grid_in = dynamic_cast<coDoUnstructuredGrid *>(DistrObj))
    {
        //   cells  connec     vertices
        grid_in->getGridSize(&num_elem, &num_conn, &num_coord);
        grid_in->getAddresses(&elemList, &connList, &xcoord, &ycoord, &zcoord);
    }
    else
    {
        fprintf(stderr, "FixUSG: wrong object-type\n");
        return (0);
    }

    /// create a Replace-List
    replBy = new int[num_coord];
    for (i = 0; i < num_coord; i++)
        replBy[i] = -2;

    numCoordToRemove = 0;
    coordInBox = new int[num_coord];
    if (!coordInBox)
    {
        fprintf(stderr, "FixUSG: failed to alloc array of %d ints (2)\n", num_coord);
        return (0);
    }
    numCoordInBox = 0;

    // the "starting" cell contains all USED coordinates
    // clear all flags -> no coordinates used at all
    for (i = 0; i < num_coord; i++)
        coordInBox[i] = 0;

    for (i = 0; i < num_conn; i++)
        coordInBox[connList[i]] = 1;

    // now remove the unused coordinates
    for (i = 0; i < num_coord; i++)
    {
        if (coordInBox[i])
        {
            // this one is used
            coordInBox[numCoordInBox] = i;
            numCoordInBox++;
        }
        else
        {
            // unused coordinate
            replBy[i] = -1;
            numCoordToRemove++;
        }
    }
    // what we do next depends on the chosen algorithm

    boundingBox(&xcoord, &ycoord, &zcoord, coordInBox, numCoordInBox,
                &bbx1, &bby1, &bbz1, &bbx2, &bby2, &bbz2);
    computeCell(xcoord, ycoord, zcoord,
                coordInBox, numCoordInBox, bbx1, bby1, bbz1,
                bbx2, bby2, bbz2, maxCoord, replBy, numCoordToRemove);

    // partially clean up
    delete[] coordInBox;

    // compute the working-lists
    computeWorkingLists(num_coord);

    // and finally remove the filtered coordinates
    NewDistrObj = filterCoordinates(DistrObj, outInfo, num_coord, xcoord, ycoord, zcoord);

    // clean up
    delete[] source2filtered;
    delete[] filtered2source;

    // status report
    //char buffer[64];
    //sprintf(buffer,"removed %d points",numCoordToRemove);
    //Covise::sendInfo(buffer);

    // done

    return NewDistrObj;
}
int main(int argc, char **argv){

	int i, j;	
	int x, y, size;
	int w_breeding, s_breeding, w_starvation, gen_num;
	char type_code;
	FILE * input_file;
	
	if(argc <= 5){
		printf("ERROR: Expected 5 arguments provided %d.\n", argc);
		printf("Expected:\n./wolves-squirrels-serial <InputFile> <WolfBreedingPeriod> <SquirrelBreedingPeriod> <WolfStarvationPerior> <Generations>\n");	
		return -1;
    }
	omp_set_num_threads(4);
	w_breeding = atoi(argv[2]);
	s_breeding = atoi(argv[3]);
	w_starvation = atoi(argv[4]);
	gen_num = atoi(argv[5]);
	
	input_file = fopen(argv[1], "r");
	if(input_file == NULL){
		printf("ERROR: A valid input file is expected. %s is not a valid file.\n", argv[1]);	
		return -1;
	}
		
	fscanf(input_file, "%d", &size);

	initWorld(size);

	while(fscanf(input_file, "%d %d %c", &x, &y, &type_code) != EOF){
		world[x][y].type = type_code;
		if(world[x][y].type == wolf){
			world[x][y].breeding_period = w_breeding;
			world[x][y].starvation_period = w_starvation;
		} else if(world[x][y].type == squirrel){
			world[x][y].breeding_period = s_breeding;
		}
	}
	
	fclose(input_file);

#ifdef VERBOSE
	start = omp_get_wtime();
#endif	

	/* Generate */
	while(gen_num != 0){
#pragma omp parallel sections
{
	#pragma omp section
	{
		/* 1st sub-generation - RED */
		#pragma omp parallel for private(i, j) schedule(guided, size/8)
		for(i=0; i<size; i++){
			for(j = i%2 == 0 ? 0 : 1 ; j<size; j+=2){
				computeCell(i, j, s_breeding, w_breeding, w_starvation, size);
			}		
		}
	}
		
	#pragma omp section
	{
		/* 2nd sub-generation */
		#pragma omp parallel for private(i, j) schedule(guided, size/8)
		for(i=0; i<size; i++){
			for(j = i%2 == 0 ? 1 : 0 ; j<size; j+=2){
				computeCell(i, j, s_breeding, w_breeding, w_starvation, size);
			}
		}
	}
}
		fixWorld(size, w_starvation, w_breeding);

		gen_num--;
	}

#ifdef VERBOSE
	end = omp_get_wtime();
	printf("Elapsed time: %lf\n", end-start); 
#endif
	
	/* Output */
	printWorldFormatted(size);
			
	return 0;
}
int main(int argc, char **argv) {

    int i, j;
    int x, y, size;
    int w_breeding, s_breeding, w_starvation, gen_num;
    char type_code;
    FILE * input_file;

    w_number = 0;

    if(argc <= 5) {
        printf("ERROR: Expected 5 arguments provided %d.\n", argc);
        printf("Expected:\n./wolves-squirrels-serial <InputFile> <WolfBreedingPeriod> <SquirrelBreedingPeriod> <WolfStarvationPerior> <Generations>\n");
        return -1;
    }

    w_breeding = atoi(argv[2]);
    s_breeding = atoi(argv[3]);
    w_starvation = atoi(argv[4]);
    gen_num = atoi(argv[5]);

    input_file = fopen(argv[1], "r");
    if(input_file == NULL) {
        printf("ERROR: A valid input file is expected. %s is not a valid file.\n", argv[1]);
        return -1;
    }

    fscanf(input_file, "%d", &size);

    initWorld(size);

    while(fscanf(input_file, "%d %d %c", &x, &y, &type_code) != EOF) {
        world[0][x][y].type = type_code;
        world[1][x][y].type = type_code;
        if(world[0][x][y].type == wolf) {
            world[0][x][y].breeding_period = w_breeding;
            world[0][x][y].starvation_period = w_starvation;
        } else if(world[0][x][y].type == squirrel || world[0][x][y].type == squirrel_on_tree) {
            world[0][x][y].breeding_period = s_breeding;
        }
    }



    fclose(input_file);


#ifdef VERBOSE
    printf("INITIAL WORLD - w_number = %d\n", w_number);
    printWorldDetailed(size);
    printf("\n");
#endif

    /* Generate */
    while(gen_num != 0) {
        cleanWorld(size);

        /* 1st sub-generation - RED */
        for(i=0; i<size; i++) {
            for(j = i%2 == 0 ? 0 : 1 ; j<size; j+=2) {
                computeCell(i, j, s_breeding, w_breeding, w_starvation, size);
            }
        }

        /* 2nd sub-generation */
        for(i=0; i<size; i++) {
            for(j = i%2 == 0 ? 1 : 0 ; j<size; j+=2) {
                computeCell(i, j, s_breeding, w_breeding, w_starvation, size);
            }
        }


#ifdef VERBOSE
        printf("\n\nIteration %d:\n", gen_num);
        printWorldDetailed(size);
        printf("\n");
#endif

        gen_num--;
        w_number = (w_number+1) % 2;
    }

    /* Output */
    printWorldFormatted(size);

    return 0;
}