私は、Dijkstraのアルゴリズムを使って、2つのノード間で最も重みの小さいパスを見つけなければならない手順に取り組んでいます。このプロシージャは、すべてのノードが特定の基準に一致するパスを返す必要があります(つまり、すべてのノードは特定の値を持つプロパティを持つ必要があります)。パス内の少なくとも1つのノードが基準に一致しない場合、パスは無効になり、アルゴリズムは次に重みの小さいパスを探す必要があります。PathExpanderBuilder.addNodeFilterはどのように機能しますか?
これを達成するために、私はPathExpanderBuilder
にノードフィルタを使用していますが、何もフィルタリングしていないようです。ここで
は私のコードです:
public class Demo {
@Procedure
@Description("apoc.algo.dijkstraWithFilters(startNode, endNode, " +
"'distance', 10, 'prop1', 2, 'prop2', [100, 200], 'prop3') " +
" YIELD path, weight - run dijkstra with relationship property name as cost function" +
" and a default weight if the property does not exist")
public Stream<WeightedPathResult> dijkstraWithFilters(
@Name("startNode") Node startNode,
@Name("endNode") Node endNode,
@Name("weightPropertyName") String weightPropertyName,
@Name("defaultWeight") double defaultWeight,
@Name("longPropName") String longPropName,
@Name("longPropValue") long longPropValue,
@Name("listPropName") String listPropName,
@Name("listPropValues") List<Long> listPropValues,
@Name("boolPropName") String boolPropName) {
PathFinder<WeightedPath> algo = GraphAlgoFactory.dijkstra(
buildPathExpanderByPermissions(longPropName, longPropValue, listPropName, listPropValues, boolPropName),
(relationship, direction) -> convertToDouble(relationship.getProperty(weightPropertyName, defaultWeight))
);
return WeightedPathResult.streamWeightedPathResult(startNode, endNode, algo);
}
private double convertToDouble(Object property) {
if (property instanceof Double)
return (double) property;
else if (property instanceof Long)
return ((Long) property).doubleValue();
else if (property instanceof Integer)
return ((Integer) property).doubleValue();
return 1;
}
private PathExpander<Object> buildPathExpanderByPermissions(
String longPropName,
long longPropValue,
String listPropName,
List<Long> listPropValue,
String boolPropName
) {
PathExpanderBuilder builder = PathExpanderBuilder.allTypesAndDirections();
builder.addNodeFilter(
node -> !node.hasProperty(longPropName) ||
node.getProperty(longPropName) instanceof Long &&
(long) node.getProperty(longPropName) < longPropValue
);
builder.addNodeFilter(
node -> {
try {
return !node.hasProperty(listPropName) ||
(boolean) node.getProperty(boolPropName, false) ||
!Collections.disjoint((List<Long>) node.getProperty(listPropName), listPropValue);
}
catch (Exception e){
return false;
}
}
);
return builder.build();
}
}
は、私はここで何をしないのですか? PathExpanderBuilder
を間違って使用していますか?