예제 #1
1
/*
Takes two lists sorted in increasing order, and
splices their nodes together to make one big
sorted list which is returned.
*/
struct node* SortedMerge(struct node* a, struct node* b) {
	struct node dummy; // a dummy first node to hang the result on
	struct node* tail = &dummy; // Points to the last result node --
	// so tail->next is the place to add
	// new nodes to the result.
	dummy.next = NULL;
	while (1) {
		if (a == NULL) { // if either list runs out, use the other list
			tail->next = b;
			break;
		}
		else if (b == NULL) {
			tail->next = a;
			break;
		}

		if (a->data <= b->data) {
			MoveNode(&(tail->next), &a);
		}
		else {
			MoveNode(&(tail->next), &b);
		}
		tail = tail->next;
	}
return(dummy.next);
}
예제 #2
0
파일: problem11.c 프로젝트: imwally/cmuck
int main(int argc, char *arg[]) {
    struct node* listA = NULL;
    Push(&listA, 3); 
    Push(&listA, 2); 
    Push(&listA, 1); 

    struct node* listB = NULL;
    Push(&listB, 6); 
    Push(&listB, 5); 
    Push(&listB, 4); 

    printf("List A\n");
    PrintList(listA);
    printf("List B\n");
    PrintList(listB);

    MoveNode(&listA, &listB);
    printf("List A\n");
    PrintList(listA);
    printf("List B\n");
    PrintList(listB);

    MoveNode(&listA, &listB);
    printf("List A\n");
    PrintList(listA);
    printf("List B\n");
    PrintList(listB);
}
예제 #3
0
파일: Tree.cpp 프로젝트: cherry-wb/GALex
		// Swaps positions of nodes in the list
		void GaTreeBase::SwapNodes(GaTreeNodeBase* node1,
			GaTreeNodeBase* node2)
		{
			GaTreeNodeBase* parent1 = node1->GetParent();
			GaTreeNodeBase* parent2 = node2->GetParent();

			// get positions of nodes in their parent's children list
			int position1 = parent1->GetChildren()->GetPosition( node1 );
			int position2 = parent2->GetChildren()->GetPosition( node2 );

			// move the first node
			MoveNode( node1, parent2, position2 );

			try
			{
				// move the second node
				MoveNode( node2, parent1, position1 );
			}
			catch( ... )
			{
				// if moveing second node fails - place back the first node
				MoveNode( node1, parent1, position1 );
				throw;
			}
		}
예제 #4
0
struct Node* Merge(struct Node *a, struct Node *b)
{
    struct Node dummy;
    struct Node* tail = NULL;

    tail = &dummy;

    dummy.next = NULL;

    while(1){
        if (a == NULL){
            tail->next = b;
            break;
        }else if (b == NULL){
            tail->next = a;
            break;
        }

        if (a->data <= b->data){
            MoveNode(&(tail->next), &a);
        }
        else{
            MoveNode(&(tail->next), &b);
        }
        tail=tail->next;
    }

