Skip to content

Commit 969f620

Browse files
authored
created spec for labeled graph (#77)
1 parent beaadaa commit 969f620

File tree

3 files changed

+151
-97
lines changed

3 files changed

+151
-97
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package aima.core.environment.map2d
2+
3+
/**
4+
* @author Shawn Garner
5+
*/
6+
final class LabeledGraph[Vertex, Edge] {
7+
import scala.collection.mutable
8+
val globalEdgeLookup = new mutable.LinkedHashMap[Vertex, mutable.LinkedHashMap[Vertex, Edge]]() // TODO: get rid of mutability; ListMap should work
9+
val vertexLabelsList = new mutable.ArrayBuffer[Vertex]() // TODO: get rid of mutability
10+
11+
def addVertex(v: Vertex): Unit = {
12+
checkForNewVertex(v)
13+
()
14+
}
15+
16+
def set(from: Vertex, to: Vertex, edge: Edge): Unit = {
17+
val localEdgeLookup = checkForNewVertex(from)
18+
localEdgeLookup.put(to, edge)
19+
checkForNewVertex(to)
20+
()
21+
}
22+
23+
def remove(from: Vertex, to: Vertex): Unit = {
24+
val localEdgeLookup = globalEdgeLookup.get(from)
25+
localEdgeLookup.foreach(l => l.remove(to))
26+
}
27+
28+
def get(from: Vertex, to: Vertex): Option[Edge] = {
29+
val localEdgeLookup = globalEdgeLookup.get(from)
30+
localEdgeLookup.flatMap(_.get(to))
31+
}
32+
33+
def successors(v: Vertex): List[Vertex] = {
34+
val localEdgeLookup = globalEdgeLookup.get(v)
35+
localEdgeLookup.toList.flatMap(_.keySet.toList)
36+
}
37+
38+
def vertexLabels =
39+
vertexLabelsList.toList
40+
41+
def isVertexLabel(v: Vertex): Boolean =
42+
globalEdgeLookup.get(v).isDefined
43+
44+
def clear(): Unit = {
45+
vertexLabelsList.clear()
46+
globalEdgeLookup.clear()
47+
}
48+
49+
private def checkForNewVertex(v: Vertex): mutable.LinkedHashMap[Vertex, Edge] = {
50+
val maybeExisting = globalEdgeLookup.get(v)
51+
maybeExisting match {
52+
case None =>
53+
val m = new mutable.LinkedHashMap[Vertex, Edge]
54+
globalEdgeLookup.put(v, m)
55+
vertexLabelsList.append(v)
56+
m
57+
case Some(existing) =>
58+
existing
59+
}
60+
}
61+
}

core/src/main/scala/aima/core/environment/map2d/Map2D.scala

Lines changed: 0 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -48,63 +48,6 @@ trait Map2D {
4848
def position(location: String): Option[Point2D]
4949
}
5050

51-
final class LabeledGraph[Vertex, Edge] {
52-
import scala.collection.mutable
53-
val globalEdgeLookup = new mutable.LinkedHashMap[Vertex, mutable.LinkedHashMap[Vertex, Edge]]() // TODO: get rid of mutability; ListMap should work
54-
val vertexLabelsList = new mutable.ArrayBuffer[Vertex]() // TODO: get rid of mutability
55-
56-
def addVertex(v: Vertex): Unit = {
57-
checkForNewVertex(v)
58-
()
59-
}
60-
61-
def set(from: Vertex, to: Vertex, edge: Edge): Unit = {
62-
val localEdgeLookup = checkForNewVertex(from)
63-
localEdgeLookup.put(to, edge)
64-
checkForNewVertex(to)
65-
()
66-
}
67-
68-
def remove(from: Vertex, to: Vertex): Unit = {
69-
val localEdgeLookup = globalEdgeLookup.get(from)
70-
localEdgeLookup.foreach(l => l.remove(to))
71-
}
72-
73-
def get(from: Vertex, to: Vertex): Option[Edge] = {
74-
val localEdgeLookup = globalEdgeLookup.get(from)
75-
localEdgeLookup.flatMap(_.get(to))
76-
}
77-
78-
def successors(v: Vertex): List[Vertex] = {
79-
val localEdgeLookup = globalEdgeLookup.get(v)
80-
localEdgeLookup.toList.flatMap(_.keySet.toList)
81-
}
82-
83-
def vertexLabels =
84-
vertexLabelsList.toList
85-
86-
def isVertexLabel(v: Vertex): Boolean =
87-
globalEdgeLookup.get(v).isDefined
88-
89-
def clear(): Unit = {
90-
vertexLabelsList.clear()
91-
globalEdgeLookup.clear()
92-
}
93-
94-
private def checkForNewVertex(v: Vertex): mutable.LinkedHashMap[Vertex, Edge] = {
95-
val maybeExisting = globalEdgeLookup.get(v)
96-
maybeExisting match {
97-
case None =>
98-
val m = new mutable.LinkedHashMap[Vertex, Edge]
99-
globalEdgeLookup.put(v, m)
100-
vertexLabelsList.append(v)
101-
m
102-
case Some(existing) =>
103-
existing
104-
}
105-
}
106-
}
107-
10851
final case class Point2D(x: Double, y: Double)
10952
final case class Distance(value: Double) extends AnyVal
11053
object Point2D {
@@ -141,8 +84,6 @@ class ExtendableMap2D(
14184
locationPositions.clear()
14285
}
14386

144-
def clearLinks(): Unit = links.clear()
145-
14687
/**
14788
* Add a one-way connection to the map.
14889
*
@@ -173,44 +114,6 @@ class ExtendableMap2D(
173114
links.set(toLocation, fromLocation, distance)
174115
}
175116

176-
/**
177-
* Remove a one-way connection.
178-
*
179-
* @param fromLocation
180-
* the from location.
181-
* @param toLocation
182-
* the to location.
183-
*/
184-
def removeUnidirectionalLink(fromLocation: String, toLocation: String): Unit = {
185-
links.remove(fromLocation, toLocation)
186-
}
187-
188-
/**
189-
* Remove the two corresponding one-way connections.
190-
*
191-
* @param fromLocation
192-
* the from location.
193-
* @param toLocation
194-
* the to location.
195-
*/
196-
def removeBidirectionalLink(fromLocation: String, toLocation: String): Unit = {
197-
links.remove(fromLocation, toLocation)
198-
links.remove(toLocation, fromLocation)
199-
}
200-
201-
/**
202-
* Defines the position of a location with respect to a 2 dimensional
203-
* coordinate system.
204-
*
205-
* @param loc
206-
* the location.
207-
* @param pos the x, y position
208-
*/
209-
def setPosition(loc: String, pos: Point2D): Unit = {
210-
locationPositions.put(loc, pos)
211-
()
212-
}
213-
214117
/**
215118
* Defines the position of a location within the map. Using this method, one
216119
* location should be selected as a reference position (<code>dist=0</code>
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package aima.core.environment.map2d
2+
3+
import org.specs2.mutable.Specification
4+
5+
/**
6+
* @author Shawn Garner
7+
*/
8+
class LabeledGraphSpec extends Specification {
9+
"add vertex" in {
10+
val graph = new LabeledGraph[Int, (Int, Int)]
11+
12+
graph.vertexLabels must beEmpty
13+
14+
graph.addVertex(2)
15+
16+
graph.vertexLabels must haveSize(1)
17+
graph.isVertexLabel(2) must beTrue
18+
graph.isVertexLabel(1) must beFalse
19+
20+
graph.addVertex(3)
21+
22+
graph.vertexLabels must haveSize(2)
23+
graph.isVertexLabel(3) must beTrue
24+
graph.isVertexLabel(2) must beTrue
25+
graph.isVertexLabel(1) must beFalse
26+
27+
graph.vertexLabels must contain(exactly(2, 3))
28+
}
29+
30+
"edge creation" in {
31+
val graph = new LabeledGraph[Int, (Int, Int)]
32+
33+
graph.addVertex(2)
34+
35+
graph.vertexLabels must haveSize(1)
36+
graph.isVertexLabel(2) must beTrue
37+
38+
graph.addVertex(6)
39+
40+
graph.vertexLabels must haveSize(2)
41+
graph.isVertexLabel(6) must beTrue
42+
43+
graph.set(2, 6, (2, 6))
44+
45+
graph.vertexLabels must haveSize(2)
46+
47+
graph.set(3, 12, (3, 12))
48+
49+
graph.vertexLabels must haveSize(4)
50+
graph.isVertexLabel(3) must beTrue
51+
graph.isVertexLabel(12) must beTrue
52+
53+
graph.set(2, 12, (2, 12))
54+
55+
graph.vertexLabels must haveSize(4)
56+
57+
graph.set(3, 6, (3, 6))
58+
59+
graph.vertexLabels must haveSize(4)
60+
61+
graph.set(6, 12, (6, 12))
62+
63+
graph.vertexLabels must haveSize(4)
64+
65+
graph.get(2, 3) must beNone
66+
graph.get(2, 6) must beSome((2, 6))
67+
graph.get(3, 6) must beSome((3, 6))
68+
graph.get(3, 12) must beSome((3, 12))
69+
graph.get(6, 12) must beSome((6, 12))
70+
}
71+
72+
"get successors" in {
73+
val graph = new LabeledGraph[Int, (Int, Int)]
74+
75+
graph.successors(2) must beEmpty
76+
77+
graph.set(2, 12, (2, 12))
78+
graph.set(3, 12, (3, 12))
79+
graph.set(2, 6, (2, 6))
80+
graph.set(3, 6, (3, 6))
81+
graph.set(6, 12, (6, 12))
82+
83+
graph.successors(2) must contain(exactly(6, 12))
84+
graph.successors(3) must contain(exactly(6, 12))
85+
86+
graph.successors(6) must contain(exactly(12))
87+
graph.successors(12) must beEmpty
88+
}
89+
90+
}

0 commit comments

Comments
 (0)