ArangoDB: Syntax error Unexpected For declaration - for-loop

in the following query I want to traverse a graph and get a list of fraud nodes and then I want to get all the traversals between those fraud nodes in the graph.
Fraud nodes I want to store in the variable lstofnodes.
How to solve this error?
let lstofnodes=(for doc in Account
filter doc.fraud == true
for v in 1..3 outbound doc graph "G1"
return distinct v._id)
return lstofnodes
for vertex in 1..3 outbound lstofndes graph "G1"
return distinct vertex._id

Can you try (the first return seems wrong, but cannot verify without data)
let lstofnodes=(for doc in Account
filter doc.fraud == true
for v in 1..3 outbound doc graph "G1"
return distinct v._id)
FOR startnode IN lstofnodes
for vertex in 1..3 outbound startnode graph "G1"
return distinct vertex._id

Related

How to traverse all the elements in a set?

I performed the set operation (i.e., return the union of two sets minus the intersection of the two sets) on two sets t1 and t2. The result is still a set. I used the following script to iterate over all the elements in the result, but an error is raised. Where is the problem?
t1 = set(1..23)
t2 = set(2..34)
result = t1^t2
for(i in result){
print(i)
}
Error message:
result => set doesn't support random access.
A set is a collection of unique elements and does not support iteration. Convert the set to a vector with keys() before you proceed:
t1 = set(1..23)
t2 = set(2..34)
result = t1^t2
vecResult = result.keys()
print(vecResult);
[24,25,26,27,28,29,1,30,31,32,33,34]

Find cities reachable in given time