    return (dummy.next);
}
예제 #5
0
struct node *ShuffleMerge (struct node *a, struct node *b)
{
		struct node *temp = NULL;
		struct node **tpos = &temp;
		struct node *aa = a;
		struct node *bb = b;
		while (1) {
				if (aa == 0) {
						*tpos = bb;
						break;
				}
				else if (bb == 0) {
						*tpos = aa;
						break;
				}
				MoveNode(tpos, &aa);
				tpos = &((*tpos)->next);
				MoveNode(tpos, &bb);
				tpos = &((*tpos)->next);
		}
		return temp;




}
예제 #6
0
bool OperCFThread::Move(FS *srcFs, FSPath &__srcPath, FSList *list, FS *destFs, FSPath &__destPath)
{
	if (list->Count()<=0) return true;
	
	FSPath srcPath = __srcPath; int srcPos = srcPath.Count();
	FSPath destPath = __destPath; int destPos = destPath.Count();
			
	FSStat st;
	int ret_error;
	int r = destFs->Stat(__destPath, &st, &ret_error, Info());
	if (r == -2) return false;

	
	if (list->Count()>1)
	{
	
		//если файлов >1 то копировать можно только в каталог
		if (r) {
			RedMessage( _LT("Can't move files, bad destination directory:\n"), destFs->Uri(__destPath).GetUtf8(), bOk, destFs->StrError(ret_error).GetUtf8());
			return false;
		}
	
		if (!st.IsDir()) 
		{
			RedMessage( _LT("Destination is not directory:\n"), destFs->Uri(__destPath).GetUtf8(), bOk);
			return false;
		}
				
		for (FSNode *node = list->First(); node; node = node->next)
		{
			srcPath.SetItemStr(srcPos, node->Name());
			destPath.SetItemStr(destPos, node->Name());
//printf("MOVE '%s'\n", srcPath.GetUtf8());			
			if (!MoveNode(srcFs, srcPath, node, destFs, destPath)) return false;
		}
		
	} else {
		// 1 element

		if (r && !destFs->IsENOENT(ret_error))
		{
			RedMessage( _LT("Can't move to:\n"), destFs->Uri(destPath).GetUtf8(), bOk, destFs->StrError(ret_error).GetUtf8());
			return false;
		}

		if (!r && st.IsDir())
			destPath.SetItemStr(destPos, list->First()->Name());
		
		FSNode *node = list->First();
		
		srcPath.SetItemStr(srcPos, list->First()->Name());
		
		if (!MoveNode(srcFs, srcPath, list->First(), destFs, destPath)) return false;
		
	}
	
	return true;
}
예제 #7
0
void AlternatingSplit(struct node* source,struct node** aRef, struct node** bRef)
{
  while(source != NULL)
  {
      MoveNode(aRef, &source);

      if(source != NULL)
        MoveNode(bRef, &source);
  }
  print_linked_list("aRef", aRef);
  print_linked_list("bRef", bRef);
}
예제 #8
0
파일: ex12.c 프로젝트: VitSalis/Algorithms
void AlternatingSplit( struct node* source, struct node** aRef, struct node** bRef ) {
	struct node* a = NULL;
	struct node* b = NULL;
	struct node* current = source;
	while ( current != NULL ) {
		MoveNode( &a, &current );
		if ( current != NULL ) {
			MoveNode( &b, &current );
		}
	}
	*aRef = a;
	*bRef = b;
}
예제 #9
0
/*
Given the source list, split its nodes into two shorter lists.
If we number the elements 0, 1, 2, ... then all the even elements
should go in the first list, and all the odd elements in the second.
The elements in the new lists may be in any order.
*/
void AlternatingSplit(struct node* source,
struct node** aRef, struct node** bRef) {
	struct node* a = NULL; // Split the nodes to these 'a' and 'b' lists
	struct node* b = NULL;
	struct node* current = source;
	while (current != NULL) {
		MoveNode(&a, &current); // Move a node to 'a'
		if (current != NULL) {
			MoveNode(&b, &current); // Move a node to 'b'
		}
	}
	*aRef = a;
	*bRef = b;
}
예제 #10
0
void AlternatingSplit (struct node *source, struct node **aRef, struct node **bRef)
{
		struct node *temp = source;
		struct node *a = NULL;
		struct node *b = NULL;

		while (temp != 0) {
				MoveNode(&a , &temp);
				if (temp != 0)
						MoveNode(&b, &temp);
		}
		*aRef = a;
		*bRef = b;
					
}
예제 #11
0
// 11 — MoveNode()
void MoveNodeTest() {
	struct node* a = BuildOneTwoThree(); // the list {1, 2, 3}
	struct node* b = BuildOneTwoThree();
	MoveNode(&a, &b);
	// a == {1, 1, 2, 3}
	// b == {2, 3}
}
예제 #12
0
static void Reverse2(struct node** headRef) {
	struct node* result = NULL;
	struct node* current = *headRef;
	while (current != NULL) {
		MoveNode(&result, &current);
	}
	*headRef = result;
}
예제 #13
0
파일: test.cpp 프로젝트: irenams/IrenaSt
void MoveNodeTest() {
	struct node* a = BuildOneTwoThree(); 
	struct node* b = BuildOneTwoThree();
	display(a);
	display(b);
	MoveNode(&a, &b);
	display(a);
	display(b);
}
예제 #14
0
void AlternatingSplit2(struct node* source,
struct node** aRef, struct node** bRef) {
	struct node aDummy;
	struct node* aTail = &aDummy; // points to the last node in 'a'
	struct node bDummy;
	struct node* bTail = &bDummy; // points to the last node in 'b'
	struct node* current = source;
	aDummy.next = NULL;
	bDummy.next = NULL;
	while (current != NULL) {
		MoveNode(&(aTail->next), &current); // add at 'a' tail
		aTail = aTail->next; // advance the 'a' tail
		if (current != NULL) {
			MoveNode(&(bTail->next), &current);
			bTail = bTail->next;
		}
	}
	*aRef = aDummy.next;
	*bRef = bDummy.next;
}
예제 #15
0
// SuffleMerge() — Local References
// Uses a local reference to get rid of the dummy nodes entirely.
struct node* ShuffleMerge3(struct node* a, struct node* b) {
	struct node* result = NULL;
	struct node** lastPtrRef = &result;
	while (1) {
		if (a==NULL) {
			*lastPtrRef = b;
			break;
		}
		else if (b==NULL) {
			*lastPtrRef = a;
			break;
		}
		else {
			MoveNode(lastPtrRef, &a);
			lastPtrRef = &((*lastPtrRef)->next);
			MoveNode(lastPtrRef, &b);
			lastPtrRef = &((*lastPtrRef)->next);
		}
	}
	return(result);
}
예제 #16
0
void AlternatingSplit2(struct node* source, struct node** aRef, struct node** bRef){
    struct node dummy_a;
    struct node* pa = &dummy_a;
    struct node dummy_b;
    struct node* pb = &dummy_b;
    struct node* current = source;

    pa->next = NULL;
    pb->next = NULL;
    while(current != NULL){
        MoveNode(&(pa->next), &current);
        pa = pa->next;
        if (current != NULL){
            MoveNode(&(pb->next), &current);
            pb = pb->next;
        }
    }

    *aRef = dummy_a.next;
    *bRef = dummy_b.next;
}
예제 #17
0
// SuffleMerge() — Dummy Node Using MoveNode()
// Basically the same as above, but use MoveNode().
struct node* ShuffleMerge2(struct node* a, struct node* b) {
	struct node dummy;
	struct node* tail = &dummy;
	dummy.next = NULL;
	while (1) {
		if (a==NULL) {
			tail->next = b;
			break;
		}
		else if (b==NULL) {
			tail->next = a;
			break;
		}
		else {
			MoveNode(&(tail->next), &a);
			tail = tail->next;
			MoveNode(&(tail->next), &b);
			tail = tail->next;
		}
	}
	return(dummy.next);
}
예제 #18
0
struct node* SortedMerge(struct node* a, struct node* b)
{
  struct node dummy;
  struct node *head = &dummy;
  dummy.next = NULL;

