Рефетека.ру / Информатика и програм-ие

Реферат: Транспортная задача

Мурманский филиал Петровского Колледжа

Курсовая по дисциплине

«Компьютерное моделирование» на тему

«Транспортная задача»

Выполнил: Ошкин Е.С.

Проверил: Сергеев А.В.

Мурманск

2002г.

Описание Алгоритма программы

ПРОГРАММА НАПИСАНА НА BORLAND С++ версии 3.1

Программа решает Транспортную Задачу (ТЗ) 3 методами:
1. Северо-западным углом
2. Северо-восточным углом
3. Методом минимального элемента в строке.

Программа состоит из функций:
1. Main()
2. Data()
3. Opplan()
4. Sohran()
5. Bas()
6. Kost()
7. Potenzial()
8. Optim()
9. Plmi()
10. Abcikl()
11. Cikl()
12. Prpoisk()
13. Levpoisk()
14. Verpoisk()
15. Nizpoisk()
16. Pr()

Главная функция main() невелика, но в ней происходит обращение функциям, выполняющим определенные действия в процессе решения ТЗ. Здесь следует обратить особое внимание на строку программы if(!z) break; - если бы не она (она показывает, что после очередной проверки базисного плана, если он оптимален, возвращаемое значение из функции optim() равно 0, что приводит к выходу из бесконечного цикла улучшения базисных планов). Иногда возникает ситуация, когда базисная переменная(одна или несколько) равна нулю, и ее следует отличать от других базисных переменных. В матрице matr() такие элементы я пометил как –2. Основные переменные я описал в комментариях в программе.

Функция data() производит ввод данных на ТЗ.

Функция opplan() выполняет задачи по составлению первоначального базисного плана методом северо-заподного угла. В этой функции используются следующие переменные:
Int *matr указатель на матрицу базисных переменных
Int *po указатель на вектор пунктов отправления
Int *pn указатель на вектор пунктов назначения
Int m количество пунктов отправления
Int n количество пунктов назначения

Функция kost() производит вывод суммарной стоимости перевозок по текущему базисному плану. Используются следующие переменные:

Int *matr, m,n;

Int *st указатель на матрицу стоимостей.

Функция potenzial() выполняет подсчет потенциалов.

Использует следующие переменные:

Int *pu указатель на вектор потенциалов строк

Int *pv указатель на вектор потенциалов столбцов

Int matr, m, n, *st;

Первоначально элементы векторов потенциалов *(pu+i) и *(pv+j) заполняются минимальными значениями для целых переменных = 32768, определенных предпроцессорным оператором define MIN – 32768. Далее пологая, что *pu=0, и используя структуру struct poten{…}, элементы векторов потенциалов приобретают свои реальные значения.

Работу этого модуля я бы разделил на эти этапы:

. Выделение памяти под элемент структуры top = (struct poten*)malloc(sizeof(struct poten)); заполнение полей элемента структуры необходимой информацией; установление связей между элементами структуры;

. Вычисление потенциалов строк и столбцов с занесением информации в секторы pu и pv;

. Проверка правильности заполнения векторов pu и pv, т.е. установление не содержат ли элементы этих векторов значения MIN. При необходимости, если существуют такие элементы векторов, производятся дополнительные вычисления;

. Вывод векторов pu и pv;

Функция optim() проверяет план на оптимальность, если он оптимален, то функция отправляет в главную функцию main() значение 0, в противном случае, если он не оптимален, то управление передается функции abcikl() и возврат главной функции main() значение –1. Функция optim() использует переменные:
Int m,n,*pu,*pv, *matr, *st. Цепь строится относительно первой попавшейся графоклетки, для которой ui + vj =cij , а не относительной характеристики.
В ходе решения ТЗ промежуточные базисные планы отличаются от тех, которые я построил, начиная с координат графоклетки с минимальным значением отрицательной характеристики, но врезультате оптимальный план будет тот же.

