fork download
  1. program TSP_Dynamic_File;
  2.  
  3. uses
  4. SysUtils, Classes;
  5.  
  6. const
  7. MAXN = 5; // Максимальна кількість міст
  8. INF = 1000000000; // Це значення може бути дуже великим
  9.  
  10. // Оголошення нового типу для матриці відстаней
  11. type
  12. TDistanceMatrix = array[0..MAXN-1, 0..MAXN-1] of LongInt; // Змінено на LongInt
  13.  
  14. var
  15. N: Integer; // Фактична кількість міст для розрахунку
  16. N_selected: Integer; // Кількість міст, яку потрібно вибрати з MAXN
  17. dist: TDistanceMatrix; // Використовуємо новий тип
  18. dp: array[0..(1 shl MAXN)-1, 0..MAXN-1] of LongInt; // Змінено на LongInt
  19. path: array[0..(1 shl MAXN)-1, 0..MAXN-1] of Integer; // path зберігає індекси, тому Integer підходить
  20. i, j, mask, last, prevMask: Integer; // prevMask не використовується, можна видалити
  21. cost, bestLast: LongInt; // cost може бути великим, bestLast - індекс, але для універсальності з cost можна залишити LongInt
  22. route: array[0..MAXN] of Integer;
  23. f: TextFile; // Не використовується
  24. s: string; // Не використовується
  25. sl: TStringList; // Не використовується
  26. parts: TStringList; // Не використовується
  27.  
  28. function Min(a, b: LongInt): LongInt; // Змінено на LongInt
  29. begin
  30. if a < b then Min := a else Min := b;
  31. end;
  32.  
  33. // Функція для генерації сталої матриці суміжності
  34. procedure GenerateConstantDistanceMatrix(var distMatrix: TDistanceMatrix; size: Integer);
  35. var
  36. row, col: Integer;
  37. begin
  38. for row := 0 to size-1 do
  39. begin
  40. for col := 0 to size-1 do
  41. begin
  42. if row = col then
  43. distMatrix[row, col] := 0 // Відстань до себе - 0
  44. else
  45. // Приклад генерації: відстань залежить від суми індексів
  46. // Можете змінити цю формулу для різних наборів даних
  47. distMatrix[row, col] := Abs(row - col) * 5 + 10;
  48. // Перевірте, чи не перевищує це значення INF
  49. if distMatrix[row, col] > INF then distMatrix[row,col] := INF; // Обмеження, якщо генерація дає надто великі числа
  50. end;
  51. end;
  52. end;
  53.  
  54. begin
  55. // Встановіть кількість міст, яку потрібно вибрати для розрахунку (<= MAXN)
  56. // Для тестування можна почати з невеликих значень, наприклад 10-15
  57. N_selected := 16;
  58.  
  59. if N_selected > MAXN then
  60. begin
  61. WriteLn('Помилка: N_selected не може бути більшим за MAXN.');
  62. ReadLn;
  63. Exit;
  64. end;
  65.  
  66. N := N_selected;
  67.  
  68. // Виберіть один із способів отримання матриці:
  69. // 1. Зчитати з файлу dist.txt (розкоментуйте цей блок)
  70. (*
  71.   AssignFile(f, 'dist.txt');
  72.   Reset(f);
  73.   sl := TStringList.Create;
  74.   parts := TStringList.Create;
  75.   parts.Delimiter := ' ';
  76.  
  77.   for i := 0 to MAXN-1 do
  78.   begin
  79.   if not Eof(f) then
  80.   begin
  81.   ReadLn(f, s);
  82.   sl.Add(s);
  83.   end
  84.   else
  85.   begin
  86.   sl.Add('');
  87.   for j := 0 to MAXN-1 do
  88.   dist[i,j] := INF;
  89.   end;
  90.   end;
  91.   CloseFile(f);
  92.  
  93.   for i := 0 to MAXN-1 do
  94.   begin
  95.   if i < sl.Count then
  96.   begin
  97.   parts.DelimitedText := sl.Strings[i];
  98.   for j := 0 to MAXN-1 do
  99.   begin
  100.   if j < parts.Count then
  101.   dist[i,j] := StrToInt(parts.Strings[j])
  102.   else
  103.   dist[i,j] := INF;
  104.   end;
  105.   end;
  106.   end;
  107.  
  108.   sl.Free;
  109.   parts.Free;
  110.   *)
  111.  
  112. // 2. Згенерувати за допомогою функції (залишайте розкоментованим для генерації)
  113. GenerateConstantDistanceMatrix(dist, MAXN);
  114.  
  115. // Ініціалізація dp-таблиці
  116. for mask := 0 to (1 shl N)-1 do
  117. for i := 0 to N-1 do
  118. begin
  119. dp[mask, i] := INF;
  120. path[mask, i] := -1;
  121. end;
  122.  
  123. dp[1 shl 0, 0] := 0;
  124.  
  125. // Динамічне програмування по підмножинах
  126. for mask := 0 to (1 shl N)-1 do
  127. for last := 0 to N-1 do
  128. if (mask and (1 shl last)) <> 0 then
  129. begin
  130. for j := 0 to N-1 do
  131. if (mask and (1 shl j)) = 0 then
  132. begin
  133. cost := dp[mask, last] + dist[last, j];
  134. if cost < dp[mask or (1 shl j), j] then
  135. begin
  136. dp[mask or (1 shl j), j] := cost;
  137. path[mask or (1 shl j), j] := last;
  138. end;
  139. end;
  140. end;
  141.  
  142. // Пошук найкоротшого циклу (повернення в місто 0)
  143. cost := INF;
  144. bestLast := -1;
  145. for i := 1 to N-1 do
  146. if dp[(1 shl N)-1, i] + dist[i, 0] < cost then
  147. begin
  148. cost := dp[(1 shl N)-1, i] + dist[i, 0];
  149. bestLast := i;
  150. end;
  151.  
  152. // Виведення мінімальної довжини маршруту
  153. WriteLn('Мінімальна довжина маршруту: ', cost);
  154.  
  155. // Відновлення маршруту
  156. mask := (1 shl N)-1;
  157. i := bestLast;
  158. for j := N-1 downto 0 do
  159. begin
  160. route[j] := i;
  161. i := path[mask, i];
  162. mask := mask xor (1 shl route[j]);
  163. end;
  164. route[N] := 0; // повернення в стартове місто
  165.  
  166. // Виведення маршруту
  167. Write('Маршрут: ');
  168. for i := 0 to N do
  169. begin
  170. Write(route[i], ' ');
  171. end;
  172. WriteLn;
  173.  
  174. ReadLn;
  175. end.
Success #stdin #stdout 0.01s 5320KB
stdin
Standard input is empty
stdout
Помилка: N_selected не може бути більшим за MAXN.