  while(1)
  {
    print_linked_list("a",&a);
    print_linked_list("b",&b);
    print_linked_list("head",&dummy.next);
    if(a == NULL)
    {
      head->next = b;
      break;
    }

    if(b == NULL)
    {
      head->next = a;
      break;
    }

    if(a->data <= b->data)
    {
      printf("a <= b\n");
      MoveNode(&head->next, &a);
    }
    else
    {
      printf("a > b\n");
      MoveNode(&head->next, &b);
    }

    head = head->next;
  }
  return dummy.next;
}
예제 #19
0
/*----------Sorted Merge------------*/
struct node* SortedMerge(struct node* a, struct node *b){
	struct node* merged = NULL;
	while(( a != NULL) || (b != NULL))
	{
	 if((a != NULL) && (b != NULL))
	  {
	    if(a->data < b->data)
	     MoveNode(&merged, &a);
	    else if(a->data > b->data)
	     MoveNode(&merged, &b);
	    else
	      {
		MoveNode(&merged, &b);
		a = a->next;
	      }
	   }
	   else if(a != NULL)
	       MoveNode(&merged, &a);
	    else if(b != NULL)
	       MoveNode(&merged, &b);
	   }
	return merged;
}
예제 #20
0
struct node* SortedMerge2(struct node* a, struct node* b) {
	struct node* result = NULL;
	struct node** lastPtrRef = &result; // point to the last result pointer
	while (1) {
		if (a==NULL) {
			*lastPtrRef = b;
			break;
		}
		else if (b==NULL) {
			*lastPtrRef = a;
			break;
		}
		if (a->data <= b->data) {
			MoveNode(lastPtrRef, &a);
		}
		else {
			MoveNode(lastPtrRef, &b);
		}
		lastPtrRef = &((*lastPtrRef)->next); // tricky: advance to point to
		// the next ".next" field
	}
	return(result);
}
예제 #21
0
Node* MergeLists(Node *a, Node* b)
{
    /* a dummy first node to hang the result on */   
   Node dummy;      
    
   /* tail points to the last result node  */
  Node* tail = &dummy;  
 
   /* so tail->next is the place to add new nodes 
     to the result. */
   dummy.next = NULL;
   while(1) 
   {
      if(a == NULL) 
      { 
         /* if either list runs out, use the other list */
         tail->next = b;
         break;
      }
      else if (b == NULL) 
      {
         tail->next = a;
         break;
      }
      if (a->data <= b->data) 
      {
         MoveNode(&(tail->next), &a);
      }
      else
     {
        MoveNode(&(tail->next), &b);
     }
     tail = tail->next;
  }
  return(dummy.next);
}
예제 #22
0
/*
 * @func: split the origianal list into two list in alternating way.
          Given the source list, split its nodes into two shorter lists.
	If we number the elements 0, 1, 2, ... then all the even elements
	should go in the first list, and all the odd elements in the second.
	The elements in the new lists may be in any order.
 */