Функция abcicl() – использует следующие переменные
Int *matr, m, n;
Int *matr2 //указатель на рабочую (изменяемую) матрицу, по началу она является копией оригинальной.
Int ik,jk; // координаты графоклетки, с которой начинает строиться цепь. В этой функции присваивается графоклетки, с которой будет происходить поиск цикла(цепь), значение -1.

Функция cikl() производит поиск относительно графоклетки со значением
–1. Она использует следующие переменные:
Int *matr2, ik, jk;
Int ch; // счетчик количества элементов в массивах *zi и *zj
Int *zi, *zj // указатели на массивы индексов. Хранят индексы элементов matr, подлежащих перераспределению.

Функции prpoisk(), levpoisk(), verpoisk(), nizpoisk()-поиск, соответственно, вправо, влево, вверх, вниз – относительно текущей графоклетки. Поиск происходит в массиве *matr2. Если известна строка, то выполняется поиск столбца, т.е. его индекса, если известен столбец –ищется строка.

Данные функции возвращают координаты столбца или строки найденной графоклетки, либо значение –1, если графоклетка в данном направлении не найденна.

Работа модуля cikl() заключается в следующем:
. Поиск нужного элемента начинается относительно графоклетки, помеченной –1 в матрице matr2 (с координатами ik и jk согласно входным данным) по возможным направлениям (поочередно);
. Если поиск успешен, то поля структуры заполняются информацией, найденный элемент структуры включается в список(работу модуля поддерживает линейный список, в котором хранится информация о ходе поиска цепи), и за основу берется уже эта (текущая) графоклетка матрицы matr2(). Далее процедура поиска повторяется:
. Если поиск на каком-то шага не неуспешен по возможным направлениям, то найденный элемент исключается из списка и за основу берется последний элемент списка (после удаления). В рабочей матрице matr2() «обнуляется» элемент с координатами, который хранил исключенный элемент, что необходимо для того, чтобы исключить повторное обращение к элементу matr2, не входящемму в цепь;
. Поиск цикла (цепи) будет закончен, когда при прохождении по какому-либо направлению мы снова наткнемся на элемент матрицы matr2 со значением –1.

В конце модуля элементы списка, т.е. его поля с координатами, переписываются в векторы zi и zj.

Внешние переменные:
Int m, n, *matr2;

Входные данные:
Int i1, j1 // координаты текущей графоклетки, относительно которой строится цепь.
Выходные данные:

I(j)- координаты строки, столбца, если переменная найдена;

Функция pr(), осуществляет печать текстовых сообщений о ходе поиска в матрице; она вызывается из модуля cikl().

Функция plmi() перераспределяет поставки по цепи, т.е. улучшает план.

Используются следующие переменные:
Int zi,zj;
Int ch,chr; /переменные размерности массивов zi,zj
Int matr /указатель на матрицу базисных переменных
Работа с модулями выполняется в несколько этапов. Если имеется нулевой базисный элемент (помеченный как –2 в матрице matr) и индекс k нечетен для векторов zi,zj, то элементы matr, помеченные, как –1 и –2(новый элемент помеченный как –2 обнуляем), меняются местами, в противном случае(если k четно или нет нулевых базисных элементов в matr) осуществляется:

Нахождение минимального элемента в матрице базисных переменных: min=matr [i][j], где i=zi[k]; j=zj[k]; k-нечетное число;

Перераспределение поставок: a) если k четное число, то matr[i][j] = matr[i][j]+min, где i=zi[k]; j=zj[k]; b)если k нечетное число, то matr[i][j] = matr[i][j]-min, где i=zi[k]; j=zj[k];


Модуль bas() подсчитывает количество ненулевых базисных переменных в матрице matr.

Модуль sohran() находит нулевую базисную переменную в matr и устанавливает её в –2.
Int basper; /количество базисных переменных.