I am trying to solve a problem where i have 3 columns in csv like below
connection Distance Duration
Prague<>Berlin 400 4
Warsaw<>Berlin 600 6
Berlin<>Munich 800 8
Munich<>Vienna 400 3.5
Munich<>Stuttgart 800 8
Stuttgart<>Freiburg 150 2
I need to find out how many cities i can cover in given time from the origin city
Example if i would give input as
Input: Berlin, 10
Output: ["Prague","Munich","Warsaw"]
Input : Berlin, 30
Output : ["Prague","Munich","Warsaw", "Vienna", "Stuttgart",
"Freiburg"]
This is something a Graph problem in real time.
I am trying this with Scala, can someone help please.
Below what i tried:
I made it working partially.
import scalax.collection.Graph // or scalax.collection.mutable.Graph
import scalax.collection.GraphPredef._, scalax.collection.GraphEdge._
import scalax.collection.edge.WDiEdge
import scalax.collection.edge.Implicits._
val rows = """Prague<>Berlin,400,4
Warsaw<>Berlin,600,6
Berlin<>Munich,800,8
Munich<>Vienna,400,3.5
Munich<>Stuttgart,800,8
Stuttgart<>Freiburg,150,2""".split("\n").toList
I am preparing the input for my application.
Below i am having a list of cities which are present in the given file.
NOTE: We can have it from file itself while reading and kept in list. Here i kept all as lowercase
val cityList = List("warsaw","berlin","prague","munich","vienna","stuttgart","freiburg")
Now creating a case class:
case class Bus(connection: String, distance: Int, duration: Float)
val buses: List[Bus] = rows.map(row => {
val r =
row.split("\\,")
Bus(r(0).toLowerCase, r(1).toInt, r(2).toFloat)
})
case class City(name: String)
// case class BusMeta(distance: Int, duration: Float)
val t = buses.map(bus => {
val s = bus.connection.split("<>")
City(s.head) ~ City(s.last) % bus.duration
})
val busGraph = Graph(t:_*)
From above we will create a Graph as required from the input file. "busGraph" in my case.
import scala.collection.mutable
val travelFrom = ("BERLIN").toLowerCase
val travelDuration = 16F
val possibleCities: mutable.Set[String] = mutable.Set()
if (cityList.contains(travelFrom)){
busGraph.nodes.get(City(travelFrom)).edges.filter(_.weight <= travelDuration).map(edge => edge.map(_.name)).flatten.toSet.filterNot(_ == travelFrom).foreach(possibleCities.add)
println("City PRESENT in File")
}
else
{
println("City Not Present in File")
}
I am geting Output here :
possibleCities: scala.collection.mutable.Set[String] = Set(munich, warsaw, prague)
Expected Output : Set(munich, warsaw, prague, stuttgart, Vienna)
Your solution only finds direct routes (that's why your output is shorter than expected). To get complete answer, you need to also consider connections, by recursively traversing the graph from each of the direct destinations.
Also, do not use mutable collections, they are evil.
Here is a possible solution for you:
// First, create the graph structure
def routes: Map[String, (String, Double)] = Source
.fromInputStream(System.in)
.getLines
.takeWhile(_.nonEmpty)
.map(_.split("\\s+"))
.flatMap { case Array(from_to, dist, time) =>
val Array(from,to) = from_to.split("<>")
Seq(from -> (to, time.toDouble), to -> (from, time.toDouble))
}.toSeq
.groupMap(_._1)(_._2)
// Now search for suitable routes
def reachable(
routes: Map[String, Seq[(String, Double)]],
from: String,
limit: Double,
cut: Set[String] = Set.empty
): Set[String] = routes
.getOrElse(from, Nil)
.filter(_._2 <= limit)
.filterNot { case (n, _) => cut(n) }
.flatMap { case(name, time) =>
reachable(routes, name, limit - time, cut + from) + name
}.toSet
// And here is how you use it
def main(argv: Array[String]): Unit = {
val Array(from, limit) = new Scanner(System.in).nextLine().split("\\s")
val reach = reachable(routes, from, limit.toDouble)
println(reach)
}
Do a breadth first search from the origin city, stopping going deeper when you reach the time limit. Output the stops reached by the search.
To my best knowledge this tasks should be solved with Graph Adjacency Matrix, which first need to build from input data.
In your particular case the Graph Adjacency Matrix would be 2D and contains cities on rows and columns and weight of direction as value.
See screenshot from Excel with example below,
At the first iteration you search for possible routes from starting cities and store city name (row/column id) and weight.
Each next iteration you try to add route and compare with limit (can you add it or not also make sure you are not adding same city)
To store results you will need again 2D array, where first element is you possible route and next element is a Tuple of visited city and value taken.
After few iterations you should get all possible options and just provide summary of founded.
TL;DR; Most of Graph programmatical algorithms use or depends (with different extent) on Graph Adjacency Matrix

Objects arranged as a graph

I want to arrange many objects of a certain class as a graph in Matlab. The goal is, that when I create a new object it automatically is added to the graph. However, as far as I can see graphs only accept numbers when I add a new node. How is typically dealt with it? Should I have a GroupClass that holds all the objects and a graph with the relations? What I would like to have is something like
G = graph()
O1 = createObject(G)
O2 = createObject(G)
and in createObject something like
...
G.addnode(O1)
G.addedge(O1,O2)
...
Afterwards I want to be able to plot the relations, print out groups or all nodes, etc.
You can do this by adding nodes as a "node properties" table. Here's a very simple example:
G = graph();
for idx = 1:10
% make a single-row table containing the name and data
% associated with this node
nodeProps = table({['Idx ', num2str(idx)]}, ...
MException('msg:id', sprintf('Message %d', idx)), ...
'VariableNames', {'Name', 'Data'});
G = addnode(G, nodeProps);
end
for idx = 2:10
% add edges based on the node names
G = addedge(G, 'Idx 1', sprintf('Idx %d', idx));
end
plot(G)

Cypher query brokes neo4j when not execute

I executed the query in the following segment of code but If there are 2 nodes faraway each other, The neo4j is broken;
START d=node(1), e=node(5)
MATCH p=shortestPath(d-[r:ROUTE*..15]-e)
WHERE all(x in relationships(p) WHERE x.RouteID=head(relationships(p)).RouteID)
RETURN p
limit 1
When I execute node 1 to 5 its working good and faster.When I execute node 5 to 45, it brokes neo4j.How can I solve that problem?
Thanks, Best regards
Try this:
START d=node(1), e=node(5)
MATCH p=shortestPath(d-[r:ROUTE*..45]-e)
WITH p, head(relationships(p)).RouteID as RouteID
WHERE all(x in relationships(p) WHERE x.RouteID=RouteID)
RETURN p
limit 1
you did a relationships(p) for any relationship in any path, so that's a big cross product.

returning values with a where clause

I have two tables as follows:
ScholarSubject
ScholarSubjectID<pk>
ScholarID
SubjectID
Mark
and
AdmissionReq
SubjectID
DegreeCode
MinumumMark
I'm trying to return everything from a Degree table (with PK degreeID) where the mark for a scholar is less than the minimum mark for admissions. My query is as follows:
public List<object> getDegreeByAPSandRequirements()
{
using (DataLayer.CareerDatabaseEntities context = new DataLayer.CareerDatabaseEntities())
{
return (from Degrees in context.Degrees
join admissions in context.AdmissionReqs on
Degrees.DegreeCode equals admissions.DegreeCode
join subject in context.Subjects on
admissions.SubjectID equals subject.SubjectID
join scholarsubject in context.ScholarSubjects on
subject.SubjectID equals scholarsubject.SubjectID
join scholar in context.Scholars on
scholarsubject.ScholarID equals scholar.ScholarID
where Degrees.APSScore <= scholar.APSScore && admissions.MinimumMark <= scholarsubject.NSC && scholarsubject.SubjectID.Equals(admissions.SubjectID)
select Degrees).Distinct().ToList<object>();
}
}
Everything works, except if I change one of the marks (in ScholarSubject) to a lesser value than the minumum mark (in AdmissionsReq) then it still returns a degree. I want to return a degree if both marks are greater than the minimum requirements and not only one of the marks.
What am I doing wrong? Can someone please help me??
I'm still not sure I understand what you're trying to do - unless you have just one scholar in your database it seems to me you will return a list of all degrees achieved by all scholars. If you don't want this, you need to filter on scholarID in the where clause.
But anyway - in order to get more information I would try to do 2 things.
I would change your query and start it with the scholar not with the degree as this might avoid some duplicates:
from scholar in context.Scholars
join scholarsubject in context.ScholarSubjects on scholar.ScholarID equals scholarsubject.ScholarID
join subject in context.Subjects on scholarsubject.SubjectID equals subject.SubjectID
join admission in context.AdmissionReqs on subject.SubjectID equals admission.SubjectID
join degree in context.Degrees on admission.DegreeCode equals degree.DegreeCode
where degree.APSScore <= scholar.APSScore
&& admission.MinimumMark <= scholarsubject.NSC
//&& scholarsubject.SubjectID.Equals(admission.SubjectID) // you should not need this line as you have the joins in place to assert this
select degree)
.Distinct()
.ToList<object>();
If this produces the same result as your previous query, then I'd change the return type to see what exactly you are getting - replace the last line with this and inspect the collection:
select new {ScholarID = scholar.ScholarID, Degree = degree})
.Distinct()
.ToList();

Resources