Нахождение вершин в орграфе - 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; // Больше путей нет 
}

Объяснение кода листинга программы

Код решает задачу поиска кратчайшего пути в орграфе. Список действий:

  1. В функции main() считываются данные из файла edge.txt о количестве вершин и дуг в графе.
  2. Выделяется память под массив структур Graph, который будет хранить информацию о графе.
  3. В функции ForStep() происходит обход графа по одной из дуг. Если вершина еще не посещалась, то она помечается как посещенная, и функция рекурсивно вызывается для этой вершины и следующей по пути. Если вершина уже посещалась, то проверяется, является ли новый путь короче, если да, то обновляется информация о пути, и функция вызывается рекурсивно для этой вершины и следующей.
  4. В функции FindWay() происходит поиск кратчайшего пути от одной вершины до другой. Если текущая вершина равна целевой, то путь найден и функция прекращает работу. Иначе функция вызывает функцию ForStep() для всех дуг, исходящих из текущей вершины.
  5. В конце функции FindWay() возвращается значение, что больше путей нет.
  6. В конце функции main() освобождается память, выделенная под массив структур Graph. Получается, что код реализует алгоритм поиска кратчайшего пути в орграфе.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 3.857 из 5
Похожие ответы