Функция opplan1() построение первоначального плана методом северо- восточного угла, а opplan2()- методом выбора наименьшего элемента в строке.

Ниже приведен текст программы
#include //Подключение стандартных
#include // Библиотек
#include
#include
#include
#define MIN -32768

int *po = NULL; //Указатель на массив пунктов отправления int *pn = NULL; //Указатель на массив пунктов назначения int *st = NULL; //Указатель на матрицу стоимостей int *matr=NULL; //Указатель на матрицу базисных переменных int *matr2 = NULL; //Указатель на рабочую матрицу int n ,m; //Размерность задачи int *pu,*pv; //Указатели на массивы потенциалов int *zj,*zi; // Указатель на массивы индексов int ch=0,ch2=0; //Счетчики
FILE *fpdat; //Указатель на вводной файл int iter=0; //Счетчик итерации
FILE *fil; //Указатель на выводной файл int zen = -1; //Переменная для сохранения стоимости п-на int z = 1; //Флаг для выхода при оптимальном плане int basper;

// void exit(int status);

void data(void)

{ int i,j,t; printf("Введите количество складов: "); scanf("%d",&m); printf("Kolichestvo skladov-----> %d",m); printf("n Введите количество магазинов:n"); scanf("%d",&n); printf("n Kolichestvo magazinov --->%d",n);

//*********** Выделение памяти ****************** if((po=(int*)calloc(m,sizeof(int)))==NULL) abort(); if((pn=(int*)calloc(n,sizeof(int)))==NULL) abort(); if((st=(int*)calloc(n*m,sizeof(int)))==NULL) abort();

printf("Введите элементы матрицы стоимостей: n"); for(i=0;iu))=(top1->b) - *(pv+j); i = (top1->u); top1 ->zn = 0; break;

}

}

}

}
// ********** Продолжение функции подсчета потенциалов *****************

