Beispiel #1
0
bool ResourceNode::_TrackBack(ResourceNode* node, STD_NAMESPACE::set<ResourceNode*>& trackBuffer)
{
	if (m_isRootNode)
		return true;
	m_isDeleted = true;

	STD_NAMESPACE::set<ResourceNode*>::iterator iter = node->m_inputs.begin();
	for (; iter != node->m_inputs.end(); iter++)
	{
		ResourceNode* i = *iter;
		if (i->m_isDeleted)
			continue;
		if (trackBuffer.find(i) != trackBuffer.end())
			continue;
		trackBuffer.insert(i);
		if (_TrackBack(i, trackBuffer)) {
			m_isDeleted = false;
			return true;
		}
	}
	iter = m_outputs.begin();
	for (; iter != m_outputs.end(); iter++)
	{
		ResourceNode* node = *iter;
		if (node->m_isDeleted)
			continue;
		node->m_inputs.erase(this);
	}
	MarkDeleted();
	return false;
}
Beispiel #2
0
GainType LKH::LKHAlg::PatchCycles(int k, GainType Gain)
{
    Node *s1, *s2, *sStart, *sStop;
    GainType NewGain;
    int M, i;

	if(!CurrentCycle.get())
	{
		CurrentCycle.reset(new int(0));
		Patchwork.reset(new int(0));
		RecLevel.reset(new int(0));
	}
	FindPermutation(k,this);
    M = Cycles(k);
    if (M == 1 && Gain > 0) {
        MakeKOptMove(k);
        return Gain;
    }
    if (M == 1 || M > PatchingC || k + M > NonsequentialMoveType)
        return 0;
    if (*RecLevel == 0)
        *Patchwork = 0;
    *CurrentCycle = ShortestCycle(M, k,this);
    for (i = 0; i < k; i++) {
        if ((*cycle.get())[(*p.get())[2 * i]] != *CurrentCycle)
            continue;
        sStart = (*t.get())[(*p.get())[2 * i]];
        sStop = (*t.get())[(*p.get())[2 * i + 1]];
        for (s1 = sStart; s1 != sStop; s1 = s2) {
            s2 = SUC(s1);
            if (FixedOrCommon(s1, s2))
                continue;
            if (++(*Patchwork) > Dimension)
                return 0;
            (*t.get())[2 * k + 1] = s1;
            (*t.get())[2 * k + 2] = s2;
            MarkDeleted(s1, s2);
            /* Find a set of gainful alternating cycles */
            NewGain = PatchCyclesRec(k, 2, M, Gain + (this->*C)(s1, s2),this);
            UnmarkDeleted(s1, s2);
            if (NewGain > 0)
                return NewGain;
        }
    }
    return 0;
}
Beispiel #3
0
LKH::LKHAlg::Node * LKH::LKHAlg::BestKOptMove(Node * t1, Node * t2, GainType * G0, GainType * Gain)
{
	if(!BestG2.get())
		BestG2.reset(new GainType(0));
    *K = Swaps == 0 ? MoveType : SubsequentMoveType;
    *Gain = 0;
    (*t.get())[1] = t1;
    (*t.get())[2] = t2;
    (*T.get())[2 * *K] = 0;
    *BestG2 = MINUS_INFINITY;

    /* 
     * Determine (T[3],T[4], ..., T[2K]) = (t[3],t[4], ..., t[2K])
     * such that
     *
     *     G[2 * K] = *G0 - C(t[2],T[3]) + C(T[3],T[4])
     *                    - C(T[4],T[5]) + C(T[5],T[6])
     *                      ...
     *                    - C(T[2K-3],T[2K-2]) + C(T[2K-1],T[2K])
     *
     * is maximum, and (T[2K-1],T[2K]) has not previously been included.
     * If during this process a legal move with *Gain > 0 is found, then 
     * make the move and exit BestKOptMove immediately.
     */

    MarkDeleted(t1, t2);
    *Gain = BestKOptMoveRec(2, *G0,this);
    UnmarkDeleted(t1, t2);

    if (*Gain <= 0 && (*T.get())[2 * *K]) {
        int i;
        memcpy(t.get() + 1, T.get() + 1, 2 * *K * sizeof(Node *));
        for (i = 2; i < 2 * *K; i += 2)
            (*incl.get())[(*incl.get())[i] = i + 1] = i;
        (*incl.get())[(*incl.get())[1] = 2 * *K] = 1;
        MakeKOptMove(*K);
        for (i = 1; i < 2 * *K; i += 2)
            Exclude((*T.get())[i], (*T.get())[i + 1]);
        *G0 = *BestG2;
        return (*T.get())[2 * *K];
    }
    return 0;
}
Beispiel #4
0
void CItems::Delete(std::vector<int>& vIds, BOOL bRemove /*= FALSE*/)
{
	std::map<int, int> setIds;
	for (std::vector<int>::iterator it = vIds.begin(); it != vIds.end(); ++it)
	{
		if (setIds.find(*it) == setIds.end())
		{
			std::vector< std::pair<int, int> > v;
			EnumItems(*it, v);
			for (std::vector< std::pair<int, int> >::iterator vi = v.begin(); vi != v.end(); ++vi)
			{
				// first - id, second - is folder
				setIds[vi->first] = vi->second;
			}
		}
	}

	for (std::map<int, int>::iterator it = setIds.begin(); it != setIds.end(); ++it)
	{
		if (bRemove)
		{
			RemoveItem(it->first);
		}
		else
		{
			MarkDeleted(it->first);
		}
		if (it->second) // folder
		{
			CApplicationImpl::Get().UpdateViews(UNM_FOLDER_DELETED, it->first);
		}
		else
		{
			CApplicationImpl::Get().UpdateViews(UNM_ITEM_DELETED, it->first);
		}
	}
}
Beispiel #5
0
static GainType BestKOptMoveRec(int k, GainType G0,LKH::LKHAlg *Alg)
{
    LKH::LKHAlg::Candidate *Nt2;
    LKH::LKHAlg::Node *t1, *t2, *t3, *t4;
    GainType G1, G2, G3, Gain;
    int X4, i;
    int Breadth2 = 0;

    t1 = (*t.get())[1];
    t2 = (*t.get())[i = 2 * k - 2];
    (*incl.get())[(*incl.get())[i] = i + 1] = i;
    (*incl.get())[(*incl.get())[1] = i + 2] = 1;
    /* Choose (t2,t3) as a candidate edge emanating from t2 */
    for (Nt2 = t2->CandidateSet; (t3 = Nt2->To); Nt2++) {
        if (t3 == t2->Pred || t3 == t2->Suc ||
            ((G1 = G0 - Nt2->Cost) <= 0 && Alg->GainCriterionUsed &&
             Alg->ProblemType != LKH::HCP && Alg->ProblemType != LKH::HPP)
            || Added(t2, t3))
            continue;
        if (++Breadth2 > Alg->MaxBreadth)
            break;
        MarkAdded(t2, t3);
        (*t.get())[2 * k - 1] = t3;
        (*G.get())[2 * k - 2] = G1 + t3->Pi;
        /* Choose t4 as one of t3's two neighbors on the tour */
        for (X4 = 1; X4 <= 2; X4++) {
            t4 = X4 == 1 ? (Alg->Reversed == (t3)->Parent->Reversed ? (t3)->Pred : (t3)->Suc) : (Alg->Reversed == (t3)->Parent->Reversed ? (t3)->Suc : (t3)->Pred);
            if ((Fixed(t3, t4) || Alg->IsCommonEdge(t3, t4)) || Deleted(t3, t4))
                continue;
            (*t.get())[2 * k] = t4;
            G2 = G1 + (Alg->*(Alg->C))(t3, t4);
            G3 = MINUS_INFINITY;
            if (t4 != t1 && !Alg->Forbidden(t4, t1) && !Added(t4, t1) &&
				(!Alg->c || G2 - (Alg->*(Alg->c))(t4, t1) > 0) &&
                (G3 = G2 - (Alg->*(Alg->C))(t4, t1)) > 0 && FeasibleKOptMove(k)) {
                UnmarkAdded(t2, t3);
                Alg->MakeKOptMove(k);
                return G3;
            }
            if (Alg->Backtracking && !Alg->Excludable(t3, t4))
                continue;
            MarkDeleted(t3, t4);
            (*G.get())[2 * k - 1] = G2 - t4->Pi;
            if (k < *K) {
				if ((Gain = BestKOptMoveRec(k + 1, G2,Alg)) > 0) {
                    UnmarkAdded(t2, t3);
                    UnmarkDeleted(t3, t4);
                    return Gain;
                }
                (*incl.get())[(*incl.get())[1] = 2 * k] = 1;
            }
            if (t4 != t1 && !Alg->Forbidden(t4, t1) &&
                k + 1 < Alg->NonsequentialMoveType &&
                Alg->PatchingC >= 2 && Alg->PatchingA >= 1 &&
                (Alg->Swaps == 0 || Alg->SubsequentPatching)) {
                if (G3 == MINUS_INFINITY)
                    G3 = G2 - (Alg->*(Alg->C))(t4, t1);
                if ((Alg->PatchingCRestricted ? G3 > 0 && Alg->IsCandidate(t4, t1) :
                     Alg->PatchingCExtended ? G3 > 0
                     || Alg->IsCandidate(t4, t1) : G3 > 0)
                    && (Gain = Alg->PatchCycles(k, G3)) > 0) {
                    UnmarkAdded(t2, t3);
                    UnmarkDeleted(t3, t4);
                    return Gain;
                }
            }
            UnmarkDeleted(t3, t4);
            if (k == *K && t4 != t1 && t3 != t1 && G3 <= 0 &&
                !Added(t4, t1) &&
                (!Alg->GainCriterionUsed || G2 - Alg->Precision >= t4->Cost)) {
                if (!Alg->Backtracking || Alg->Swaps > 0) {
                    if ((G2 > *BestG2 ||
                         (G2 == *BestG2 && !Near(t3, t4) &&
                          Near((*T.get())[2 * *K - 1], (*T.get())[2 * *K]))) &&
                        Alg->Swaps < Alg->MaxSwaps &&
                        Alg->Excludable(t3, t4) && !InInputTour(t3, t4)) {
                        if (Alg->RestrictedSearch && *K > 2 &&
                            Alg->ProblemType != LKH::HCP && Alg->ProblemType != LKH::HPP) {
                            /* Ignore the move if the gain does not vary */
                            (*G.get())[0] = (*G.get())[2 * *K - 2];
                            (*G.get())[1] = (*G.get())[2 * *K - 1];
                            for (i = 2 * *K - 3; i >= 2; i--)
                                if ((*G.get())[i] != (*G.get())[i % 2])
                                    break;
                            if (i < 2)
                                continue;
                        }
                        if (FeasibleKOptMove(*K)) {
                            *BestG2 = G2;
                            memcpy(T.get() + 1, t.get() + 1, 2 * *K * sizeof(LKH::LKHAlg::Node *));
                        }
                    }
                } else if (Alg->MaxSwaps > 0 && FeasibleKOptMove(*K)) {
					LKH::LKHAlg::Node *SUCt1 = (Alg->Reversed == (t1)->Parent->Reversed ? (t1)->Suc : (t1)->Pred);
                    Alg->MakeKOptMove(*K);
                    for (i = 1; i < 2 * k; i += 2) {
                        Alg->Exclude((*t.get())[i], (*t.get())[i + 1]);
                        UnmarkDeleted((*t.get())[i], (*t.get())[i + 1]);
                    }
                    for (i = 2; i < 2 * k; i += 2)
                        UnmarkAdded((*t.get())[i], (*t.get())[i + 1]);
                    memcpy(tSaved.get() + 1, t.get() + 1, 2 * k * sizeof(LKH::LKHAlg::Node *));
                    while ((t4 = (Alg->*(Alg->BestSubsequentMove))(t1, t4, &G2, &Gain)));
                    if (Gain > 0) {
                        UnmarkAdded(t2, t3);
                        return Gain;
                    }
                    Alg->RestoreTour();
                    *K = k;
                    memcpy(t.get() + 1, tSaved.get() + 1, 2 * *K * sizeof(LKH::LKHAlg::Node *));
                    for (i = 1; i < 2 * *K - 2; i += 2)
                        MarkDeleted((*t.get())[i], (*t.get())[i + 1]);
                    for (i = 2; i < 2 * *K; i += 2)
                        MarkAdded((*t.get())[i], (*t.get())[i + 1]);
                    for (i = 2; i < 2 * *K; i += 2)
                        (*incl.get())[(*incl.get())[i] = i + 1] = i;
                    (*incl.get())[(*incl.get())[1] = 2 * *K] = 1;
                    if (SUCt1 != (Alg->Reversed == (t1)->Parent->Reversed ? (t1)->Suc : (t1)->Pred))
                        Alg->Reversed ^= 1;
                    (*T.get())[2 * *K] = 0;
                }
            }
        }
        UnmarkAdded(t2, t3);
        if (t3 == t1)
            continue;
        /* Try to delete an added edge, (_,t3) or (t3,_) */
        for (i = 2 * k - 4; i >= 2; i--) {
            if (t3 == (*t.get())[i]) {
                t4 = (*t.get())[i ^ 1];
                if (t4 == t1 || Alg->Forbidden(t4, t1) || (Fixed(t3, t4) || Alg->IsCommonEdge(t3, t4)) ||
                    Added(t4, t1))
                    continue;
                G2 = G1 + (Alg->*(Alg->C))(t3, t4);
                if ((!Alg->c || G2 - (Alg->*(Alg->c))(t4, t1) > 0)
                    && (Gain = G2 - (Alg->*(Alg->C))(t4, t1)) > 0) {
                    (*incl.get())[(*incl.get())[i ^ 1] = 1] = i ^ 1;
                    (*incl.get())[(*incl.get())[i] = 2 * k - 2] = i;
                    if (FeasibleKOptMove(k - 1)) {
                        Alg->MakeKOptMove(k - 1);
                        return Gain;
                    }
                    (*incl.get())[(*incl.get())[i ^ 1] = i] = i ^ 1;
                }
            }
        }
        (*incl.get())[1] = 2 * k;
        (*incl.get())[2 * k - 2] = 2 * k - 1;
    }
    return 0;
}
Beispiel #6
0
static GainType PatchCyclesRec(int k, int m, int M, GainType G0, LKH::LKHAlg *Alg)
{
    LKH::LKHAlg::Node *s1, *s2, *s3, *s4, *s5, *s6, *S3 = 0, *S4 = 0;
    LKH::LKHAlg::Candidate *Ns2, *Ns4;
    GainType G1, G2, G3, G4, Gain, CloseUpGain,
        BestCloseUpGain = Alg->PatchingAExtended ? MINUS_INFINITY : 0;
    int X4, X6;
    int i, NewCycle, *cycleSaved = 0, *pSaved = 0;
    int Breadth2 = 0, Breadth4;

    s1 = (*t.get())[2 * k + 1];
    s2 = (*t.get())[i = 2 * (k + m) - 2];
    (*incl.get())[(*incl.get())[i] = i + 1] = i;

    /* Choose (s2,s3) as a candidate edge emanating from s2 */
    for (Ns2 = s2->CandidateSet; (s3 = Ns2->To); Ns2++) {
        if (s3 == s2->Pred || s3 == s2->Suc || Added(s2, s3) ||
			(NewCycle = Cycle(s3, k,Alg)) == *CurrentCycle)
            continue;
        if (++Breadth2 > Alg->MaxBreadth)
            break;
        MarkAdded(s2, s3);
        (*t.get())[2 * (k + m) - 1] = s3;
        G1 = G0 - Ns2->Cost;
        /* Choose s4 as one of s3's two neighbors on the tour */
        for (X4 = 1; X4 <= 2; X4++) {
            s4 = X4 == 1 ? s3->Pred : s3->Suc;
            if ((Fixed(s3, s4) || Alg->IsCommonEdge(s3, s4)) || Deleted(s3, s4))
                continue;
            MarkDeleted(s3, s4);
            (*t.get())[2 * (k + m)] = s4;
			G2 = G1 + (Alg->*(Alg->C))(s3, s4);
            if (M > 2) {
                if (!cycleSaved) {
                    assert(cycleSaved =
                           (int *) malloc(2 * k * sizeof(int)));
                    memcpy(cycleSaved, cycle.get() + 1, 2 * k * sizeof(int));
                }
                for (i = 1; i <= 2 * k; i++)
                    if ((*cycle.get())[i] == NewCycle)
                        (*cycle.get())[i] = *CurrentCycle;
                /* Extend the current alternating path */
				if ((Gain = PatchCyclesRec(k, m + 1, M - 1, G2,Alg)) > 0) {
                    UnmarkAdded(s2, s3);
                    UnmarkDeleted(s3, s4);
                    goto End_PatchCyclesRec;
                }
                memcpy(cycle.get() + 1, cycleSaved, 2 * k * sizeof(int));
                if (Alg->PatchingA >= 2 && *Patchwork < Alg->Dimension &&
                    k + M < Alg->NonsequentialMoveType &&
                    !Alg->Forbidden(s4, s1) &&
                    (!Alg->PatchingARestricted || Alg->IsCandidate(s4, s1))) {
                    GainType Bound = BestCloseUpGain >= 0 ||
                        Alg->IsCandidate(s4, s1) ? BestCloseUpGain : 0;
                    if ((!Alg->c || G2 - (Alg->*(Alg->c))(s4, s1) > Bound) &&
                        (CloseUpGain = G2 - (Alg->*(Alg->C))(s4, s1)) > Bound) {
                        S3 = s3;
                        S4 = s4;
                        BestCloseUpGain = CloseUpGain;
                    }
                }
            } else if (!Alg->Forbidden(s4, s1) && (!Alg->c || G2 - (Alg->*(Alg->c))(s4, s1) > 0)
                       && (Gain = G2 - (Alg->*(Alg->C))(s4, s1)) > 0) {
                (*incl.get())[(*incl.get())[2 * k + 1] = 2 * (k + m)] = 2 * k + 1;
                Alg->MakeKOptMove(k + m);
                UnmarkAdded(s2, s3);
                UnmarkDeleted(s3, s4);
                goto End_PatchCyclesRec;
            }
            UnmarkDeleted(s3, s4);
        }
        UnmarkAdded(s2, s3);
    }
    if (M == 2 && !Alg->PatchingCRestricted) {
        /* Try to patch the two cycles by a sequential 3-opt move */
        (*incl.get())[(*incl.get())[2 * (k + m)] = 2 * (k + m) + 1] = 2 * (k + m);
        (*incl.get())[(*incl.get())[2 * k + 1] = 2 * (k + m) + 2] = 2 * k + 1;
        Breadth2 = 0;
        /* Choose (s2,s3) as a candidate edge emanating from s2 */
        for (Ns2 = s2->CandidateSet; (s3 = Ns2->To); Ns2++) {
            if (s3 == s2->Pred || s3 == s2->Suc || Added(s2, s3))
                continue;
            if (++Breadth2 > Alg->MaxBreadth)
                break;
            (*t.get())[2 * (k + m) - 1] = s3;
            G1 = G0 - Ns2->Cost;
			NewCycle = Cycle(s3, k,Alg);
            /* Choose s4 as one of s3's two neighbors on the tour */
            for (X4 = 1; X4 <= 2; X4++) {
                s4 = X4 == 1 ? s3->Pred : s3->Suc;
                if ((Fixed(s3, s4) || Alg->IsCommonEdge(s3, s4)) || Deleted(s3, s4))
                    continue;
                (*t.get())[2 * (k + m)] = s4;
                G2 = G1 + (Alg->*(Alg->C))(s3, s4);
                Breadth4 = 0;
                /* Choose (s4,s5) as a candidate edge emanating from s4 */
                for (Ns4 = s4->CandidateSet; (s5 = Ns4->To); Ns4++) {
                    if (s5 == s4->Pred || s5 == s4->Suc || s5 == s1 ||
                        Added(s4, s5) ||
                        (NewCycle == *CurrentCycle &&
						Cycle(s5, k,Alg) == *CurrentCycle))
                        continue;
                    if (++Breadth4 > Alg->MaxBreadth)
                        break;
                    G3 = G2 - Ns4->Cost;
                    /* Choose s6 as one of s5's two neighbors on the tour */
                    for (X6 = 1; X6 <= 2; X6++) {
                        s6 = X6 == 1 ? s5->Pred : s5->Suc;
                        if (s6 == s1 || Alg->Forbidden(s6, s1)
                            || (Fixed(s5, s6) || Alg->IsCommonEdge(s5, s6))
                            || Deleted(s5, s6)
                            || Added(s6, s1))
                            continue;
                        G4 = G3 + (Alg->*(Alg->C))(s5, s6);
                        if ((!Alg->c || G4 - (Alg->*(Alg->c))(s6, s1) > 0) &&
                            (Gain = G4 - (Alg->*(Alg->C))(s6, s1)) > 0) {
                            if (!pSaved) {
                                assert(pSaved =
                                       (int *) malloc(2 * k *
                                                      sizeof(int)));
                                memcpy(pSaved, p.get() + 1, 2 * k * sizeof(int));
                            }
                            (*t.get())[2 * (k + m) + 1] = s5;
                            (*t.get())[2 * (k + m) + 2] = s6;
                            if (FeasibleKOptMove(k + m + 1)) {
                                Alg->MakeKOptMove(k + m + 1);
                                goto End_PatchCyclesRec;
                            }
                            memcpy(p.get() + 1, pSaved, 2 * k * sizeof(int));
                            for (i = 1; i <= 2 * k; i++)
                                (*q.get())[(*p.get())[i]] = i;
                        }
                    }
                }
            }
        }
    }
    Gain = 0;
    if (S4) {
        int OldCycle = *CurrentCycle;
        if (!pSaved) {
            assert(pSaved = (int *) malloc(2 * k * sizeof(int)));
            memcpy(pSaved, p.get() + 1, 2 * k * sizeof(int));
        }
        (*t.get())[2 * (k + m) - 1] = S3;
        (*t.get())[2 * (k + m)] = S4;
        (*incl.get())[(*incl.get())[2 * k + 1] = 2 * (k + m)] = 2 * k + 1;
        /* Find a new alternating cycle */
        Alg->PatchingA--;
        (*RecLevel)++;
        MarkAdded(s2, S3);
        MarkDeleted(S3, S4);
        MarkAdded(S4, s1);
        Gain = Alg->PatchCycles(k + m, BestCloseUpGain);
        UnmarkAdded(s2, S3);
        UnmarkDeleted(S3, S4);
        UnmarkAdded(S4, s1);
        (*RecLevel)--;
        Alg->PatchingA++;
        if (Gain <= 0) {
            memcpy(cycle.get() + 1, cycleSaved, 2 * k * sizeof(int));
            memcpy(p.get() + 1, pSaved, 2 * k * sizeof(int));
            for (i = 1; i <= 2 * k; i++)
                (*q.get())[(*p.get())[i]] = i;
            *CurrentCycle = OldCycle;
        }
    }

  End_PatchCyclesRec:
    free(cycleSaved);
    free(pSaved);
    return Gain;
}