Во-первых, сделайте отступ в коде.
Во-вторых, вам нужно инициализировать значения indegree
. Вот почему некоторые градусы, которые вы печатаете, НЕОБХОДИМЫ.
В-третьих, ваш N
слишком мал. Вы устанавливаете его на 7, но в примере .mtx
файл вы go вплоть до 11
. Для этого файла вам потребуется N
равным 12.
В-четвертых, если предоставленный вами вывод - это все, что выводила программа, то вы не читаете файл .mtx
, поскольку вы печатаете строку для каждого строка, которую вы читаете.
В-пятых, почему вы нарушаете l oop здесь:
if (j == i)
{
indegree[k]--;
break;
}
Это будет означать, что вы никогда не добавляете в очередь более одного узла за раз . Имеет ли это смысл?
В-шестых, у вас, мягко говоря, отсутствует реализация. Вы просматриваете список смежности на каждой итерации l oop. Это дает нам наихудший случай O(N^3)
, когда алгоритм Кана на самом деле линейен.
В-седьмых, я думаю, что первая строка в .mtx
отделена от остальных. Я думаю, это говорит о том, что в графе 7 концов и 11 узлов. Вы, однако, относитесь к этому как к описанию края. Если мое предположение верно, то эту информацию можно использовать для динамического определения N
вместо жесткого кодирования, как это делаете вы. Затем вы должны установить N
как второе число в первой строке.
В-восьмых, вам нужно сбросить указатель файла. Поэтому, когда вы снова попытаетесь прочитать файл, ничего не произойдет. Я также рекомендую не читать файл несколько раз. Скорее сохраняйте значения в массиве.
В-девятых, приятно видеть, что вы вызываете fclose
в конце, но если ваш график включает цикл, вы возвращаете -1
и не вызываете fclose
.
Относительно комментария ниже:
Чтобы прояснить четвертый пункт, если это все, что выводит ваша программа, то
11
Node : 12 with indegree value: -1
11
Node : 12 with indegree value: -1
8
Node : 8 with indegree value: 1
8
Node : 8 with indegree value: 2
2
Node : 2 with indegree value: 482383745
9
Node : 9 with indegree value: 1
10
Node : 10 with indegree value: -908997711
9
Node : 9 with indegree value: 2
10
Node : 10 with indegree value: -908997710
-1 enqueued to queue
-1 enqueued to queue
-1 enqueued to queue
-1 enqueued to queue
-1 enqueued to queue
-1 enqueued to queue
-1 enqueued to queue
тогда это l oop никогда не запускается:
while(fgets(line,50,fp)!=NULL)
{
sscanf(line, "%*d %d", &i);
printf("%d\n" , i); //I inserted this print to check if the .mtx file is read correctly(it is!)
indegree[i] ++;
printf("Node : %d with indegree value: %d\n",i,indegree[i]); //I inserted this print to check the indegree value that is incremented in each iteration
}
Я бы просто инициализировал indegree
с помощью for-l oop.
Что касается N
, вам нужно, чтобы он был по крайней мере, на единицу больше, чем имя самого большого узла во входных данных. Если некоторые узлы не появляются в файле, как в приведенном вами примере, они по-прежнему являются частью вашего графика, и их не следует (как правило) игнорировать. Если вы реализуете, например, алгоритм поиска по графу Дейкстры, вы можете игнорировать эти узлы, но для Кана вам нужно поместить их где-нибудь в вашем топологическом порядке (их расположение, однако, не имеет значения). Если бы вы игнорировали изолированные узлы, вам пришлось бы делать это осторожно. Если вы сделаете это так, как вы это сделаете, вы укажете за пределы indegree
, поскольку он имеет размер 7, но некоторые узлы больше этого. Вам нужно будет сопоставить их значения с 0, 1, ..., 6, чтобы поместиться в массив. Это несложно и может быть выполнено путем сортировки (логарифмически линейное время) или с помощью карты ha sh (линейное время). Для повторной передачи это не идеальный вариант в алгоритме Кана, потому что вам нужно учитывать расположение всех узлов в топологическом порядке, поэтому просто введите N = 12
и игнорируйте узел 0
. Вы также можете установить N = 11
и уменьшить все значения в файле .mtx
.