Cod sursa(job #2892193)

Utilizator Fanelu02Stefan Raileanu Fanelu02 Data 21 aprilie 2022 11:13:20
Problema Algoritmul lui Dijkstra Scor 0
Compilator c-32 Status done
Runda Arhiva educationala Marime 6.79 kb
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define inf 999

typedef struct graphMatrix {
	int** costMatrix;
	int numNodes;
} graphMatrix;

// clang-format off
int tempMatrix[][10] = { {0, 1, inf, inf, inf, inf, inf, inf, inf, 20},
						{1, 0, inf, 1, 2, inf, inf, inf, inf, inf},
						{inf, inf, 0, 1, 1, 1, inf, inf, inf, inf},
						{inf, 1, 1, 0, 3, inf, inf, inf, inf, inf},
						{inf, 2, 1, 3, 0, inf, inf, inf, inf, inf},
						{inf, inf, 1, inf, inf, 0, inf, 1, inf, inf},
						{inf, inf, inf, inf, inf, inf, 0, inf, inf, inf},
						{inf, inf, inf, inf, inf, 1, inf, 0, 1, 1},
						{inf, inf, inf, inf, inf, inf, inf, 1, 0, 1},
						{20, inf, inf, inf, inf, inf, inf, 1, 1, 0} };
// clang-format on

graphMatrix initGraphMatrix()
{
	graphMatrix graph;
	graph.numNodes = 10;
	graph.costMatrix = (int**)malloc(sizeof(int*) * graph.numNodes);
	for (int i = 0; i < graph.numNodes; i++) {
		graph.costMatrix[i] = (int*)malloc(sizeof(int) * graph.numNodes);
		for (int j = 0; j < graph.numNodes; j++)
			graph.costMatrix[i][j] = tempMatrix[i][j];
	}
	return graph;
}

void printMaxDegree(graphMatrix graph)
{
	int maxDegree = 0;
	int maxDegreeNode = -1;
	int degree = 0;
	int degreeNode = 0;

	for (int i = 0; i < graph.numNodes; i++) {
		degree = 0;
		for (int j = 0; j < graph.numNodes; j++) {
			if (graph.costMatrix[i][j] != 0 && graph.costMatrix[i][j] != inf) {
				degree++;
			}
		}
		if (degree > maxDegree) {
			maxDegree = degree;
			maxDegreeNode = i;
		}
	}
	

	printf("Node %i has maximum degree %i\n", maxDegreeNode, maxDegree);
}

graphMatrix floydWarshall(graphMatrix graph)
{
	graphMatrix pathCosts;
	pathCosts.numNodes = graph.numNodes;
	pathCosts.costMatrix = (int**)malloc(sizeof(int*) * pathCosts.numNodes);
	for (int i = 0; i < pathCosts.numNodes; i++) {
		pathCosts.costMatrix[i] = (int*)malloc(sizeof(int) * pathCosts.numNodes);
		for (int j = 0; j < pathCosts.numNodes; j++)
			pathCosts.costMatrix[i][j] = graph.costMatrix[i][j];
	}
	for(int k=0;k<graph.numNodes;k++)
		for(int i=0;i<graph.numNodes;i++)
			for (int j = 0; j < graph.numNodes; j++) 
				if (pathCosts.costMatrix[i][j] > pathCosts.costMatrix[i][k] + pathCosts.costMatrix[k][j]) 
					pathCosts.costMatrix[i][j] = pathCosts.costMatrix[i][k] + pathCosts.costMatrix[k][j];
	return pathCosts;
}

typedef struct nodeDP {
	int node;
	int d;
	int parent;
} nodeDP;

int index = 0;
nodeDP list[100];

int cmpNDP(const void* a, const void* b)
{
	nodeDP* A = (nodeDP*)a;
	nodeDP* B = (nodeDP*)b;
	return (A->d - B->d);
}

void printNDP(nodeDP* NDP, int n)
{
	printf("  Node: ");
	for (int i = 0; i < n; i++)
		printf("%5i", NDP[i].node);
	printf("\n");
	printf("     D: ");
	for (int i = 0; i < n; i++)
		printf("%5i", NDP[i].d);
	printf("\n");
	printf("Parent: ");
	for (int i = 0; i < n; i++)
		printf("%5i", NDP[i].parent);
	printf("\n");
}

void push(nodeDP node)
{
	if (index < 100) {
		list[index] = node;
		index++;
	}
	else
		printf("Lista este goala");
}

nodeDP min()
{
	int min = 100;
	for (int i = 0; i < index; i++) {
		if (list[i].d < min)
			min = i;
	}
	return list[min];
}

void pop(nodeDP node)
{
	int k = 0;
	for (int i = 0; i < index; i++) {
		if (node.node == list[i].node) {
			k = i;
			break;
		}
	}
	for (int i = k; i < index - 1; i++) {
		list[i] = list[i + 1];
	}
	list[index - 1].d = inf;
	list[index - 1].node = inf;
	list[index - 1].parent = inf;
	index--;
}

nodeDP* sortNDP(nodeDP* node)
{
	nodeDP aux;
	int ok = 0;
	do {
		ok = 0;
		for (int i = 0; i < 9; i++) {
			if (node[i].d > node[i + 1].d) {
				aux.d = node[i].d;
				aux.node = node[i].node;
				aux.parent = node[i].parent;
				node[i].d = node[i+1].d;
				node[i].node = node[i + 1].node;
				node[i].parent = node[i + 1].parent;
				node[i + 1].d = aux.d;
				node[i + 1].node = aux.node;
				node[i + 1].parent = aux.parent;
				ok = 1;
			}
		}
	} while (ok);
	return node;
}

nodeDP* dijsktra(graphMatrix graph, int source)
{
	nodeDP aux;
	nodeDP* NDP = (nodeDP*)malloc(sizeof(nodeDP) * graph.numNodes);
	if (NDP == NULL)
		return NULL;
	for (int i = 0; i < graph.numNodes; i++) {
		NDP[i].node = i;
		NDP[i].d = inf;
		NDP[i].parent = -1;
	}
	NDP[source].d = 0;
	int position = 0;
	push(NDP[source]);

	while (index) {
		aux = min();
		source = aux.node;
		for (int j = 0; j < graph.numNodes; j++) {
			if (graph.costMatrix[source][j] != inf && graph.costMatrix[source][j] != 0) {
				if (NDP[j].d > NDP[source].d + graph.costMatrix[source][j]) {
					NDP[j].d = graph.costMatrix[source][j]+NDP[source].d;
					NDP[j].parent = source;
					push(NDP[j]);
				}
			}
		}
		pop(NDP[source]);
	}
	NDP = sortNDP(NDP);
	return NDP;
}

int getGraphDiameter(nodeDP* graph)
{
	int max = 0;
	for (int i = 10; i >= 0; i--)
		if (graph[i].d != inf && graph[i].d > max)
			max = graph[i].d;

	return max;
}

typedef struct edge {
	int leftNode;
	int rightNode;
	int w;
	int selected;
} edge;

void printEdges(edge* edges, int n)
{
	for (int i = 0; i < n; i++) {
		if (edges[i].selected)
			printf("%i -%i-> %i\n", edges[i].leftNode, edges[i].w, edges[i].rightNode);
	}
}

int countEdges(graphMatrix graph)
{
	int numEdges = 0;
	for (int i = 0; i < graph.numNodes; i++)
		for (int j = 0; j < graph.numNodes; j++)
			if (i < j && graph.costMatrix[i][j] < inf)
				numEdges++;
	return numEdges;
}

int cmpEdge(const void* a, const void* b)
{
	//TODO
	return 1;
}

edge* kruskal(graphMatrix graph)
{
	int numEdges = countEdges(graph);
	edge* edges = (edge*)malloc(sizeof(edge) * numEdges);
	numEdges = 0;
	for (int i = 0; i < graph.numNodes; i++)
		for (int j = 0; j < graph.numNodes; j++)
			if (i < j && graph.costMatrix[i][j] < inf) {
				edges[numEdges].leftNode = i;
				edges[numEdges].rightNode = j;
				edges[numEdges].w = graph.costMatrix[i][j];
				edges[numEdges].selected = 0;
				numEdges++;
			}
	qsort(edges, numEdges, sizeof(edge), cmpEdge);
	int* treeTag = (int*)malloc(sizeof(int) * graph.numNodes);
	for (int i = 0; i < graph.numNodes; i++)
		treeTag[i] = i;

	//TODO

	return edges;
}

int main()
{
	graphMatrix graphM = initGraphMatrix();
	printMaxDegree(graphM);
	printf("\n");
	graphMatrix pathCosts = floydWarshall(graphM);
	for (int i = 0; i < pathCosts.numNodes; i++) {
		for (int j = 0; j < pathCosts.numNodes; j++)
			printf("%4i ", pathCosts.costMatrix[i][j]);
		printf("\n");
	}
	printf("\n");
	nodeDP* NDP = dijsktra(graphM, 0);
	printf("Diameter of the graph is %i\n", getGraphDiameter(NDP));

	
	printf("\nDijsktra rezult:\n");
	printNDP(NDP, graphM.numNodes);
	edge* treeEdges = kruskal(graphM);
	printf("\nKruskal rezult:\n");
	printEdges(treeEdges, countEdges(graphM));
	printf("\n");
	return 0;
}