void AlternatingSplit(struct node* source, struct node** aRef, struct node** bRef){
    // here is error case, In order to return the pointer,
    // the address of node must be passed into MoveNode().
    struct node* current = source;
    while (current != NULL){
        MoveNode(bRef, &current);
        if (current->next != NULL){
            MoveNode(aRef, &(source->next));
        }
        current = current->next->next;
    }

    // here is correct version. but, the lists are reverse order.
    struct node* a = NULL;
    struct node* b = NULL;
    while (current != NULL){
        MoveNode(&a, &current);
        if (current != NULL){
            MoveNode(&b, &current);
        }
        *aRef = a;
        *bRef = b;
    }
}
예제 #23
0
struct node* ShuffleMerge(struct node* a, struct node* b)
{

  struct node dummy;
  struct node *head = &dummy;
  dummy.next = NULL;

  while((a != NULL) || (b != NULL))
  {
    if(a != NULL)
    {
      MoveNode(&head->next, &a);
      head = head->next;
    }

    if(b != NULL)
    {
      MoveNode(&head->next, &b);
      head = head->next;
    }
  }

  return dummy.next;
}
void TurretManager::UpdateNodes()
{
	for (int i = nodes.size() - 1; i >= 0; i--)
	{
		auto node = nodes[i];
		node->MoveNode(orbit01Angle, orbit02Angle);
		if (node->GetTrue())
		{
			nodes[i]->AddTag("Construct");
			AddTurretButtons();
			
			//if (node->GetOrbit() == 1)
				//CreateTurret(node->GetOrbitPos() + 1, node->GetOrbit(), node->GetOrbitPos());
			//else
				//CreateTurret(1, node->GetOrbit(), node->GetOrbitPos());

			//RemoveChild(node);
			//nodes.erase(nodes.begin() + i); Not necessary anymore since we can just hide the nodes
			UI = true;
		}
	}
}
예제 #25
0
/**
 * @brief 新たな候補手を一手設定します。
 */
