Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Задача коммивояжера


Автор: Invisible 13.5.2006, 21:29
Доброго времени... дали нам в институте уже давно курсовик , описание зделал а саму программу как делать понятия не имею ... может кто - нибудь объяснить как представить города, как обозначить длину пути и вобще указать связаны эти города или нет ... в интернете нашёл уже написаную программу , там это зделано было в виде таблицы ... если вы хоть что - то знаете об этой задаче очень прошу написать .. и не нада спрашивать хочу ли я что б вы написали её за меня .. отвечаю сразу : не хочу , прошу хотя бы направить ....  

Автор: Dov 13.5.2006, 22:53
Invisible, пойди в раздел АЛГОРИТМЫ и сделай поиск по ключевым словам, наверняка там что-нибудь накопаешь. 

Автор: bsa 14.5.2006, 01:08
Все просто. Представляешь город, как структуру, одно из полей которой содержит список всех примыкающих городов (тех, с которыми есть непосредственная связь) и растояний до них...
Код
struct town;
struct totown {
      struct town * town;        //указатель на город
      int distance;                    //рассояние от текущего города до того, на который указывает ссылка
};

struct town {
      std::string name;                        //название города (например)
      std::list<struct totown> towns;  //список всех городов, с которыми есть непосредственная связь
};
 

Автор: dips 14.5.2006, 07:27
Вот тебе пример решения задачи методом перебора,
тут всё описано, правда на паскале, ну мне в своё
время этого вполне хватило чтоб понять суть 

Автор: bsa 15.5.2006, 15:44
В приведенном примере struct totown - это описатель маршрута до соседнего города, а struct town - это описатель самого города.
Таким образом, каждый город имеет список маршрутов к соседним городам.
 

Автор: Mayk 15.5.2006, 18:51
Нам в универе на первом курсе рассказывали про решение этой задачи методом ветвей и границ. Гугль в помощь, метод не очень сложный.
 
Модератор: перемещено в алгоритмы 

Автор: Invisible 24.5.2006, 22:14
итак, есть конкретное решение на MVC , здача коммивояжера 

Код

/*задача коммивояжёра

Коммивояжёр (бродячий торговец) должен выйти из первого города, посетить по разу
в неизвестном порядке города и вернуться в первый город.
Расстояние между городами известны. В каком порядке следует обходить города,
чтобы замкнутый путь (тур) коммивояжёра был кротчайшим.
Иными словами, коммивояжёр должен обойти все города по кротчайшему пути и
при этом посещая каждый город только один раз.
Расстояния берутся из файла. В файле матрица с произвольными правильными
значениями (т.е. значение не отрицательны и такие, что проход коммивояжёром
всех городов возможен).
Программа ищет путь с помощью метода ветвей и границ.
*/
#include <fstream.h>
const int maxn=100;                //максимум городов
int n,i,s,min,count,found;        //n-количество городов
                                //i-счетчик
                                //s-текущая сумма
                                //min-минимальная сумма
                                //count-счетчик пройденных городов
                                //found-найден ли город
int a[maxn][maxn];                //матрица рассояний
int m[maxn],minm[maxn];            //m-текущий путь
                                //minm-минимальный путь

void _input()                    //ввод данных
{
 ifstream fin("input.txt");     //открыли файл
 fin >> n;                        //считали n
 for (int i=1;i<=n;i++)    
   for (int j=1;j<=n;j++)
    fin >> a[i][j];                //считали матрицу расстояний
}

void _output()                    //вывод данных
{
 ofstream fout("output.txt");   //открыли файл
 if (found)                        //если найден маршрут...
    {
    fout << "Lenght of min path = " << min << endl;
    fout << "Path : ";
    int c=1;                    //номер в порядке обхода городов
    for (int i=1;i<=n;i++)      //пробегаем по всем городам
    {
    int j=1;
    while ((j<=n)&&                //ищем следующий город в порядке обхода    
               (minm[j]!=c)) j++;
    fout << j <<"->";
    c++;
    }
    fout << minm[1] << endl;    //обход завершается первым городом
    }
    else fout << "Path not found!";
}
void search(int x)                //поиск следующего города в порядке 
                                //обхода после города с номером Х
{
if ((count==n)&&                //если просмотрели все города
    (a[x][1]!=0)&&                //из последнего города есть путь в первый город
    (s+a[x][1]<min))            //новая сумма расстояний меньше минимальной суммы
     {
     found=1;                    //маршрут найден
     min=s+a[x][1];                //изменяем: новая минимальная сумма расстояний
     for (int i=1;i<=n;i++)minm[i]=m[i];//изменяем: новый минимальный путь
     }
     else
     {
     for (int i=1;i<=n;i++)     //из текущего города просматриваем все города
    if ((i!=x)&&                //новый город не совпадает с текущим    
        (a[x][i]!=0)&&            //есть прямой путь из x в i
            (m[i]==0)&&            //новый город еще не простотрен
            (s+a[x][i]<min))    //текущая сумма не превышает минимальной
        {
        s+=a[x][i];                //наращиваем сумму
        count++;                //количество просмотренных городав
        m[i]=count;                //отмечаем у нового города новый номер в порядке обхода
        search(i);                //поиск нового города начиная с города i
        m[i]=0;                    //возвращаем все назад
        count--;                //-"-
        s-=a[x][i];                //-"-
        }
     }
}
void run()
{                                //инициализация                                
s=0;
found=0;
min=32767;
for (int i=1;i<=n;i++) m[i]=0;
count=1;
m[1]=count;                        //считаем что поиск начинается с первого города
search(1);                        //считаем что поиск начинается с первого города
}

void main()
{
_input();                        //ввод данных
run();                            //запуск основного алгоритма
_output();                        //вывод результатов
}


пример файла input.txt
Код

4

0    6    1    5
6    0    3    1
1    3    0    2
5    1    2    0
 

Автор: Юля4310 18.5.2009, 16:24
а нельзя эту программу перевести на Delphi? очень очень надо, помогите пожалуйста

Автор: aleksanr 5.6.2009, 16:38
при компиляция данная прога выдает ошибку

 Ошибка    3    error C2872: min: неоднозначный символ


помогите ее исправить пожалуста!!!!!

Автор: n4ela 22.9.2009, 01:22
Я может быть археолог, но в примере выше разве не метод полного перебора?

Автор: maxim1000 22.9.2009, 08:08
думаю, гораздо больше потенциальных помощников перевести на Delphi будет в разделе Delphi, так что с подобными вопросами стоит обратиться туда

то же самое с min - тут лучше обратиться в C++-раздел

Автор: AlexeroN 10.5.2010, 12:32
Про ошибку можно почитать тут http://msdn.microsoft.com/ru-ru/library/t57wswcs.aspx
А я решил проблему элементарно, просто в этом min добавил подчерк, чтоб было _min, и все ок

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)