Нахождение вершин в орграфе - C (СИ)
Формулировка задачи:
Я хочу считать граф из файла и передать его в уже написанную функцию.Но не до конца понял как вообще считывается граф из файла.Подскажите правильно ли я вообще делаю и как должно выглядеть заполнение графа в файле чтобы программа его правильно считывала?
struct edge_struct { int id; //номер узла int in; //номера входящих ребер int out; //номера исходящих ребер int weight; }; int main(){ FILE *edge,*node; int n,i,node_number,edge_number; struct edge_struct *newList; newList = (struct edge_struct *) malloc(sizeof(struct edge_struct)); struct edge_struct edge_item[n]; if(edge=fopen("edge.txt","r")) { fread(&n,sizeof(int),1,edge); struct edge_struct edge_item[n]; edge_number; i=0; while(!eof(edge)) { fread(&n,sizeof(int), 1,edge); edge_item[i].id=n; fread(&n,sizeof(int),1 ,edge); edge_item[i].out=n; fread(&n,sizeof(int),1 ,edge); edge_item[i].in=n; fread(&n,sizeof(int),1 ,edge); edge_item[i].weight=n; } } if(node=fopen("node.txt","r")){ fread(&n,sizeof(int),1,node); struct edge_struct edge_item[n]; node_number=n; } close(edge); close(node); for(i=0;i<n;i++) { scanf("d", newList->in); scanf("d", newList->out); } }
Решение задачи: «Нахождение вершин в орграфе»
textual
Листинг программы
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> struct Arc { int from; //индекс исходящей вершины int to; //индекс входящей вершины double weight; } ; struct Way { bool exist; //существование пути double sumWeight; //суммарный вес int refPrev; //индекс узла, через который проходит путь }; struct Graph { int numNodes; //число вершин int numArcs; //число дуг struct Arc *arcs; //указатель на массив дуг struct Way *pMinWay; //Адрес первого элемента массива и инфрмацией о минималном пути от start до finish //pMinWay[i] минимальная стоимость из i в start }; void FindWay(struct Graph g, int, int); int main(){ FILE *edge; int i, edge_number; struct edge_struct *edge_items; struct edge_item *items; struct Graph *g; edge = fopen("edge.txt", "r"); if (!edge) return 1; fscanf(edge, "%d", &edge_number); g = calloc(edge_number, sizeof(*g)); for (i = 0; i < edge_number; ++i) fscanf(edge, "%d%d%d%d", &g[i].numNodes, &g[i].numArcs); fclose(edge); //ForStep(struct edge_struct *edge_items, struct edge_item *items, int edge_number); free(edge_items); return 0; } // Шаг по дуге ixArc к вершине, смежной с вершиной transit void ForStep(struct Graph g, int ixArc) { int transit = g.arcs[ ixArc ].from; // Транзитная вершина int step = g.arcs[ ixArc ].to; // Смежная вершина int finish = g.arcs[ ixArc ].from; // Транзитная вершина //////////// // Вычисляем новый суммарный вес пути через transit до step double newSumWeight = g.pMinWay[ transit ].sumWeight + g.arcs[ ixArc ].weight; if( !g.pMinWay[ step ].exist ) { // Эта вершина раскрыта впервые g.pMinWay[ step ].exist = true; g.pMinWay[ step ].sumWeight = newSumWeight; g.pMinWay[ step ].refPrev = transit; FindWay( g, step, finish ); } else { // Эта вершина раньше встречалась if( g.pMinWay[ step ].sumWeight > newSumWeight ) { // Новый путь короче g.pMinWay[ step ].sumWeight = newSumWeight; g.pMinWay[ step].refPrev = transit; FindWay( g, step, finish ); ////////////////////////// } // Здесь: прежний путь лучше, то есть дальше искать // нечего, поэтому игнорируем этот шаг } } // Поиск кратчайшего пути от transit до finish void FindWay(struct Graph g, int transit, int finish ) { int ixArc; if( transit == finish ) return; // Находим дуги, исходящие из transit и // выполняем шаг по каждой найденной дуге for( ixArc=0; ixArc < g.numArcs; ixArc++ ) { // Рассматриваем случай орграфа, поэтому анализируем // только исходящую вершину дуги if( g.arcs[ ixArc ].from == transit ) ForStep( g, ixArc ); } return; // Больше путей нет }
Объяснение кода листинга программы
Код решает задачу поиска кратчайшего пути в орграфе. Список действий:
- В функции main() считываются данные из файла
edge.txt
о количестве вершин и дуг в графе. - Выделяется память под массив структур Graph, который будет хранить информацию о графе.
- В функции ForStep() происходит обход графа по одной из дуг. Если вершина еще не посещалась, то она помечается как посещенная, и функция рекурсивно вызывается для этой вершины и следующей по пути. Если вершина уже посещалась, то проверяется, является ли новый путь короче, если да, то обновляется информация о пути, и функция вызывается рекурсивно для этой вершины и следующей.
- В функции FindWay() происходит поиск кратчайшего пути от одной вершины до другой. Если текущая вершина равна целевой, то путь найден и функция прекращает работу. Иначе функция вызывает функцию ForStep() для всех дуг, исходящих из текущей вершины.
- В конце функции FindWay() возвращается значение, что больше путей нет.
- В конце функции main() освобождается память, выделенная под массив структур Graph. Получается, что код реализует алгоритм поиска кратчайшего пути в орграфе.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д