Advertisement
Guest User

Stanisław Strzelecki - kod

a guest
Jun 18th, 2019
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.03 KB | None | 0 0
  1. #include "graph.h"
  2. #include "heap.h"
  3. #include "memory.h"
  4.  
  5. #include <stdint.h>
  6. #include <stdbool.h>
  7. #include <stdlib.h>
  8.  
  9. typedef struct Edge Edge;
  10.  
  11. typedef struct Vertex Vertex;
  12.  
  13. typedef struct Graph Graph;
  14.  
  15. /**
  16.  * Struktura przechowująca wierzchołek grafu.
  17.  */
  18. struct Vertex
  19. {
  20.     List *edges;
  21.     bool allowed;
  22.     bool visited;
  23.     Distance distance;
  24.     Edge *from;
  25.     String name;
  26. };
  27.  
  28. /**
  29.  * Struktura przechowująca krawędź grafu.
  30.  */
  31. struct Edge
  32. {
  33.     Vertex *to;
  34.     uint32_t length;
  35.     int32_t year;
  36.     bool active;
  37.     Edge *opposite;
  38.     void *placeInList;
  39. };
  40.  
  41. /**
  42.  * Struktura przechowująca graf.
  43.  */
  44. struct Graph
  45. {
  46.     List *vertexes;
  47.     List *emptyList;
  48.     int32_t size;
  49.     int32_t edgeSize;
  50. };
  51.  
  52. Edge *makeEdge(Vertex *to, uint32_t length, int32_t year)
  53. {
  54.     Edge *edge = allocMisc(sizeof(Edge));
  55.     edge->to = to;
  56.     edge->length = length;
  57.     edge->year = year;
  58.     edge->active = true;
  59.     return edge;
  60. }
  61.  
  62.  
  63. Graph *newGraph()
  64. {
  65.     Graph *graph = allocMisc(sizeof(Graph));
  66.     if (!graph)
  67.         return graph;
  68.     graph->vertexes = newList();
  69.     graph->emptyList = newList();
  70.     graph->size = 0;
  71.     graph->edgeSize = 0;
  72.  
  73.     if (!graph->vertexes || !graph->emptyList)
  74.     {
  75.         if (graph->vertexes)
  76.             removeList(graph->vertexes);
  77.         if (graph->emptyList)
  78.             removeList(graph->emptyList);
  79.         freeMemory(graph);
  80.         return NULL;
  81.     }
  82.     return graph;
  83. }
  84.  
  85.  
  86. Edge *addEdge(Vertex *vertex1, Vertex *vertex2, uint32_t length, int32_t year, Graph *graph)
  87. {
  88.     Edge *edge1 = makeEdge(vertex2, length, year);
  89.     Edge *edge2 = makeEdge(vertex1, length, year);
  90.     if (!edge1 || !edge2)
  91.     {
  92.         freeMemory(edge1);
  93.         freeMemory(edge2);
  94.         return NULL;
  95.     }
  96.  
  97.     edge1->opposite = edge2;
  98.     edge2->opposite = edge1;
  99.     addToList(vertex1->edges, edge1);
  100.     addToList(vertex2->edges, edge2);
  101.     edge1->placeInList = firstListElement(vertex1->edges);
  102.     edge2->placeInList = firstListElement(vertex2->edges);
  103.     graph->edgeSize++;
  104.     return edge1;
  105. }
  106.  
  107.  
  108. void updateEdgeYear(Edge* edge, int32_t newYear)
  109. {
  110.     edge->year = newYear;
  111.     edge->opposite->year = newYear;
  112. }
  113.  
  114.  
  115. void removeEdge(Edge* edge, Graph *graph)
  116. {
  117.     removeListElement(edge->placeInList);
  118.  
  119.     removeListElement(edge->opposite->placeInList);
  120.     freeMemory(edge->opposite);
  121.  
  122.     freeMemory(edge);
  123.  
  124.     graph->edgeSize++;
  125. }
  126.  
  127.  
  128. Vertex *addVertex(String name, Graph *graph)
  129. {
  130.     Vertex *newVertex = allocMisc(sizeof(Vertex));
  131.     if (!newVertex)
  132.         return NULL;
  133.     if (!addToList(graph->vertexes, newVertex))
  134.     {
  135.         freeMemory(newVertex);
  136.         return NULL;
  137.     }
  138.  
  139.     graph->size++;
  140.     newVertex->edges = newList();
  141.     newVertex->allowed = true;
  142.     newVertex->visited = false;
  143.     newVertex->distance = infDistance();
  144.     newVertex->name = name;
  145.     return newVertex;
  146. }
  147.  
  148.  
  149. void removeVertex(Vertex *vertex, Graph *graph)
  150. {
  151.     while (firstListElement(vertex->edges))
  152.     {
  153.         removeEdge(firstListElement(vertex->edges)->value, graph);
  154.     }
  155.     removeList(vertex->edges);
  156.     freeMemory(vertex);
  157.     graph->size--;
  158. }
  159.  
  160.  
  161. void removeGraph(Graph *graph)
  162. {
  163.     for (ListElement *element = firstListElement(graph->vertexes); element; element = nextListElement(element))
  164.     {
  165.         removeVertex(element->value, graph);
  166.     }
  167.     removeList(graph->vertexes);
  168.     removeList(graph->emptyList);
  169.     freeMemory(graph);
  170. }
  171.  
  172.  
  173. void cleanVertexes(Graph *graph)
  174. {
  175.     for (ListElement *element = firstListElement(graph->vertexes); element; element = nextListElement(element))
  176.     {
  177.         Vertex *vertex = element->value;
  178.         vertex->visited = false;
  179.         vertex->allowed = true;
  180.         vertex->distance = infDistance();
  181.         vertex->from = NULL;
  182.     }
  183. }
  184.  
  185.  
  186. Distance shortestPath(Vertex *start, Vertex *target, List *zabronione, Graph *graph)
  187. {
  188.     cleanVertexes(graph);
  189.  
  190.     for (ListElement *element = firstListElement(zabronione); element; element = nextListElement(element))
  191.     {
  192.         Vertex *aktualVertex = element->value;
  193.         aktualVertex->allowed = false;
  194.         element = nextListElement(element);
  195.         if (!element)
  196.             break;
  197.     }
  198.  
  199.     start->allowed = true;
  200.     start->distance = newDistance();
  201.     target->allowed = true;
  202.  
  203.     Heap *priorytyQueue = newHeap(graph->edgeSize);
  204.     if (!priorytyQueue)
  205.         return start->distance;
  206.     pushHeap(priorytyQueue, start->distance, start);
  207.  
  208.     while (!isHeapEmpty(priorytyQueue))
  209.     {
  210.         Vertex *v = frontHeap(priorytyQueue);
  211.         popHeap(priorytyQueue);
  212.         if (v->visited)
  213.             continue;
  214.         v->visited = true;
  215.  
  216.         for (ListElement *element = firstListElement(v->edges); element; element = nextListElement(element))
  217.         {
  218.             Edge *e = element->value;
  219.             if (!e->active || !e->to->allowed)
  220.                 continue;
  221.  
  222.             int32_t cmp = compareDistance(e->to->distance, modifyDistance(v->distance, e->length, e->year));
  223.             e->to->distance = getBetterDistance(e->to->distance, modifyDistance(v->distance, e->length, e->year));
  224.             if (cmp > 0)
  225.             {
  226.                 e->to->from = e;
  227.                 pushHeap(priorytyQueue, e->to->distance, e->to);
  228.             }
  229.         }
  230.     }
  231.  
  232.     removeHeap(priorytyQueue);
  233.     Distance result = target->distance;
  234.     if (result.howMany != 1)
  235.         return target->distance;
  236.     result.pathTo = newList();
  237.     if (!result.pathTo)
  238.         return result;
  239.  
  240.     addToList(result.pathTo, target);
  241.     while (target != start)
  242.     {
  243.         if (!addToList(result.pathTo, target->from))
  244.         {
  245.             removeList(result.pathTo);
  246.             result.pathTo = NULL;
  247.             return result;
  248.         }
  249.  
  250.         if (!addToList(result.pathTo, target->from->opposite->to))
  251.         {
  252.             removeList(result.pathTo);
  253.             result.pathTo = NULL;
  254.             return result;
  255.         }
  256.         target = target->from->opposite->to;
  257.     }
  258.     return result;
  259. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement