示例#1
0
/**
 * @name new_search
 *
 * Create and initialize a new search record.
 */
SEARCH_RECORD *Wordrec::new_search(CHUNKS_RECORD *chunks_record,
                                   int num_joints,
                                   BLOB_CHOICE_LIST_VECTOR *best_char_choices,
                                   WERD_CHOICE *best_choice,
                                   WERD_CHOICE *raw_choice,
                                   STATE *state) {
  SEARCH_RECORD *this_search;

  this_search = (SEARCH_RECORD *) memalloc (sizeof (SEARCH_RECORD));

  this_search->open_states = MakeHeap (wordrec_num_seg_states * 20);
  this_search->closed_states = new_hash_table();

  if (state)
    this_search->this_state = new_state (state);
  else
    cprintf ("error: bad initial state in new_search\n");

  this_search->first_state = new_state (this_search->this_state);
  this_search->best_state = new_state (this_search->this_state);

  this_search->best_choice = best_choice;
  this_search->raw_choice = raw_choice;
  this_search->best_char_choices = best_char_choices;

  this_search->num_joints = num_joints;
  this_search->num_states = 0;
  this_search->before_best = 0;
  this_search->segcost_bias = 0;

  return (this_search);
}
示例#2
0
// 堆排序,时间复杂度O(nlogn)
void HeapSort(int a[], int n) {
    MakeHeap(a, n);
    for(int i=n; i>1; --i) {
        swap(a[i], a[1]);
        ShiftDown(a, i-1, 1);
    }
}
示例#3
0
void ReadProblem()
{
    FreeStructures();
    FirstNode = 0;
    C = c = 0;
	/***************************** my code start**************************/
	Name = (char *) malloc(strlen("problem.atsp") + 1);
    Type = (char *) malloc(strlen("ATSP") + 1);
	ProblemType = ATSP;
	DimensionSaved = Dimension = Rp0->VVnum;

	Read_EDGE_WEIGHT_SECTION();
	WeightType = -1;
	Swaps = 0;

    /* Adjust parameters */
    MaxSwaps = Dimension;
    if (MaxCandidates > Dimension - 1)
        MaxCandidates = Dimension - 1;
	if (AscentCandidates > Dimension - 1)
		AscentCandidates = Dimension - 1;
	InitialPeriod = Dimension / 2;
	if (InitialPeriod < 100)
		InitialPeriod = 100;
	
	Excess = 1.0 / Dimension;
	MaxTrials = Dimension;
	MakeHeap(Dimension);
	
    C = C_FUNCTION ;
    D = D_FUNCTION;
    
	MoveFunction Movefun[5] = {Best2OptMove,Best2OptMove,Best3OptMove,Best4OptMove,Best5OptMove};
    BestMove = BestSubsequentMove = Movefun[MoveType-1];
}
示例#4
0
void LKH::LKHAlg::AllocateStructures()
{
	if(!K.get())
		K.reset(new int(0));
    int i, K;

    Free(Heap);
    Free(BestTour);
    Free(BetterTour);
    Free(HTable);
    Free(Rand);
    Free(CacheSig);
    Free(CacheVal);
	T.reset();
    G.reset();
    t.reset();
    p.reset();
    q.reset();
    Free(SwapStack);
    tSaved.reset();

    MakeHeap(Dimension,this);
    assert(BestTour = (int *) calloc(1 + Dimension, sizeof(int)));
    assert(BetterTour = (int *) calloc(1 + Dimension, sizeof(int)));
    assert(HTable = (HashTable *) malloc(sizeof(HashTable)));
    HashInitialize((HashTable *) HTable);
    SRandom(Seed);
    assert(Rand = (unsigned *)
           malloc((Dimension + 1) * sizeof(unsigned)));
    for (i = 1; i <= Dimension; i++)
        Rand[i] = Random();
    SRandom(Seed);
    if (WeightType != EXPLICIT) {
        for (i = 0; (1 << i) < (Dimension << 1); i++);
        i = 1 << i;
        assert(CacheSig = (int *) calloc(i, sizeof(int)));
        assert(CacheVal = (int *) calloc(i, sizeof(int)));
        CacheMask = i - 1;
    }
    AllocateSegments();
    K = MoveType;
    if (SubsequentMoveType > K)
        K = SubsequentMoveType;
	T.reset( new vector<Node *>(1 + 2 * K));
	G.reset(new vector<GainType>(2 * K));
	t.reset(new vector<Node *>(6 * K));
	tSaved.reset(new vector<Node *>(1 + 2 * K));
	p.reset(new vector<int>(6 * K));
	q.reset(new vector<int>(6 * K));
	incl.reset(new vector<int>(6 * K));
	cycle.reset(new vector<int>(6 * K));
    assert(SwapStack =
           (SwapRecord *) malloc((MaxSwaps + 6 * K) * sizeof(SwapRecord)));
}
void AllocateStructures()
{
    int i, K;

    Free(Heap);
    Free(BestTour);
    Free(BetterTour);
    Free(HTable);
    Free(Rand);
    Free(CacheSig);
    Free(CacheVal);
    Free(T);
    Free(G);
    Free(t);
    Free(p);
    Free(q);
    Free(SwapStack);
    Free(tSaved);

    MakeHeap(Dimension);
    assert(BestTour = (int *) calloc(1 + Dimension, sizeof(int)));
    assert(BetterTour = (int *) calloc(1 + Dimension, sizeof(int)));
    assert(HTable = (HashTable *) malloc(sizeof(HashTable)));
    HashInitialize((HashTable *) HTable);
    SRandom(Seed);
    assert(Rand = (unsigned *)
           malloc((Dimension + 1) * sizeof(unsigned)));
    for (i = 1; i <= Dimension; i++)
        Rand[i] = Random();
    SRandom(Seed);
    if (WeightType != EXPLICIT) {
        for (i = 0; (1 << i) < (Dimension << 1); i++);
        i = 1 << i;
        assert(CacheSig = (int *) calloc(i, sizeof(int)));
        assert(CacheVal = (int *) calloc(i, sizeof(int)));
        CacheMask = i - 1;
    }
    AllocateSegments();
    K = MoveType;
    if (SubsequentMoveType > K)
        K = SubsequentMoveType;
    assert(T = (Node **) malloc((1 + 2 * K) * sizeof(Node *)));
    assert(G = (GainType *) malloc(2 * K * sizeof(GainType)));
    assert(t = (Node **) malloc(6 * K * sizeof(Node *)));
    assert(tSaved = (Node **) malloc((1 + 2 * K) * sizeof(Node *)));
    assert(p = (int *) malloc(6 * K * sizeof(int)));
    assert(q = (int *) malloc(6 * K * sizeof(int)));
    assert(incl = (int *) malloc(6 * K * sizeof(int)));
    assert(cycle = (int *) malloc(6 * K * sizeof(int)));
    assert(SwapStack =
           (SwapRecord *) malloc((MaxSwaps + 6 * K) * sizeof(SwapRecord)));
}
示例#6
0
uint
iAuction::UpdateLabeledRows(uint _col_id){
 
  uint cnt=0;
  for(uint i=0; i<row_size; i++)
    if(assignment[i]==_col_id){
      LU.insert(i);
      MakeHeap(i);
      cnt++;
    }

  return cnt;
}
示例#7
0
文件: ft.c 项目: 8l/csolve
Vertices *
MST(Vertices * graph)
{
  HeapP * heap;
  Vertices * vertex;
  Edges * edge;
  ;

  InitFHeap();

  /*
   * key(s) = 0;
   * key(v) = infty for v != s;
   * init heap;
   * make a heap;
   * put s in heap;
   */
  vertex = graph;
  KEY(vertex) = 0;
  heap = MakeHeap();
  (void)Insert(&heap, (Item *)vertex);

  vertex = NEXT_VERTEX(vertex);
  while(vertex != graph)
  {
    KEY(vertex) = PLUS_INFINITY;
    vertex = NEXT_VERTEX(vertex);
  }
  while(vertex != graph);

  vertex = FindMin(heap);
  while(vertex != NULL_VERTEX)
  {
    heap = DeleteMin(heap);
    KEY(vertex) = MINUS_INFINITY;
    edge = EDGES(vertex);
    while(edge != NULL_EDGE)
    {
      if(WEIGHT(edge) < KEY(VERTEX(edge)))
      {
        KEY(VERTEX(edge)) = WEIGHT(edge);
        CHOSEN_EDGE(VERTEX(edge)) = edge;
        (void)Insert(&heap, VERTEX(edge));
      }
      edge = NEXT_EDGE(edge);
    }
    vertex = FindMin(heap);
  }
  ;
  return(graph);
}
示例#8
0
void HeapSort(int* arr, int size)
{
	Heap* heap = MakeHeap(arr, size);

	BuildMaxHeap(heap);

	for (int i = size; i > 0; --i)
	{
		arr[i - 1] = heap->element[1];

		heap->element[1] = heap->element[heap->size];
		heap->size = heap->size - 1;

		MaxHeapify(heap, 1);
	}
}
示例#9
0
void init(){
	FreeStructures();
	FirstNode = 0;
	WeightType = EXPLICIT;

	WeightFormat = FULL_MATRIX;
	ProblemType = ATSP;

	CoordType = NO_COORDS;
//	Name = "Unnamed";
	Type = EdgeWeightType = EdgeWeightFormat = 0;
	EdgeDataFormat = NodeCoordType = DisplayDataType = 0;
	Distance = 0;
	C = 0;
	c = 0;


	Distance = Distance_EXPLICIT;

	DimensionSaved = Dimension = TSP_N;
	init_graph();




	Swaps = 0;

	/* Adjust parameters */
	if (Seed == 0)
		Seed = (unsigned)time(0);
	if (Precision == 0)
		Precision = 100;
	if (InitialStepSize == 0)
		InitialStepSize = 1;
	if (MaxSwaps < 0)
		MaxSwaps = Dimension;
	if (KickType > Dimension / 2)
		KickType = Dimension / 2;

	if (Runs == 0)
		Runs = 10;

	if (MaxCandidates > Dimension - 1)
		MaxCandidates = Dimension - 1;
	if (ExtraCandidates > Dimension - 1)
		ExtraCandidates = Dimension - 1;
	if (SubproblemSize >= Dimension)
		SubproblemSize = Dimension;
	else if (SubproblemSize == 0) {
		if (AscentCandidates > Dimension - 1)
			AscentCandidates = Dimension - 1;
		if (InitialPeriod < 0) {
			InitialPeriod = Dimension / 2;
			if (InitialPeriod < 100)
				InitialPeriod = 100;
		}
		if (Excess < 0)
			Excess = 1.0 / Dimension;
		if (MaxTrials == -1)
			MaxTrials = Dimension;
		MakeHeap(Dimension);
	}

	if (CostMatrix == 0 && Dimension <= MaxMatrixDimension && Distance != 0
		&& Distance != Distance_1 && Distance != Distance_ATSP) {
		Node *Ni, *Nj;
		assert(CostMatrix =
			(int *)calloc((size_t)Dimension * (Dimension - 1) / 2,
			sizeof(int)));
		Ni = FirstNode->Suc;
		do {
			Ni->C =
				&CostMatrix[(size_t)(Ni->Id - 1) * (Ni->Id - 2) / 2] - 1;
			if (ProblemType != HPP || Ni->Id < Dimension)
			for (Nj = FirstNode; Nj != Ni; Nj = Nj->Suc)
				Ni->C[Nj->Id] = Fixed(Ni, Nj) ? 0 : Distance(Ni, Nj);
			else
			for (Nj = FirstNode; Nj != Ni; Nj = Nj->Suc)
				Ni->C[Nj->Id] = 0;
		} while ((Ni = Ni->Suc) != FirstNode);
		WeightType = EXPLICIT;
		c = 0;
	}


	if (Precision > 1 && (WeightType == EXPLICIT || ProblemType == ATSP)) {
		int j, n = ProblemType == ATSP ? Dimension / 2 : Dimension;
		for (int i = 2; i <= n; i++) {
			Node *N = &NodeSet[i];
			for (j = 1; j < i; j++)
			if (N->C[j] * Precision / Precision != N->C[j])
			{
				printf("PRECISION (= %d) is too large", Precision);
				system("pause");
			}

		}
	}



	C = WeightType == EXPLICIT ? C_EXPLICIT : C_FUNCTION;
	D = WeightType == EXPLICIT ? D_EXPLICIT : D_FUNCTION;
	if (SubsequentMoveType == 0)
		SubsequentMoveType = MoveType;
	int K = MoveType >= SubsequentMoveType
		|| !SubsequentPatching ? MoveType : SubsequentMoveType;
	if (PatchingC > K)
		PatchingC = K;
	if (PatchingA > 1 && PatchingA >= PatchingC)
		PatchingA = PatchingC > 2 ? PatchingC - 1 : 1;
	if (NonsequentialMoveType == -1 ||
		NonsequentialMoveType > K + PatchingC + PatchingA - 1)
		NonsequentialMoveType = K + PatchingC + PatchingA - 1;
	if (PatchingC >= 1 && NonsequentialMoveType >= 4) {
		BestMove = BestSubsequentMove = BestKOptMove;
		if (!SubsequentPatching && SubsequentMoveType <= 5) {
			MoveFunction BestOptMove[] =
			{ 0, 0, Best2OptMove, Best3OptMove,
			Best4OptMove, Best5OptMove
			};
			BestSubsequentMove = BestOptMove[SubsequentMoveType];
		}
	}
	else {
		MoveFunction BestOptMove[] = { 0, 0, Best2OptMove, Best3OptMove,
			Best4OptMove, Best5OptMove
		};
		BestMove = MoveType <= 5 ? BestOptMove[MoveType] : BestKOptMove;
		BestSubsequentMove = SubsequentMoveType <= 5 ?
			BestOptMove[SubsequentMoveType] : BestKOptMove;
	}
	if (ProblemType == HCP || ProblemType == HPP)
		MaxCandidates = 0;
	//if (TraceLevel >= 1) {
	//	printff("done\n");
	//	PrintParameters();
	//}





}
示例#10
0
void Wordrec::SegSearch(CHUNKS_RECORD *chunks_record,
                        WERD_CHOICE *best_choice,
                        BLOB_CHOICE_LIST_VECTOR *best_char_choices,
                        WERD_CHOICE *raw_choice,
                        STATE *output_best_state) {
  int row, col = 0;
  if (segsearch_debug_level > 0) {
    tprintf("Starting SegSearch on ratings matrix:\n");
    chunks_record->ratings->print(getDict().getUnicharset());
  }
  // Start with a fresh best_choice since rating adjustments
  // used by the chopper and the new segmentation search are not compatible.
  best_choice->set_rating(WERD_CHOICE::kBadRating);
  // Clear best choice accumulator (that is used for adaption), so that
  // choices adjusted by chopper do not interfere with the results from the
  // segmentation search.
  getDict().ClearBestChoiceAccum();

  MATRIX *ratings = chunks_record->ratings;
  // Priority queue containing pain points generated by the language model
  // The priority is set by the language model components, adjustments like
  // seam cost and width priority are factored into the priority.
  HEAP *pain_points = MakeHeap(segsearch_max_pain_points);

  // best_path_by_column records the lowest cost path found so far for each
  // column of the chunks_record->ratings matrix over all the rows.
  BestPathByColumn *best_path_by_column =
    new BestPathByColumn[ratings->dimension()];
  for (col = 0; col < ratings->dimension(); ++col) {
    best_path_by_column[col].avg_cost = WERD_CHOICE::kBadRating;
    best_path_by_column[col].best_vse = NULL;
  }

  language_model_->InitForWord(prev_word_best_choice_, &denorm_,
                               assume_fixed_pitch_char_segment,
                               best_choice->certainty(),
                               segsearch_max_char_wh_ratio,
                               pain_points, chunks_record);

  MATRIX_COORD *pain_point;
  float pain_point_priority;
  BestChoiceBundle best_choice_bundle(
      output_best_state, best_choice, raw_choice, best_char_choices);

  // pending[i] stores a list of the parent/child pair of BLOB_CHOICE_LISTs,
  // where i is the column of the child. Initially all the classified entries
  // in the ratings matrix from column 0 (with parent NULL) are inserted into
  // pending[0]. As the language model state is updated, new child/parent
  // pairs are inserted into the lists. Next, the entries in pending[1] are
  // considered, and so on. It is important that during the update the
  // children are considered in the non-decreasing order of their column, since
  // this guarantess that all the parents would be up to date before an update
  // of a child is done.
  SEG_SEARCH_PENDING_LIST *pending =
    new SEG_SEARCH_PENDING_LIST[ratings->dimension()];

  // Search for the ratings matrix for the initial best path.
  for (row = 0; row < ratings->dimension(); ++row) {
    if (ratings->get(0, row) != NOT_CLASSIFIED) {
      pending[0].add_sorted(
          SEG_SEARCH_PENDING::compare, true,
          new SEG_SEARCH_PENDING(row, NULL, LanguageModel::kAllChangedFlag));
    }
  }
  UpdateSegSearchNodes(0, &pending, &best_path_by_column, chunks_record,
                       pain_points, &best_choice_bundle);

  // Keep trying to find a better path by fixing the "pain points".
  int num_futile_classifications = 0;
  while (!(language_model_->AcceptableChoiceFound() ||
           num_futile_classifications >=
           segsearch_max_futile_classifications)) {
    // Get the next valid "pain point".
    int pop;
    while (true) {
      pop = HeapPop(pain_points, &pain_point_priority, &pain_point);
      if (pop == EMPTY) break;
      if (pain_point->Valid(*ratings) &&
        ratings->get(pain_point->col, pain_point->row) == NOT_CLASSIFIED) {
        break;
      } else {
        delete pain_point;
      }
    }
    if (pop == EMPTY) {
      if (segsearch_debug_level > 0) tprintf("Pain points queue is empty\n");
      break;
    }
    if (segsearch_debug_level > 0) {
      tprintf("Classifying pain point priority=%.4f, col=%d, row=%d\n",
              pain_point_priority, pain_point->col, pain_point->row);
    }
    BLOB_CHOICE_LIST *classified = classify_piece(
        chunks_record->chunks, chunks_record->splits,
        pain_point->col, pain_point->row);
    ratings->put(pain_point->col, pain_point->row, classified);

    if (segsearch_debug_level > 0) {
      print_ratings_list("Updated ratings matrix with a new entry:",
                         ratings->get(pain_point->col, pain_point->row),
                         getDict().getUnicharset());
      chunks_record->ratings->print(getDict().getUnicharset());
    }

    // Insert initial "pain points" to join the newly classified blob
    // with its left and right neighbors.
    if (!classified->empty()) {
      float worst_piece_cert;
      bool fragmented;
      if (pain_point->col > 0) {
        language_model_->GetWorstPieceCertainty(
            pain_point->col-1, pain_point->row, chunks_record->ratings,
            &worst_piece_cert, &fragmented);
        language_model_->GeneratePainPoint(
            pain_point->col-1, pain_point->row, false,
            LanguageModel::kInitialPainPointPriorityAdjustment,
            worst_piece_cert, fragmented, best_choice->certainty(),
            segsearch_max_char_wh_ratio, NULL, NULL,
            chunks_record, pain_points);
      }
      if (pain_point->row+1 < ratings->dimension()) {
        language_model_->GetWorstPieceCertainty(
            pain_point->col, pain_point->row+1, chunks_record->ratings,
            &worst_piece_cert, &fragmented);
        language_model_->GeneratePainPoint(
            pain_point->col, pain_point->row+1, true,
            LanguageModel::kInitialPainPointPriorityAdjustment,
            worst_piece_cert, fragmented, best_choice->certainty(),
            segsearch_max_char_wh_ratio, NULL, NULL,
            chunks_record, pain_points);
      }
    }

    // Record a pending entry with the pain_point and each of its parents.
    int parent_row = pain_point->col - 1;
    if (parent_row < 0) {  // this node has no parents
      pending[pain_point->col].add_sorted(
          SEG_SEARCH_PENDING::compare, true,
          new SEG_SEARCH_PENDING(pain_point->row, NULL,
                                 LanguageModel::kAllChangedFlag));
    } else {
      for (int parent_col = 0; parent_col < pain_point->col; ++parent_col) {
        if (ratings->get(parent_col, parent_row) != NOT_CLASSIFIED) {
          pending[pain_point->col].add_sorted(
              SEG_SEARCH_PENDING::compare, true,
              new SEG_SEARCH_PENDING(pain_point->row,
                                     ratings->get(parent_col, parent_row),
                                     LanguageModel::kAllChangedFlag));
        }
      }
    }
    UpdateSegSearchNodes(pain_point->col, &pending, &best_path_by_column,
                         chunks_record, pain_points, &best_choice_bundle);
    if (!best_choice_bundle.updated) ++num_futile_classifications;

    if (segsearch_debug_level > 0) {
      tprintf("num_futile_classifications %d\n", num_futile_classifications);
    }

    // Clean up
    best_choice_bundle.updated = false;
    delete pain_point;  // done using this pain point
  }

  if (segsearch_debug_level > 0) {
    tprintf("Done with SegSearch (AcceptableChoiceFound: %d\n",
            language_model_->AcceptableChoiceFound());
  }

  // Clean up.
  FreeHeapData(pain_points, MATRIX_COORD::Delete);
  delete[] best_path_by_column;
  delete[] pending;
  for (row = 0; row < ratings->dimension(); ++row) {
    for (col = 0; col <= row; ++col) {
      BLOB_CHOICE_LIST *rating = ratings->get(col, row);
      if (rating != NOT_CLASSIFIED) language_model_->DeleteState(rating);
    }
  }
}
示例#11
0
void ReadProblem()
{
    int i, K;
    char *Line, *Keyword;

    if (!(ProblemFile = fopen(ProblemFileName, "r")))
        eprintf("Cannot open PROBLEM_FILE: \"%s\"", ProblemFileName);
    if (TraceLevel >= 1)
        printff("Reading PROBLEM_FILE: \"%s\" ... ", ProblemFileName);
    FreeStructures();
    FirstNode = 0;
    WeightType = WeightFormat = ProblemType = -1;
    CoordType = NO_COORDS;
    Name = Copy("Unnamed");
    Type = EdgeWeightType = EdgeWeightFormat = 0;
    EdgeDataFormat = NodeCoordType = DisplayDataType = 0;
    Distance = 0;
    C = 0;
    c = 0;
    while ((Line = ReadLine(ProblemFile))) {
        if (!(Keyword = strtok(Line, Delimiters)))
            continue;
        for (i = 0; i < (int) strlen(Keyword); i++)
            Keyword[i] = (char) toupper(Keyword[i]);
        if (!strcmp(Keyword, "COMMENT"));
        else if (!strcmp(Keyword, "DEMAND_SECTION"))
            eprintf("Not implemented: %s", Keyword);
        else if (!strcmp(Keyword, "DEPOT_SECTION"))
            eprintf("Not implemented: %s", Keyword);
        else if (!strcmp(Keyword, "DIMENSION"))
            Read_DIMENSION();
        else if (!strcmp(Keyword, "DISPLAY_DATA_SECTION"))
            Read_DISPLAY_DATA_SECTION();
        else if (!strcmp(Keyword, "DISPLAY_DATA_TYPE"))
            Read_DISPLAY_DATA_TYPE();
        else if (!strcmp(Keyword, "EDGE_DATA_FORMAT"))
            Read_EDGE_DATA_FORMAT();
        else if (!strcmp(Keyword, "EDGE_DATA_SECTION"))
            Read_EDGE_DATA_SECTION();
        else if (!strcmp(Keyword, "EDGE_WEIGHT_FORMAT"))
            Read_EDGE_WEIGHT_FORMAT();
        else if (!strcmp(Keyword, "EDGE_WEIGHT_SECTION"))
            Read_EDGE_WEIGHT_SECTION();
        else if (!strcmp(Keyword, "EDGE_WEIGHT_TYPE"))
            Read_EDGE_WEIGHT_TYPE();
        else if (!strcmp(Keyword, "EOF"))
            break;
        else if (!strcmp(Keyword, "FIXED_EDGES_SECTION"))
            Read_FIXED_EDGES_SECTION();
        else if (!strcmp(Keyword, "NAME"))
            Read_NAME();
        else if (!strcmp(Keyword, "NODE_COORD_SECTION"))
            Read_NODE_COORD_SECTION();
        else if (!strcmp(Keyword, "NODE_COORD_TYPE"))
            Read_NODE_COORD_TYPE();
        else if (!strcmp(Keyword, "TOUR_SECTION"))
            Read_TOUR_SECTION(&ProblemFile);
        else if (!strcmp(Keyword, "TYPE"))
            Read_TYPE();
        else
            eprintf("Unknown keyword: %s", Keyword);
    }
    Swaps = 0;

    /* Adjust parameters */
    if (Seed == 0)
        Seed = (unsigned) time(0);
    if (Precision == 0)
        Precision = 100;
    if (InitialStepSize == 0)
        InitialStepSize = 1;
    if (MaxSwaps < 0)
        MaxSwaps = Dimension;
    if (KickType > Dimension / 2)
        KickType = Dimension / 2;
    if (Runs == 0)
        Runs = 10;
    if (MaxCandidates > Dimension - 1)
        MaxCandidates = Dimension - 1;
    if (ExtraCandidates > Dimension - 1)
        ExtraCandidates = Dimension - 1;
    if (SubproblemSize >= Dimension)
        SubproblemSize = Dimension;
    else if (SubproblemSize == 0) {
        if (AscentCandidates > Dimension - 1)
            AscentCandidates = Dimension - 1;
        if (InitialPeriod < 0) {
            InitialPeriod = Dimension / 2;
            if (InitialPeriod < 100)
                InitialPeriod = 100;
        }
        if (Excess < 0)
            Excess = 1.0 / Dimension;
        if (MaxTrials == -1)
            MaxTrials = Dimension;
        MakeHeap(Dimension);
    }
    if (CostMatrix == 0 && Dimension <= MaxMatrixDimension && 
        Distance != 0 && Distance != Distance_1 && 
        Distance != Distance_ATSP && Distance != Distance_SPECIAL) {
        Node *Ni, *Nj;
        assert(CostMatrix =
               (int *) calloc((size_t) Dimension * (Dimension - 1) / 2,
                              sizeof(int)));
        Ni = FirstNode->Suc;
        do {
            Ni->C =
                &CostMatrix[(size_t) (Ni->Id - 1) * (Ni->Id - 2) / 2] - 1;
            if (ProblemType != HPP || Ni->Id < Dimension)
                for (Nj = FirstNode; Nj != Ni; Nj = Nj->Suc)
                    Ni->C[Nj->Id] = Fixed(Ni, Nj) ? 0 : Distance(Ni, Nj);
            else
                for (Nj = FirstNode; Nj != Ni; Nj = Nj->Suc)
                    Ni->C[Nj->Id] = 0;
        }
        while ((Ni = Ni->Suc) != FirstNode);
        WeightType = EXPLICIT;
        c = 0;
    }
    if (Precision > 1 && (WeightType == EXPLICIT || ProblemType == ATSP)) {
        int j, n = ProblemType == ATSP ? Dimension / 2 : Dimension;
        for (i = 2; i <= n; i++) {
            Node *N = &NodeSet[i];
            for (j = 1; j < i; j++)
                if (N->C[j] * Precision / Precision != N->C[j])
                    eprintf("PRECISION (= %d) is too large", Precision);
        }
    }
    C = WeightType == EXPLICIT ? C_EXPLICIT : C_FUNCTION;
    D = WeightType == EXPLICIT ? D_EXPLICIT : D_FUNCTION;
    if (SubsequentMoveType == 0)
        SubsequentMoveType = MoveType;
    K = MoveType >= SubsequentMoveType
        || !SubsequentPatching ? MoveType : SubsequentMoveType;
    if (PatchingC > K)
        PatchingC = K;
    if (PatchingA > 1 && PatchingA >= PatchingC)
        PatchingA = PatchingC > 2 ? PatchingC - 1 : 1;
    if (NonsequentialMoveType == -1 ||
        NonsequentialMoveType > K + PatchingC + PatchingA - 1)
        NonsequentialMoveType = K + PatchingC + PatchingA - 1;
    if (PatchingC >= 1 && NonsequentialMoveType >= 4) {
        BestMove = BestSubsequentMove = BestKOptMove;
        if (!SubsequentPatching && SubsequentMoveType <= 5) {
            MoveFunction BestOptMove[] =
                { 0, 0, Best2OptMove, Best3OptMove,
                Best4OptMove, Best5OptMove
            };
            BestSubsequentMove = BestOptMove[SubsequentMoveType];
        }
    } else {
        MoveFunction BestOptMove[] = { 0, 0, Best2OptMove, Best3OptMove,
            Best4OptMove, Best5OptMove
        };
        BestMove = MoveType <= 5 ? BestOptMove[MoveType] : BestKOptMove;
        BestSubsequentMove = SubsequentMoveType <= 5 ?
            BestOptMove[SubsequentMoveType] : BestKOptMove;
    }
    if (ProblemType == HCP || ProblemType == HPP)
        MaxCandidates = 0;
    if (TraceLevel >= 1) {
        printff("done\n");
        PrintParameters();
    } else
        printff("PROBLEM_FILE = %s\n",
                ProblemFileName ? ProblemFileName : "");
    fclose(ProblemFile);
    if (InitialTourFileName)
        ReadTour(InitialTourFileName, &InitialTourFile);
    if (InputTourFileName)
        ReadTour(InputTourFileName, &InputTourFile);
    if (SubproblemTourFileName && SubproblemSize > 0)
        ReadTour(SubproblemTourFileName, &SubproblemTourFile);
    if (MergeTourFiles >= 1) {
        free(MergeTourFile);
        assert(MergeTourFile =
               (FILE **) malloc(MergeTourFiles * sizeof(FILE *)));
        for (i = 0; i < MergeTourFiles; i++)
            ReadTour(MergeTourFileName[i], &MergeTourFile[i]);
    }
    free(LastLine);
    LastLine = 0;
}