Для начала вы можете рассмотреть возможность сделать p
параметром со значением по умолчанию (см. документация ). Что-то вроде Influence[x_,p_?Positive:0.05]:= (* definition *)
.
Во-вторых, вы устанавливаете спецификацию детали i
так, чтобы она начиналась с 0. В Mathematica индексы начинаются с 1, а не с 0. В итоге вы получите Head
объекта. В этом случае Followers[[x,0]]
вернет List
. Вам нужно изменить это и увеличить ваши данные на 1.
Following = {{3, 4, 5}, {1, 5}, {2, 4}, {2, 5}, {1, 3}};
Followers = {{2, 5}, {3, 4}, {1, 5}, {1, 3}, {1, 2, 4}};
Influence[x_, P_: 0.05] :=
Influence[x] =
Sum[1 + (P*Influence[Followers[[x, i]]])/(1 +
Length[Following[[x]]]), {i, Length[Followers[[x]]]}]
В-третьих, у вас есть некоторая рекурсивность в ваших данных. За человеком 1 следует лицо 2, за которым следуют 3 и 4, за которыми следуют оба. 1. Конечно, это рекурсивно.
follows = Join @@ Thread /@ Thread[Following -> Range@5]
{3 -> 1, 4 -> 1, 5 -> 1, 1 -> 2, 5 -> 2, 2 -> 3, 4 -> 3, 2 -> 4,
5 -> 4, 1 -> 5, 3 -> 5}
GraphPlot[follows, DirectedEdges -> True, VertexLabeling -> True]
![enter image description here](https://i.stack.imgur.com/KVSQs.png)
Вы можете рассмотреть явный тип итерации FixedPoint
, используя Chop
или параметр SameTest
, чтобы навсегда предотвратить рекурсию с небольшими изменениями. Но я сомневаюсь, что даже это поможет избежать проблемы с такими же циклическими данными, как у вас.
EDIT
хорошо, поэтому я разработал итеративное решение. Сначала вам нужно преобразовать данные ваших подписчиков в матрицу смежности.
(* Following = {{3, 4, 5}, {1, 5}, {2, 4}, {2, 5}, {1, 3}}; *)
Followers = {{2, 5}, {3, 4}, {1, 5}, {1, 3}, {1, 2, 4}};
adjmatrix = PadRight[SparseArray[List /@ # -> 1] & /@ Followers]
{{0, 1, 0, 0, 1},
{0, 0, 1, 1, 0},
{1, 0, 0, 0, 1},
{1, 0, 1, 0, 0},
{1, 1, 0, 1, 0}}
Это дает бит, эквивалентный операторам Length
в вашей версии.
vec1 = Table[1, {5}] (* {1, 1, 1, 1, 1} *)
adjmatrix.vec1
vec1.adjmatrix
{2, 2, 2, 2, 3}
{3, 2, 2, 2, 2}
Сходимость быстрая.
NestList[1 + 0.02 * adjmatrix.#1/(1 + vec1.adjmatrix) &, {1, 1, 1, 1, 1}, 5]
{{1, 1, 1, 1, 1}, {1.01, 1.01333, 1.01333, 1.01333, 1.02}, {1.01017,
1.01351, 1.01353, 1.01349, 1.02024}, {1.01017, 1.01351, 1.01354,
1.01349, 1.02025}, {1.01017, 1.01351, 1.01354, 1.01349,
1.02025}, {1.01017, 1.01351, 1.01354, 1.01349, 1.02025}}
Учитывая матрицу смежности, вы можете иметь функцию:
TunkRank[mat_?MatrixQ, p_?Positive] :=
With[{vec = Table[1, {Length[mat]}]},
FixedPoint[1 + p * mat.#1/(1 + vec.mat) &, vec]]
Надеюсь, это поможет. Я предполагаю, что это дает правильные ответы.