for(;;){ fl = 0; for(top = topnast;top!=NULL;top =top -> next)

{ if((top -> zn) == -1)

{ if(*(pu+(top ->u)) !=MIN)

{

*(pv+(top->v))=(top->b) - *(pu+(top ->u)); fl = 1; top -> zn = 0;

} if(*(pv+(top->v)) !=MIN)

{

*(pu+(top->u))=(top->b) - *(pv+(top->v)); fl=1; top->zn = 0;

}

}

} if(!fl) break;

} printf("n ПОТЕНЦИАЛЫ ПО v:"); fprintf(fil,"n **** ПОТЕНЦИАЛЫ ПО v:"); for(i = 0;ijck = jk; ch++; fprintf(fil,"nnДо Условия while fl3 =%d n",fl3); pr("top2",top2); fprintf(fil,"Весь цикл поиска сейчас начнется, надеюсь -
n что он будет не бесконечный или не бесполезный :( n"); printf("Весь цикл поиска сейчас начнется, надеюсь - n что он будет не бесконечный или не бесполезный :( n"); printf("n t ttpress anykey to contunion"); getch(); while(fl3)

{ fl3=0; fl = 0; if((nst = prpoisk(ik,jk))>=0)

{ fprintf(fil,"nnВнимание!!!n nst = %d n",nst); fprintf(fil,"Ща будет поик идти ему бы...:Point found!n"); printf("И он пошел RIGHT:Point found !nr"); napr = 2; jk = nst; top2->prnapr = 1;

} else if((nstr = nizpoisk(ik,jk))>=0)

{ fprintf(fil,"DOWN: Point found !n"); printf("DOWN: Point found !nr"); napr = 3; ik = nstr; top2->prnapr = 2;

}

else if((nst=levpoisk(ik,jk))>=0)

{ fprintf(fil,"LEFT:Point found !n"); printf("LEFT:Point found !nr"); napr = 4; jk = nst; top2->prnapr = 3;

}

// **************** Prodolzhenie 1 poiska *********************** else if((nstr = verpoisk(ik,jk))>=0)

{ fprintf(fil,"UP:Point found !n"); printf("UP:Point found !nr"); napr = 1; ik = nstr; top2->prnapr = 4;

} else return(-1);

while(!fl || *(matr2+ik*n+jk)!=-1)

{ fl=1; switch(napr)

{ case 1: printf("Search to the right --->"); fprintf(fil,"Search to the right --->"); if((nst = prpoisk(ik,jk))>=0)

{ printf("foundednr"); fprintf(fil,"foundedn"); if((top2=(struct cik*)malloc(sizeof(struct cik)))==NULL) abort(); if(!topnast1) topnast1=top2; else top3 -> next=top2; top3 = top2; top2 -> next = NULL; top2->ick = ik; top2->jck = jk; ch++; top2->prnapr = 1; pr("top2",top2); napr = 2; jk = nst; perpr = perlev = 0;

} // **** IF ******* else

{ fprintf(fil,"Point not found ! Change direction to LEFTn"); napr = 3; perpr = 1;

} break;

//***************** PRODOLZHENIE 2 POISKA
****************************** case 2: printf("Search to the down --->"); fprintf(fil,"Search to the down --->"); if((nstr=nizpoisk(ik,jk))>=0)

{ if((top2=(struct cik*)malloc(sizeof(struct cik))) ==
NULL) abort(); printf("foundednr"); fprintf(fil,"foundedn"); if(!topnast1) topnast1=top2; else top3->next=top2; top3=top2; top2->next=NULL; top2->ick = ik; top2->jck = jk; ch++; top2->prnapr = 2; pr("top2",top2); napr = 3; ik = nstr; perniz=perver=0;

} //**** IF ******** else

{ fprintf(fil,"Point not found ! Change direction to UPn"); napr = 4; perniz = 1;

} break;

case 3: printf("Search to the left -->"); fprintf(fil,"Search to the left -->"); if((nst=levpoisk(ik,jk))>=0)

{ if((top2=(struct cik*)malloc(sizeof(struct cik))) == NULL) abort(); printf("foundednr"); fprintf(fil,"foundedn"); if(!topnast1) topnast1=top2; else top3->next=top2; top3=top2; top2->next=NULL; top2->ick = ik; top2->jck = jk; ch++;

//************ PRODOLZHENIE 3 POISKA ************* top2->prnapr = 3; pr("top2",top2); napr = 4; jk = nst; perlev = perpr = 0;

} // ******* IF ***** else{ fprintf(fil,"Point not found ! Change direction to RIGHTn"); napr = 1; perlev = 1;

} break; case 4: printf("Search to the up --->"); fprintf(fil,"Search to the up --->"); if((nstr=verpoisk(ik,jk))>=0)

{ if((top2=(struct cik*)malloc(sizeof(struct cik)))==NULL) abort(); printf("foundednr"); fprintf(fil,"foundedn"); if(!topnast1) topnast1=top2; else top3->next=top2; top3=top2; top2->next=NULL; top2->ick=ik; top2->jck=jk; ch++; top2->prnapr = 4; pr("top2",top2); napr = 1; ik = nstr; perver = perniz = 0;

} // *****If ************** else

{ fprintf(fil,"Point not found ! Change direction to
DOWNn"); napr = 2; perver = 1;

} break;

} // ************ SWITCH ********************

// ************** PRODOLZHENIE 4 POISKA ******************** if(perlev == 1 && perpr == 1)

{

*(matr2+ik*n+jk) = 0; ik = top3 ->ick; jk = top3 ->jck; napr = top3->prnapr; top3 = topnast1; printf("Zerro 1nr");

for(top2=topnast1;top2->next !=NULL;top2=top2->next) top3 = top2; top3 -> next=NULL; perlev = perpr = 0; // if(ch == 1) if(top2==top3)

{ fl3=1; break;

} else

{ top3->next=NULL; free(top2); ch--; printf("Viynimaem tochky:
(%d,%d)=%dn",ik,jk,*(matr2+ik*n+jk)); fprintf(fil,"Viynimaem tochky:
(%d,%d)=%dn",ik,jk,*(matr2+ik*n+jk)); pr("top2",top2);

} perpr = 0; perlev = 0;

} // IF

if(perver == 1 && perniz == 1)

{

*(matr2+ik*n+jk)=0; printf("Zerro 2nr"); ik=top3->ick; jk = top3->jck; napr = top3->prnapr; top3 = topnast1;

for(top2 = topnast1;top2->next !=NULL;top2=top2-
>next) top3 = top2; perver = perniz = 0; if(top2==top3)

{ fl3=1; break;

} else

{ top3->next = NULL; free(top2); ch--;

// ******* PRODOLZHENIE 5 POISKA ********************* printf("Viynimaem tochky: (%d,%d) =
%dn",ik,jk,*(matr2+ik*n+jk)); fprintf(fil,"Viynimaem tochky: (%d,%d) =
%dn",ik,jk,*(matr2+ik*n+jk));

pr("top2",top2);

} perver = 0; perniz = 0;

} // IF if(ch==0)

{ fl3=1; break;

}

} //while

} //while i=0; if((zi = (int*)calloc(ch,sizeof(int))) == NULL ) abort(); if((zj = (int*)calloc(ch,sizeof(int))) == NULL ) abort(); printf("nr"); ch2 = ch; for(top2 = topnast1;top2 !=NULL;top2 = top2->next)

{

*(zi+i) = top2 ->ick;

*(zj+i) = top2 ->jck; i++;

}

return(0);

} // *********** cikl ****************************

int prpoisk(int i1, int j1)

{ int j;

for(j=j1+1;j=0;j--)

{ if((*(matr2+i1*n+j))!=0) return(j);

} return(-1);

} int verpoisk(int i1,int j1)

{ int i;

for(i=i1-1;i>=0;i--)

{ if((*(matr2+i*n+j1))!=0) return(i);

} return(-1);

}

int nizpoisk(int i1, int j1)

{ int i; for(i = i1+1;iick,ptr->jck); printf("Koordinatiy ytoplennoy tochki : %d and %dnr",ptr-
>ick,ptr->jck); fprintf(fil,"and napravlenie"); printf("Napravlenie"); switch(ptr->prnapr)

{ case 1: fprintf(fil,"Vpravon"); printf("Vpravonr"); break; case 2: fprintf(fil,"Vnizn"); printf("Vniznr"); break; case 3: fprintf(fil,"Vlevon"); printf("Vlevonr"); break; case 4: fprintf(fil,"Vverhn"); printf("Vverhnr"); break; default: fprintf(fil,"Startn"); printf("Startnr"); break;

} fprintf(fil,"WORK MATRIXn"); for(i=0;i

Похожие работы:

  1. • Методы линейного программирования для решения транспортной ...
  2. • Транспортная задача линейного программирования
  3. • Математическая постановка транспортной задачи линейного ...
  4. • Решение транспортных задач
  5. • Транспортная задача
  6. • Транспортная задача линейного программирования
  7. • Решение транспортной задачи линейного ...
  8. • Решение транспортной задачи методом потенциалов
  9. •  ... среди магазинов методами решения транспортной задачи
  10. • Транспортная задача
  11. • Решение задач транспортного типа методом потенциалов
  12. • Транспортная задача с ограничениями возможных ...
  13. • Решение транспортной задачи методом потенциалов
  14. • Решение транспортной задачи
  15. • Решение транспортной задачи в Excel
  16. • Сущность и использование транспортных задач
  17. • Решение транспортной задачи с правильным балансом
  18. • Нахождение опорного плана транспортной задачи
  19. • Регрессионный анализ. Транспортная задача
  20. • Решение транспортной задачи
Рефетека ру refoteka@gmail.com