program TSP_Dynamic_File;
uses
SysUtils, Classes;
const
MAXN = 5; // Максимальна кількість міст
INF = 1000000000; // Це значення може бути дуже великим
// Оголошення нового типу для матриці відстаней
type
TDistanceMatrix = array[0..MAXN-1, 0..MAXN-1] of LongInt; // Змінено на LongInt
var
N: Integer; // Фактична кількість міст для розрахунку
N_selected: Integer; // Кількість міст, яку потрібно вибрати з MAXN
dist: TDistanceMatrix; // Використовуємо новий тип
dp: array[0..(1 shl MAXN)-1, 0..MAXN-1] of LongInt; // Змінено на LongInt
path: array[0..(1 shl MAXN)-1, 0..MAXN-1] of Integer; // path зберігає індекси, тому Integer підходить
i, j, mask, last, prevMask: Integer; // prevMask не використовується, можна видалити
cost, bestLast: LongInt; // cost може бути великим, bestLast - індекс, але для універсальності з cost можна залишити LongInt
route: array[0..MAXN] of Integer;
f: TextFile; // Не використовується
s: string; // Не використовується
sl: TStringList; // Не використовується
parts: TStringList; // Не використовується
function Min(a, b: LongInt): LongInt; // Змінено на LongInt
begin
if a < b then Min := a else Min := b;
end;
// Функція для генерації сталої матриці суміжності
procedure GenerateConstantDistanceMatrix(var distMatrix: TDistanceMatrix; size: Integer);
var
row, col: Integer;
begin
for row := 0 to size-1 do
begin
for col := 0 to size-1 do
begin
if row = col then
distMatrix[row, col] := 0 // Відстань до себе - 0
else
// Приклад генерації: відстань залежить від суми індексів
// Можете змінити цю формулу для різних наборів даних
distMatrix[row, col] := Abs(row - col) * 5 + 10;
// Перевірте, чи не перевищує це значення INF
if distMatrix[row, col] > INF then distMatrix[row,col] := INF; // Обмеження, якщо генерація дає надто великі числа
end;
end;
end;
begin
// Встановіть кількість міст, яку потрібно вибрати для розрахунку (<= MAXN)
// Для тестування можна почати з невеликих значень, наприклад 10-15
N_selected := 16;
if N_selected > MAXN then
begin
WriteLn('Помилка: N_selected не може бути більшим за MAXN.');
ReadLn;
Exit;
end;
N := N_selected;
// Виберіть один із способів отримання матриці:
// 1. Зчитати з файлу dist.txt (розкоментуйте цей блок)
(*
AssignFile(f, 'dist.txt');
Reset(f);
sl := TStringList.Create;
parts := TStringList.Create;
parts.Delimiter := ' ';
for i := 0 to MAXN-1 do
begin
if not Eof(f) then
begin
ReadLn(f, s);
sl.Add(s);
end
else
begin
sl.Add('');
for j := 0 to MAXN-1 do
dist[i,j] := INF;
end;
end;
CloseFile(f);
for i := 0 to MAXN-1 do
begin
if i < sl.Count then
begin
parts.DelimitedText := sl.Strings[i];
for j := 0 to MAXN-1 do
begin
if j < parts.Count then
dist[i,j] := StrToInt(parts.Strings[j])
else
dist[i,j] := INF;
end;
end;
end;
sl.Free;
parts.Free;
*)
// 2. Згенерувати за допомогою функції (залишайте розкоментованим для генерації)
GenerateConstantDistanceMatrix(dist, MAXN);
// Ініціалізація dp-таблиці
for mask := 0 to (1 shl N)-1 do
for i := 0 to N-1 do
begin
dp[mask, i] := INF;
path[mask, i] := -1;
end;
dp[1 shl 0, 0] := 0;
// Динамічне програмування по підмножинах
for mask := 0 to (1 shl N)-1 do
for last := 0 to N-1 do
if (mask and (1 shl last)) <> 0 then
begin
for j := 0 to N-1 do
if (mask and (1 shl j)) = 0 then
begin
cost := dp[mask, last] + dist[last, j];
if cost < dp[mask or (1 shl j), j] then
begin
dp[mask or (1 shl j), j] := cost;
path[mask or (1 shl j), j] := last;
end;
end;
end;
// Пошук найкоротшого циклу (повернення в місто 0)
cost := INF;
bestLast := -1;
for i := 1 to N-1 do
if dp[(1 shl N)-1, i] + dist[i, 0] < cost then
begin
cost := dp[(1 shl N)-1, i] + dist[i, 0];
bestLast := i;
end;
// Виведення мінімальної довжини маршруту
WriteLn('Мінімальна довжина маршруту: ', cost);
// Відновлення маршруту
mask := (1 shl N)-1;
i := bestLast;
for j := N-1 downto 0 do
begin
route[j] := i;
i := path[mask, i];
mask := mask xor (1 shl route[j]);
end;
route[N] := 0; // повернення в стартове місто
// Виведення маршруту
Write('Маршрут: ');
for i := 0 to N do
begin
Write(route[i], ' ');
end;
WriteLn;
ReadLn;
end.