void MoveNodeList::add_move(Move move)
{
    m_nodeList.push_back(MoveNode(move));
}
예제 #26
0
파일: only_deg.c 프로젝트: pkdevbox/rgraph
/*
  ---------------------------------------------------------------------
  Do a Monte Carlo step for the prediction of missing links. Each
  "step" involves nnod independent attempts to move a single node.
  ---------------------------------------------------------------------
*/
void
LSMCStepMB_OD(int factor,
	   double *H,
	   double linC,
	   struct node_gra **nlist,
	   struct group **glist,
	   struct group *part,
	   int nnod,
	   int **G2G,
	   int *n2gList,
	   double **LogChooseList,
	   int LogChooseListSize,
	   double *LogFactList, int LogFactListSize,
	   double *HarmonicList,
	   gsl_rng *gen)
{
  double dH;
  struct group *g, *oldg, *newg;
  int dice, oldgnum, newgnum, n2g, oldg2g, newg2g, ng, noldg, nnewg;
  struct node_gra *node;
  int n2oldg, n2newg, newg2oldg, oldg2oldg, newg2newg;
  int r, l;
  int i, j, ngroup=nnod;
  int move;
  int effectng=0;

  for (move=0; move<nnod*factor; move++) {

    /* Choose node and destination group */
    dice = floor(gsl_rng_uniform(gen) * (double)nnod);
    node = nlist[dice];
    oldgnum = node->inGroup;
    do {
      newgnum = floor(gsl_rng_uniform(gen) * (double)nnod);
    } while (newgnum == oldgnum);
    oldg = glist[oldgnum];
    newg = glist[newgnum];
    
    /* Calculate the change of energy */
    dH = 0.0;
    noldg = oldg->size;
    nnewg = newg->size;
    if (noldg == 1)  /* number of groups would decrease by one */ 
      dH -= linC;
    if (nnewg == 0)  /* number of groups would increase by one */
      dH += linC;
    n2oldg = NLinksToGroup(node, oldg);
    n2newg = NLinksToGroup(node, newg);
    newg2oldg = NG2GLinks(newg, oldg);
    oldg2oldg = oldg->inlinks;
    newg2newg = newg->inlinks;
    g = part;
    effectng = 0;
    while ((g = g->next) != NULL) {
      if (g->size > 0) {  /* group is not empty */
	effectng++;
	n2gList[g->label] = NLinksToGroup(node, g);
	if (g->label == oldg->label) {
	  /* old conf, oldg-oldg */
	  r = noldg * (noldg - 1) / 2;
	  l = oldg2oldg;
	  dH -= log(r + 1) + FastLogChoose(r, l,
					   LogChooseList, LogChooseListSize);
	  /*dH -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* new conf, oldg-oldg */
	  r = (noldg - 1) * (noldg - 2) / 2;
	  l = oldg2oldg - n2oldg;
	  dH += log(r + 1) + FastLogChoose(r, l,
					   LogChooseList, LogChooseListSize);
	  /*dH += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* old conf, newg-oldg */
	  r = nnewg * noldg;
	  l = newg2oldg;
	  dH -= log(r + 1) + FastLogChoose(r, l,
					   LogChooseList, LogChooseListSize);
	  /*dH -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* new conf, newg-oldg */
	  r = (nnewg + 1) * (noldg - 1);
	  l = newg2oldg + n2oldg - n2newg;
	  dH += log(r + 1) + FastLogChoose(r, l,
					   LogChooseList, LogChooseListSize);
	  /*dH += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	}
	else if (g->label == newg->label) {
	  /* old conf, newg-newg */
	  r = nnewg * (nnewg - 1) / 2;
	  l = newg2newg;
	  dH -= log(r + 1) + FastLogChoose(r, l,
					   LogChooseList, LogChooseListSize);
	  /*dH -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* new conf, newg-newg */
	  r = (nnewg + 1) * nnewg / 2;
	  l = newg2newg + n2newg;
	  dH += log(r + 1) + FastLogChoose(r, l,
					   LogChooseList, LogChooseListSize);
	  /*dH += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	}
	else {
	  n2g = n2gList[g->label];
	  oldg2g = G2G[oldg->label][g->label];
	  newg2g = G2G[newg->label][g->label];
	  ng = g->size;
	  /* old conf, oldg-g */
	  r = noldg * ng;
	  l = oldg2g;
	  dH -= log(r + 1) + FastLogChoose(r, l,
					   LogChooseList, LogChooseListSize);
	  /*dH -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* new conf, oldg-g */
	  r = (noldg - 1) * ng;
	  l = oldg2g - n2g;
	  dH += log(r + 1) + FastLogChoose(r, l,
					   LogChooseList, LogChooseListSize);
	  /*dH += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* old conf, newg-g */
	  r = nnewg * ng;
	  l = newg2g;
	  dH -= log(r + 1) + FastLogChoose(r, l,
					   LogChooseList, LogChooseListSize);
	  /*dH -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* new conf, newg-g */
	  r = (nnewg + 1) * ng;
	  l = newg2g + n2g;
	  dH += log(r + 1) + FastLogChoose(r, l,
					   LogChooseList, LogChooseListSize);
	  /*dH += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	}
      }
      else { /* group is empty */
	n2gList[g->label] = 0.0;
      }
    }

    /* Labeled-groups sampling correction */
    if (noldg == 1 && nnewg != 0) { // effectng would decrease by one
      dH -= -FastLogFact(ngroup - effectng, LogFactList, LogFactListSize);
      dH += -FastLogFact(ngroup - (effectng-1), LogFactList, LogFactListSize);
      dH += LogDegeneracy_OD(effectng) - LogDegeneracy_OD(effectng - 1);
    }
    else if (noldg != 1 && nnewg == 0) {  // effectng would increase by one
      dH -= -FastLogFact(ngroup - effectng, LogFactList, LogFactListSize);
      dH += -FastLogFact(ngroup - (effectng+1), LogFactList, LogFactListSize);
      dH += LogDegeneracy_OD(effectng) - LogDegeneracy_OD(effectng + 1);
    }

    /* Metropolis rule */
    if ((dH <= 0.0) || (gsl_rng_uniform(gen) < exp(-dH))) {
      
      /* accept move */
      MoveNode(node, oldg, newg);
      *H += dH;
    
      /* update G2G */
      for (i=0; i<nnod; i++) {
	G2G[i][oldgnum] -= n2gList[i];
	G2G[oldgnum][i] = G2G[i][oldgnum];
	G2G[i][newgnum] += n2gList[i];
	G2G[newgnum][i] = G2G[i][newgnum];
      }
    }
  } /* nnod moves completed: done! */
}
예제 #27
0
파일: only_deg.c 프로젝트: pkdevbox/rgraph
/*
  ---------------------------------------------------------------------
  Do a Gibbs Monte Carlo step for the prediction of missing links.
  ---------------------------------------------------------------------
*/
void
GibbsLinkScoreStepMB_OD(double *H,
		   double linC,
		   struct node_gra **nlist,
		   struct group **glist,
		   struct group *part,
		   int nnod,
		   int **G2G,
		   int *n2gList,
		   double **LogChooseList,
		   int LogChooseListSize,
		   double *LogFactList, int LogFactListSize, double *HarmonicList,	
		   gsl_rng *gen)
{
  double *dH;
  struct group *g, *oldg, *newg;
  int oldgnum, newgnum, n2g, oldg2g, newg2g, ng, noldg, nnewg;
  struct node_gra *node;
  int n2oldg, n2newg, newg2oldg, oldg2oldg, newg2newg;
  int r, l;
  int i, j, ngroup=nnod;
  int move;
  int effectng;
  /* Shortlist of groups. Groups not in this list are empty for
     sure. Note that, during a step, we may have to add groups to this
     list (groups that were initially empty but got filled) but we
     never remove groups from it (even if they loose all their nodes
     during a step). slgXsize is the size of slgX. */
  int *slg=NULL;
  int slgn, slgsize, isinlist;
  int newgn, target;
  double dice, norm, dHempty, cum;
  double Href;
  
  /* Preliminaries */

  dH = allocate_d_vec(nnod);
  slg = allocate_i_vec(nnod);  // Shortlist of groups
  slgsize = 0;
  g = part;
  while ((g=g->next) != NULL)
    if (g->size > 0)
      slg[slgsize++] = g->label;

  /* Steps */
  for (move=0; move<nnod; move++) {
    node = nlist[move];
    oldgnum = node->inGroup;
    oldg = glist[oldgnum];
    norm = 0.0;

    /* Loop over destination groups */
    for (newgn=0; newgn<slgsize; newgn++) {
      newgnum = slg[newgn];
      newg = glist[newgnum];

      if (newgnum != oldgnum) {	
	/* Calculate the change of energy */
	dH[newgnum] = 0.0;
	noldg = oldg->size;
	nnewg = newg->size;
	if (noldg == 1)  /* number of groups would decrease by one */ 
	  dH[newgnum] -= linC;
	if (nnewg == 0)  /* number of groups would increase by one */
	  dH[newgnum] += linC;
	n2oldg = NLinksToGroup(node, oldg);
	n2newg = NLinksToGroup(node, newg);
	newg2oldg = NG2GLinks(newg, oldg);
	oldg2oldg = oldg->inlinks;
	newg2newg = newg->inlinks;
	effectng = 0;
	for (slgn=0; slgn<slgsize; slgn++) {
	  g = glist[slg[slgn]];
	  if (g->size > 0) {  /* group is not empty */
	    effectng++;
	    n2gList[g->label] = NLinksToGroup(node, g);
	    if (g->label == oldg->label) {
	      /* old conf, oldg-oldg */
	      r = noldg * (noldg - 1) / 2;
	      l = oldg2oldg;
	      dH[newgnum] -= log(r + 1) + FastLogChoose(r, l,
							LogChooseList,
							LogChooseListSize);
	      /*dH[newgnum] -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	      /* new conf, oldg-olg */
	      r = (noldg - 1) * (noldg - 2) / 2;
	      l = oldg2oldg - n2oldg;
	      dH[newgnum] += log(r + 1) + FastLogChoose(r, l,
							LogChooseList,
							LogChooseListSize);
	      /*dH[newgnum] += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	      /* old conf, newg-oldg */
	      r = nnewg * noldg;
	      l = newg2oldg;
	      dH[newgnum] -= log(r + 1) + FastLogChoose(r, l,
							LogChooseList,
							LogChooseListSize);
	      /*dH[newgnum] -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	      /* new conf, newg-oldg */
	      r = (nnewg + 1) * (noldg - 1);
	      l = newg2oldg + n2oldg - n2newg;
	      dH[newgnum] += log(r + 1) + FastLogChoose(r, l,
							LogChooseList,
							LogChooseListSize);
	      /*dH[newgnum] += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	    }
	    else if (g->label == newg->label) {
	      /* old conf, newg-newg */
	      r = nnewg * (nnewg - 1) / 2;
	      l = newg2newg;
	      dH[newgnum] -= log(r + 1) + FastLogChoose(r, l,
							LogChooseList,
							LogChooseListSize);
	      /*dH[newgnum] -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	      /* new conf, newg-olg */
	      r = (nnewg + 1) * nnewg / 2;
	      l = newg2newg + n2newg;
	      dH[newgnum] += log(r + 1) + FastLogChoose(r, l,
							LogChooseList,
							LogChooseListSize);
	      /*dH[newgnum] += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	    }
	    else {
	      n2g = n2gList[g->label];
	      oldg2g = G2G[oldg->label][g->label];
	      newg2g = G2G[newg->label][g->label];
	      ng = g->size;
	      /* old conf, oldg-g */
	      r = noldg * ng;
	      l = oldg2g;
	      dH[newgnum] -= log(r + 1) + FastLogChoose(r, l,
							LogChooseList,
							LogChooseListSize);
	      /*dH[newgnum] -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	      /* new conf, oldg-g */
	      r = (noldg - 1) * ng;
	      l = oldg2g - n2g;
	      dH[newgnum] += log(r + 1) + FastLogChoose(r, l,
							LogChooseList,
							LogChooseListSize);
	      /*dH[newgnum] += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	      /* old conf, newg-g */
	      r = nnewg * ng;
	      l = newg2g;
	      dH[newgnum] -= log(r + 1) + FastLogChoose(r, l,
							LogChooseList,
							LogChooseListSize);
	      /*dH[newgnum] -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	      /* new conf, newg-g */
	      r = (nnewg + 1) * ng;
	      l = newg2g + n2g;
	      dH[newgnum] += log(r + 1) + FastLogChoose(r, l,
							LogChooseList,
							LogChooseListSize);
	      /*dH[newgnum] += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	    }
	  }
	  else { /* group is empty */
	    n2gList[g->label] = 0.0;
	  }
	}


	/* Labeled-groups sampling correction */
	if (noldg == 1 && nnewg != 0) { // effectng would decrease by one
	  dH[newgnum] -= -FastLogFact(ngroup - effectng, LogFactList, LogFactListSize);
	  dH[newgnum] += -FastLogFact(ngroup - (effectng-1), LogFactList, LogFactListSize);
	  dH[newgnum] += LogDegeneracy_OD(effectng) - LogDegeneracy_OD(effectng - 1);
	}
	else if (noldg != 1 && nnewg == 0) {  // effectng would increase by one
	  dH[newgnum] -= -FastLogFact(ngroup - effectng, LogFactList, LogFactListSize);
	  dH[newgnum] += -FastLogFact(ngroup - (effectng+1), LogFactList, LogFactListSize);
	  dH[newgnum] += LogDegeneracy_OD(effectng) - LogDegeneracy_OD(effectng + 1);
	}
      }

      else { // oldg and newg are the same: nothing changes
	dH[newgnum] = 0.0;
      }

      norm += exp(-dH[newgnum]);
    }

    /** Calculate the change of energy to go to an empty group **/
    dHempty = 0.0;
    nnewg = 0;
    if (noldg == 1)  /* number of groups would decrease by one */ 
      dHempty -= linC;
    if (nnewg == 0)  /* number of groups would increase by one */
      dHempty += linC;
    n2newg = 0;
    newg2oldg = 0;
    newg2newg = 0;

    for (slgn=0; slgn<slgsize; slgn++) {
      g = glist[slg[slgn]];
      if (g->size > 0) {  /* group is not empty */
	if (g->label == oldg->label) {
	  /* old conf, oldg-oldg */
	  r = noldg * (noldg - 1) / 2;
	  l = oldg2oldg;
	  dHempty -= log(r + 1) + FastLogChoose(r, l,
						LogChooseList,
						LogChooseListSize);
	  /*dHempty -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* new conf, oldg-olg */
	  r = (noldg - 1) * (noldg - 2) / 2;
	  l = oldg2oldg - n2oldg;
	  dHempty += log(r + 1) + FastLogChoose(r, l,
						LogChooseList,
						LogChooseListSize);
	  /*dHempty += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* old conf, newg-oldg */
	  r = nnewg * noldg;
	  l = newg2oldg;
	  dHempty -= log(r + 1) + FastLogChoose(r, l,
						LogChooseList,
						LogChooseListSize);
	  /*dHempty -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* new conf, newg-oldg */
	  r = (nnewg + 1) * (noldg - 1);
	  l = newg2oldg + n2oldg - n2newg;
	  dHempty += log(r + 1) + FastLogChoose(r, l,
						LogChooseList,
						LogChooseListSize);
	  /*dHempty += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	}
	else {
	  n2g = n2gList[g->label];
	  oldg2g = G2G[oldg->label][g->label];
	  newg2g = 0;
	  ng = g->size;
	  /* old conf, oldg-g */
	  r = noldg * ng;
	  l = oldg2g;
	  dHempty -= log(r + 1) + FastLogChoose(r, l,
						LogChooseList,
						LogChooseListSize);
	  /*dHempty -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* new conf, oldg-g */
	  r = (noldg - 1) * ng;
	  l = oldg2g - n2g;
	  dHempty += log(r + 1) + FastLogChoose(r, l,
						LogChooseList,
						LogChooseListSize);
	  /*dHempty += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* old conf, newg-g */
	  r = nnewg * ng;
	  l = newg2g;
	  dHempty -= log(r + 1) + FastLogChoose(r, l,
						LogChooseList,
						LogChooseListSize);
	  /*dHempty -= -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	  /* new conf, newg-g */
	  r = (nnewg + 1) * ng;
	  l = newg2g + n2g;
	  dHempty += log(r + 1) + FastLogChoose(r, l,
						LogChooseList,
						LogChooseListSize);
	  /*dHempty += -log(HarmonicList[r + 1] - HarmonicList[l]);*/
	}
      }
    }

    /* Labeled-groups sampling correction */
    if (noldg == 1 && nnewg != 0) { // effectng would decrease by one
      dHempty -= -FastLogFact(ngroup - effectng, LogFactList, LogFactListSize);
      dHempty += -FastLogFact(ngroup - (effectng-1), LogFactList, LogFactListSize);
      dHempty += LogDegeneracy_OD(effectng) - LogDegeneracy_OD(effectng - 1);
    }
    else if (noldg != 1 && nnewg == 0) {  // effectng would increase by one
      dHempty -= -FastLogFact(ngroup - effectng, LogFactList, LogFactListSize);
      dHempty += -FastLogFact(ngroup - (effectng+1), LogFactList, LogFactListSize);
      dHempty += LogDegeneracy_OD(effectng) - LogDegeneracy_OD(effectng + 1);
    }

    norm += exp(-dHempty) * (double)(nnod - slgsize);
    
    /** CHOOSE THE MOVE **/
    dice = norm * gsl_rng_uniform(gen);

    if (dice > (norm - (double)(nnod - slgsize) * exp(-dHempty))) {
      /* Select an empty group */
      newg = GetEmptyGroup(part);
      newgnum = newg->label;
      dH[newgnum] = dHempty;
    }
    else {
      /* Select group in shortlist */
      target = 0;
      cum = 0.0;
      while (cum < dice) {
	cum += exp(-dH[slg[target++]]);
      }
      newgnum = slg[target - 1];
      newg = glist[newgnum];
    }
    
    /* MAKE THE MOVE AND UPDATE MATRICES */
    MoveNode(node, oldg, newg);
    *H += dH[newgnum];
    
    /* update G2G */
    for (slgn=0; slgn<slgsize; slgn++) {
      G2G[slg[slgn]][oldgnum] -= n2gList[slg[slgn]];
      G2G[oldgnum][slg[slgn]] = G2G[slg[slgn]][oldgnum];
      G2G[slg[slgn]][newgnum] += n2gList[slg[slgn]];
      G2G[newgnum][slg[slgn]] = G2G[slg[slgn]][newgnum];
    }
    
    /* Add newg to shortlist (if it's not there already!) */
    isinlist = 0;
    for (slgn=0; slgn<slgsize; slgn++)
      if (newgnum == slg[slgn])
	isinlist = 1;
    if (isinlist == 0)
      slg[slgsize++] = newgnum;
  }  /* nnod moves completed: done! */

  free_i_vec(slg);
  free_d_vec(dH);
}