Exemplo n.º 1
0
void GQAP::GRASPInit_reduced(double alpha) {
	// GRASP-Initialization using the provided alpa-value
	// works similar to GRASPInit, but considers just one random equipment during the list construction
	
	// if Random-Initialization is choosen, then do random initialization, since it is much faster
	// GRASP-Init with alpha = 0 is equal to random initialization
	if (alpha == 1) {
		RandomInit();
		
	// do GRASP-Init, if alpha > 0
	} else {
		// Define a Vector holing the Restricted Candidate List with maximum size
		std::vector<RCL_element> candidateList(numLocation);
	
		// current Assignment
		Assignment cAssign;
	
		// set the current solution to an undefined representation to distinguish it from valid partial solution
		//solution = std::vector<int>(numEquip, -1);
		solution = eoVector<eoMinimizingFitness, int>(numEquip, -1);
	
		// reset the values for capacity violations
		numViolatedLocations = 0;
		numViolatedCapacityUnits = 0;
	
		// Initialize the RCL
		GRASPInitReducedCandiateList(candidateList);
	
		// Add Assignments, until solution has been constructed
		for (int i = 0; i < numEquip; i++) {
			GRASPAddAssignment_CostBased(candidateList, alpha);
			GRASPUpdateReducedCandiateList(candidateList);
		}
	}
}
DCEL DivideAndConquerFor3DCH::DVCalculate3DConvexHull( vector<VERTEX>* pVertex, const int startPoint, const int endPoint, const unsigned int offset )
{
    /*
    * Phase 1: Find two convex hulls
    */
    if( endPoint - startPoint + 1 <= 10 )
    {
        vector<VERTEX*> tmpVertexSet;
        for( int i = startPoint; i < endPoint  + 1; i++ )
        {
            tmpVertexSet.push_back( &(*pVertex)[ i ] );
        }

        DCEL dcel = BruceForceCH( &tmpVertexSet, offset );
        if (generateAnimation)
        {
            for (list<FaceObject*>::iterator i=dcel.m_Faces->begin(); i!=dcel.m_Faces->end(); i++)
                addOneStep( *i );

        }
        return dcel;
    }

    int midPoint = ( endPoint + startPoint ) * 0.5;
    DCEL CH1 = DVCalculate3DConvexHull( pVertex, startPoint, midPoint, offset );
    DCEL CH2 = DVCalculate3DConvexHull( pVertex, midPoint + 1, endPoint, midPoint + 1 );

    assert(CH1.checkIterators());
    assert(CH2.checkIterators());

    CH1.unsetVisited();
    CH2.unsetVisited();

    /*
    * Phase 2: Merge two convex hulls
    */
    VertexObject* v1AtTanVO = NULL, * v2AtTanVO = NULL;
    vector<VertexObject*> CH_Up, CH_Down;
    CH_Up = find2DConvexHull( CH1.m_Vertexs );
    CH_Down = find2DConvexHull( CH2.m_Vertexs );
    findTangentFor3DCHs( &CH_Up, &CH_Down, &v1AtTanVO, &v2AtTanVO );

    // Find a plane that cross this tangent and parallel z axis
    D3DXVECTOR3 planV1( v1AtTanVO->v->x - v2AtTanVO->v->x, v1AtTanVO->v->y - v2AtTanVO->v->y, v1AtTanVO->v->z - v2AtTanVO->v->z );
    D3DXVECTOR3 planV2( 0.0f, 0.0f, -1.0f * v1AtTanVO->v->z );
    D3DXVECTOR3 planeNormal, tmpPlaneNormal1, tmpPlaneNormal2, maxTmpPlaneNormal1, maxTmpPlaneNormal2;
    D3DXVec3Cross( &planeNormal, &planV1, &planV2 );
    D3DXVec3Normalize( &planeNormal, &planeNormal );

    // make sure planeNormal be the outside normal
    for (list<VertexObject*>::iterator it=CH1.m_Vertexs->begin(); it!=CH1.m_Vertexs->end(); it++)
    {
        D3DXVECTOR3 v((*it)->v->x - v1AtTanVO->v->x, (*it)->v->y - v1AtTanVO->v->y, (*it)->v->z - v1AtTanVO->v->z);
        double dot = D3DXVec3Dot(&v, &planeNormal);
        if (dot > 1E-5)
        {
            planeNormal = planeNormal * -1.0f;
            break;
        }
    }
    for (list<VertexObject*>::iterator it=CH2.m_Vertexs->begin(); it!=CH2.m_Vertexs->end(); it++)
    {
        D3DXVECTOR3 v((*it)->v->x - v1AtTanVO->v->x, (*it)->v->y - v1AtTanVO->v->y, (*it)->v->z - v1AtTanVO->v->z);
        double dot = D3DXVec3Dot(&v, &planeNormal);
        if (dot > 1E-5)
        {
            planeNormal = planeNormal * -1.0f;
            break;
        }
    }

    // These two points are two ends of the tangent
    VertexObject* vE1Start = v1AtTanVO, * vE2Start = v2AtTanVO;

    struct candidateList
    {
        VertexObject* candidatePoint;
        // 0, belong CH on the top; 1, belong CH at the bottom
        int           belonging;
        HalfedgeObject* candidateEdge;
        HalfedgeObject* candidateEdgeTwin;

        candidateList( VertexObject* cand, int bl, HalfedgeObject* candE )
        {
            candidatePoint = cand;
            belonging = bl;
            candidateEdge = candE;
        }

        candidateList()
        {
            candidatePoint = NULL;
            belonging = 1e20f;
            candidateEdge = NULL;
        }

        void operator =( const candidateList& other )
        {
            candidatePoint = other.candidatePoint;
            belonging      = other.belonging;
        }
    };
    vector<candidateList> CHCandidates;
    CHCandidates.push_back( candidateList( v1AtTanVO, 0, NULL ) );
    CHCandidates.push_back( candidateList( v2AtTanVO, 1, NULL ) );


    /*
    * Find triangulation T
    */
    do {
        // Start warping this two convex hull
        double maxPlaneAngleE1 = -10000.0f, maxPlaneAngleE2 = -10000.0f;
        HalfedgeObject* currentHalfEdge = v1AtTanVO->leaving;
        VertexObject* testVertex = currentHalfEdge->twins->origin;
        VertexObject* resultVertex1 = NULL, * resultVertex2 = NULL;
        HalfedgeObject* resultEdge1 = NULL, * resultEdge2 = NULL;

        do
        {
            if (currentHalfEdge->visited)
            {
                currentHalfEdge = currentHalfEdge->twins->nextEdge;
                testVertex = currentHalfEdge->twins->origin;
                continue;
            }
            // Find the angle between two plane
            planV1 = D3DXVECTOR3( v1AtTanVO->v->x - testVertex->v->x, v1AtTanVO->v->y - testVertex->v->y, v1AtTanVO->v->z - testVertex->v->z );
            planV2 = D3DXVECTOR3( v2AtTanVO->v->x - v1AtTanVO->v->x, v2AtTanVO->v->y - v1AtTanVO->v->y, v2AtTanVO->v->z - v1AtTanVO->v->z );
            D3DXVec3Cross( &tmpPlaneNormal1, &planV2, &planV1 );
            D3DXVec3Normalize( &tmpPlaneNormal1, &tmpPlaneNormal1 );

            double tmpMaxPlaneAngle = D3DXVec3Dot( &planeNormal, &tmpPlaneNormal1 );
            if( tmpMaxPlaneAngle > maxPlaneAngleE1 )
            {
                maxPlaneAngleE1 = tmpMaxPlaneAngle;
                resultVertex1 = testVertex;
                maxTmpPlaneNormal1 = tmpPlaneNormal1;
                resultEdge1 = currentHalfEdge;
            }

            currentHalfEdge = currentHalfEdge->twins->nextEdge;
            testVertex = currentHalfEdge->twins->origin;
        } while( currentHalfEdge != v1AtTanVO->leaving );

        currentHalfEdge = v2AtTanVO->leaving;
        testVertex = currentHalfEdge->twins->origin;
        do
        {
            if (currentHalfEdge->visited)
            {
                currentHalfEdge = currentHalfEdge->twins->nextEdge;
                testVertex = currentHalfEdge->twins->origin;
                continue;
            }

            // Find the angle between two plane
            planV1 = D3DXVECTOR3( v2AtTanVO->v->x - testVertex->v->x, v2AtTanVO->v->y - testVertex->v->y, v2AtTanVO->v->z - testVertex->v->z );
            planV2 = D3DXVECTOR3( v1AtTanVO->v->x - v2AtTanVO->v->x, v1AtTanVO->v->y - v2AtTanVO->v->y, v1AtTanVO->v->z - v2AtTanVO->v->z );
            D3DXVec3Cross( &tmpPlaneNormal2, &planV1, &planV2 );
            D3DXVec3Normalize( &tmpPlaneNormal2, &tmpPlaneNormal2 );

            double tmpMaxPlaneAngle = D3DXVec3Dot( &planeNormal, &tmpPlaneNormal2 );
            if( tmpMaxPlaneAngle > maxPlaneAngleE2 )
            {
                maxPlaneAngleE2 = tmpMaxPlaneAngle;
                maxTmpPlaneNormal2 = tmpPlaneNormal2;
                resultVertex2 = testVertex;
                resultEdge2 = currentHalfEdge;
            }

            currentHalfEdge = currentHalfEdge->twins->nextEdge;
            testVertex = currentHalfEdge->twins->origin;
        } while( currentHalfEdge != v2AtTanVO->leaving );

        if( maxPlaneAngleE2 < maxPlaneAngleE1 )
        {
            v1AtTanVO = resultVertex1;
            v1AtTanVO->status = 1;
            planeNormal = maxTmpPlaneNormal1;
            resultEdge1->visited = true;
            CHCandidates.push_back( candidateList( resultVertex1, 0, resultEdge1 ) );


        }
        else
        {
            v2AtTanVO = resultVertex2;
            v2AtTanVO->status = 1;
            planeNormal = maxTmpPlaneNormal2;
            resultEdge2->visited = true;
            CHCandidates.push_back( candidateList( resultVertex2, 1, resultEdge2 ) );
        }
    } while( vE1Start != v1AtTanVO || vE2Start != v2AtTanVO );


    /*
    * Change DCEL structure, delete the face, halfedges and vertices inside the new convex hull
    */
    for (int i=2; i<(int)CHCandidates.size(); i++)
    {
        CHCandidates[ i ].candidateEdge->visited = true;
    }

    for (int i=2; i<(int)CHCandidates.size(); i++)
    {
        if ( CHCandidates[ i ].belonging == 0)
            recursivelyDeleteFace( CHCandidates[ i ].candidateEdge->attachedFace, &CH1);
        else
        {
            recursivelyDeleteFace( CHCandidates[ i ].candidateEdge->twins->attachedFace, &CH2);
        }
    }

    /*
    * Construct DCEL based on the CHCandidates
    */

    list<FaceObject*>::iterator faceIter, tmpFaceIter;
    candidateList a = CHCandidates[ 0 ]; // tangent point at CH1
    candidateList b = CHCandidates[ 1 ]; // tangent point at CH2

    //int latestPos = 1;
    vector<FaceObject*> tmpFaces;
    for( int i = 2; i < CHCandidates.size(); i++ )
    {
        VertexObject* curPoint = CHCandidates[ i ].candidatePoint;
        HalfedgeObject *HEdge1 = new HalfedgeObject;
        HalfedgeObject *HEdge2 = new HalfedgeObject;
        HalfedgeObject *HEdge3 = new HalfedgeObject;

        if (CHCandidates[ i ].belonging == 0)
        {
            delete HEdge2;
            HEdge2 = CHCandidates[ i ].candidateEdge;
        }
        else
        {
            delete HEdge3;
            HEdge3 = CHCandidates[ i ].candidateEdge->twins;
        }

        FaceObject* face = new FaceObject;
        face->attachedEdge = HEdge1;
        tmpFaces.push_back( face );

        HEdge1->origin = b.candidatePoint;
        HEdge1->attachedFace = face;
        b.candidatePoint->leaving = HEdge1;
        HEdge1->nextEdge = HEdge2;
        HEdge1->preEdge  = HEdge3;

        HEdge2->origin = a.candidatePoint;
        HEdge2->attachedFace = face;
        a.candidatePoint->leaving = HEdge2;
        HEdge2->nextEdge = HEdge3;
        HEdge2->preEdge  = HEdge1;

        HEdge3->origin = curPoint;
        HEdge3->attachedFace = face;
        curPoint->leaving = HEdge3;
        HEdge3->nextEdge = HEdge1;
        HEdge3->preEdge  = HEdge2;

        if( CHCandidates[ i ].belonging == a.belonging )
        {
            HEdge2->twins = CHCandidates[ i ].candidateEdge->twins;
            CHCandidates[ i ].candidateEdge->twins->twins = HEdge2;
        }
        else
        {
            HEdge3->twins = CHCandidates[ i ].candidateEdge;
            CHCandidates[ i ].candidateEdge->twins = HEdge3;
        }

        int currentPos = CHCandidates[ i ].belonging;
        if( currentPos == 1 )
        {
            b = CHCandidates[ i ];
        }
        else
        {
            a = CHCandidates[ i ];
        }
    }


    for( int i = 0; i < tmpFaces.size(); i++ )
    {
        HalfedgeObject* preHEArray[ 3 ], * curHEArray[ 3];
        preHEArray[ 0 ] = tmpFaces[ ( i - 1 + tmpFaces.size() ) % tmpFaces.size() ]->attachedEdge;
        preHEArray[ 1 ] = tmpFaces[ ( i - 1 + tmpFaces.size() ) % tmpFaces.size() ]->attachedEdge->nextEdge;
        preHEArray[ 2 ] = tmpFaces[ ( i - 1 + tmpFaces.size() ) % tmpFaces.size() ]->attachedEdge->nextEdge->nextEdge;

        curHEArray[ 0 ] = tmpFaces[ i ]->attachedEdge;
        curHEArray[ 1 ] = tmpFaces[ i ]->attachedEdge->nextEdge;
        curHEArray[ 2 ] = tmpFaces[ i ]->attachedEdge->nextEdge->nextEdge;

        bool flag = true;
        for( int j = 0; j < 3 && flag; j++ )
        {
            for( int k = 0; k < 3; k++ )
            {
                if( preHEArray[ k ]->nextEdge->origin == curHEArray[ j ]->origin && curHEArray[ j ]->nextEdge->origin == preHEArray[ k ]->origin )
                {
                    preHEArray[ k ]->twins = curHEArray[ j ];
                    curHEArray[ j ]->twins = preHEArray[ k ];
                    flag = false;
                    break;
                }
            }
        }
    }

    /*
    * Change DCEL structure, delete the vertices
    * Delete points with status delete
    */

    list<VertexObject*>::iterator vexIter, tmpVexIter;
    for( vexIter = CH1.m_Vertexs->begin(); vexIter != CH1.m_Vertexs->end();  )
    {
        if( (*vexIter)->status == 2 )
        {
            tmpVexIter = vexIter++;
            CH1.remove( (*tmpVexIter ) );
        }
        else
        {
            // Reset point status
            if( (*vexIter)->status == 1 )
            {
                (*vexIter)->status == 0;
            }
            vexIter++;
        }
    }
    for( vexIter = CH2.m_Vertexs->begin(); vexIter != CH2.m_Vertexs->end();  )
    {
        if( (*vexIter)->status == 2 )
        {
            tmpVexIter = vexIter++;
            CH2.remove( (*tmpVexIter) );
        }
        else
        {
            // Reset point status
            if( (*vexIter)->status == 1 )
            {
                (*vexIter)->status == 0;
            }
            vexIter++;
        }

    }



    CH1.m_HalfEdges->splice( CH1.m_HalfEdges->end(), *CH2.m_HalfEdges );
    CH1.m_Faces->splice( CH1.m_Faces->end(), *CH2.m_Faces );
    CH1.m_Vertexs->splice( CH1.m_Vertexs->end(), *CH2.m_Vertexs );

    for( int i = 0; i < tmpFaces.size(); i++ )
    {
        CH1.add( tmpFaces[ i ] );
        CH1.add( tmpFaces[ i ]->attachedEdge );
        CH1.add( tmpFaces[ i ]->attachedEdge->nextEdge );
        CH1.add( tmpFaces[ i ]->attachedEdge->nextEdge->nextEdge );
        tmpFaces[ i ]->normal = VECTOR(*tmpFaces[ i ]->attachedEdge->nextEdge->origin->v - *tmpFaces[ i ]->attachedEdge->origin->v).normalize();
        tmpFaces[ i ]->normal = tmpFaces[ i ]->normal.cross(VECTOR(*tmpFaces[ i ]->attachedEdge->nextEdge->nextEdge->origin->v - *tmpFaces[ i ]->attachedEdge->origin->v)).normalize();
        if (generateAnimation)
        {
            addOneStep(&CH1);
        }
    }


    CH1.fixIterator();
    CH1.removeUselessVertices();
    CH1.fixIterator();

    return CH1;
}