1 25 50 package org.jgrapht.graph; 51 52 import java.io.*; 53 54 import java.util.*; 55 56 import org.jgrapht.*; 57 import org.jgrapht.event.*; 58 import org.jgrapht.util.*; 59 60 61 115 public class Subgraph<V, E> 116 extends AbstractGraph<V, E> 117 implements Serializable 118 { 119 120 122 private static final long serialVersionUID = 3208313055169665387L; 123 private static final String NO_SUCH_EDGE_IN_BASE = 124 "no such edge in base graph"; 125 private static final String NO_SUCH_VERTEX_IN_BASE = 126 "no such vertex in base graph"; 127 128 130 Set<E> edgeSet = new LinkedHashSet<E>(); Set<V> vertexSet = new LinkedHashSet<V>(); 134 136 private transient Set<E> unmodifiableEdgeSet = null; 138 private transient Set<V> unmodifiableVertexSet = null; 139 private Graph<V, E> base; 140 private boolean isInduced = false; 141 142 144 154 public Subgraph(Graph<V, E> base, Set<V> vertexSubset, Set<E> edgeSubset) 155 { 156 super(); 157 158 this.base = base; 159 160 if (base instanceof ListenableGraph) { 161 ((ListenableGraph<V, E>) base).addGraphListener( 162 new BaseGraphListener()); 163 } 164 165 addVerticesUsingFilter(base.vertexSet(), vertexSubset); 166 addEdgesUsingFilter(base.edgeSet(), edgeSubset); 167 } 168 169 179 public Subgraph(Graph<V, E> base, Set<V> vertexSubset) 180 { 181 this(base, vertexSubset, null); 182 183 isInduced = true; 184 } 185 186 188 191 public Set<E> getAllEdges(V sourceVertex, V targetVertex) 192 { 193 Set<E> edges = null; 194 195 if (containsVertex(sourceVertex) && containsVertex(targetVertex)) { 196 edges = new ArrayUnenforcedSet<E>(); 197 198 Set<E> baseEdges = base.getAllEdges(sourceVertex, targetVertex); 199 200 for (Iterator<E> iter = baseEdges.iterator(); iter.hasNext();) { 201 E e = iter.next(); 202 203 if (edgeSet.contains(e)) { edges.add(e); 206 } 207 } 208 } 209 210 return edges; 211 } 212 213 216 public E getEdge(V sourceVertex, V targetVertex) 217 { 218 Set<E> edges = getAllEdges(sourceVertex, targetVertex); 219 220 if ((edges == null) || edges.isEmpty()) { 221 return null; 222 } else { 223 return edges.iterator().next(); 224 } 225 } 226 227 230 public EdgeFactory<V, E> getEdgeFactory() 231 { 232 return base.getEdgeFactory(); 233 } 234 235 238 public E addEdge(V sourceVertex, V targetVertex) 239 { 240 assertVertexExist(sourceVertex); 241 assertVertexExist(targetVertex); 242 243 if (!base.containsEdge(sourceVertex, targetVertex)) { 244 throw new IllegalArgumentException (NO_SUCH_EDGE_IN_BASE); 245 } 246 247 Set<E> edges = base.getAllEdges(sourceVertex, targetVertex); 248 249 for (Iterator<E> iter = edges.iterator(); iter.hasNext();) { 250 E e = iter.next(); 251 252 if (!containsEdge(e)) { 253 edgeSet.add(e); 254 255 return e; 256 } 257 } 258 259 return null; 260 } 261 262 265 public boolean addEdge(V sourceVertex, V targetVertex, E e) 266 { 267 if (e == null) { 268 throw new NullPointerException (); 269 } 270 271 if (!base.containsEdge(e)) { 272 throw new IllegalArgumentException (NO_SUCH_EDGE_IN_BASE); 273 } 274 275 assertVertexExist(sourceVertex); 276 assertVertexExist(targetVertex); 277 278 assert (base.getEdgeSource(e) == sourceVertex); 279 assert (base.getEdgeTarget(e) == targetVertex); 280 281 if (containsEdge(e)) { 282 return false; 283 } else { 284 edgeSet.add(e); 285 286 return true; 287 } 288 } 289 290 304 public boolean addVertex(V v) 305 { 306 if (v == null) { 307 throw new NullPointerException (); 308 } 309 310 if (!base.containsVertex(v)) { 311 throw new IllegalArgumentException (NO_SUCH_VERTEX_IN_BASE); 312 } 313 314 if (containsVertex(v)) { 315 return false; 316 } else { 317 vertexSet.add(v); 318 319 return true; 320 } 321 } 322 323 326 public boolean containsEdge(E e) 327 { 328 return edgeSet.contains(e); 329 } 330 331 334 public boolean containsVertex(V v) 335 { 336 return vertexSet.contains(v); 337 } 338 339 342 public int degreeOf(V vertex) 343 { 344 assertVertexExist(vertex); 345 346 ((UndirectedGraph<V, E>) base).degreeOf(vertex); 351 352 int degree = 0; 353 354 for (E e : base.edgesOf(vertex)) { 355 if (containsEdge(e)) { 356 degree++; 357 358 if (getEdgeSource(e).equals(getEdgeTarget(e))) { 359 degree++; 360 } 361 } 362 } 363 364 return degree; 365 } 366 367 370 public Set<E> edgeSet() 371 { 372 if (unmodifiableEdgeSet == null) { 373 unmodifiableEdgeSet = Collections.unmodifiableSet(edgeSet); 374 } 375 376 return unmodifiableEdgeSet; 377 } 378 379 382 public Set<E> edgesOf(V vertex) 383 { 384 assertVertexExist(vertex); 385 386 Set<E> edges = new ArrayUnenforcedSet<E>(); 387 Set<E> baseEdges = base.edgesOf(vertex); 388 389 for (E e : baseEdges) { 390 if (containsEdge(e)) { 391 edges.add(e); 392 } 393 } 394 395 return edges; 396 } 397 398 401 public int inDegreeOf(V vertex) 402 { 403 assertVertexExist(vertex); 404 405 int degree = 0; 406 407 for (E e : ((DirectedGraph<V, E>) base).incomingEdgesOf(vertex)) { 408 if (containsEdge(e)) { 409 degree++; 410 } 411 } 412 413 return degree; 414 } 415 416 419 public Set<E> incomingEdgesOf(V vertex) 420 { 421 assertVertexExist(vertex); 422 423 Set<E> edges = new ArrayUnenforcedSet<E>(); 424 Set<E> baseEdges = ((DirectedGraph<V, E>) base).incomingEdgesOf(vertex); 425 426 for (E e : baseEdges) { 427 if (containsEdge(e)) { 428 edges.add(e); 429 } 430 } 431 432 return edges; 433 } 434 435 438 public int outDegreeOf(V vertex) 439 { 440 assertVertexExist(vertex); 441 442 int degree = 0; 443 444 for (E e : ((DirectedGraph<V, E>) base).outgoingEdgesOf(vertex)) { 445 if (containsEdge(e)) { 446 degree++; 447 } 448 } 449 450 return degree; 451 } 452 453 456 public Set<E> outgoingEdgesOf(V vertex) 457 { 458 assertVertexExist(vertex); 459 460 Set<E> edges = new ArrayUnenforcedSet<E>(); 461 Set<? extends E> baseEdges = 462 ((DirectedGraph<V, E>) base).outgoingEdgesOf(vertex); 463 464 for (E e : baseEdges) { 465 if (containsEdge(e)) { 466 edges.add(e); 467 } 468 } 469 470 return edges; 471 } 472 473 476 public boolean removeEdge(E e) 477 { 478 return edgeSet.remove(e); 479 } 480 481 484 public E removeEdge(V sourceVertex, V targetVertex) 485 { 486 E e = getEdge(sourceVertex, targetVertex); 487 488 return edgeSet.remove(e) ? e : null; 489 } 490 491 494 public boolean removeVertex(V v) 495 { 496 if (containsVertex(v) && base.containsVertex(v)) { 500 removeAllEdges(edgesOf(v)); 501 } 502 503 return vertexSet.remove(v); 504 } 505 506 509 public Set<V> vertexSet() 510 { 511 if (unmodifiableVertexSet == null) { 512 unmodifiableVertexSet = Collections.unmodifiableSet(vertexSet); 513 } 514 515 return unmodifiableVertexSet; 516 } 517 518 521 public V getEdgeSource(E e) 522 { 523 return base.getEdgeSource(e); 524 } 525 526 529 public V getEdgeTarget(E e) 530 { 531 return base.getEdgeTarget(e); 532 } 533 534 private void addEdgesUsingFilter(Set<E> edgeSet, Set<E> filter) 535 { 536 E e; 537 boolean containsVertices; 538 boolean edgeIncluded; 539 540 for (Iterator<E> iter = edgeSet.iterator(); iter.hasNext();) { 541 e = iter.next(); 542 543 V sourceVertex = base.getEdgeSource(e); 544 V targetVertex = base.getEdgeTarget(e); 545 containsVertices = 546 containsVertex(sourceVertex) 547 && containsVertex(targetVertex); 548 549 edgeIncluded = (filter == null) || filter.contains(e); 551 552 if (containsVertices && edgeIncluded) { 553 addEdge(sourceVertex, targetVertex, e); 554 } 555 } 556 } 557 558 private void addVerticesUsingFilter(Set<V> vertexSet, Set<V> filter) 559 { 560 V v; 561 562 for (Iterator<V> iter = vertexSet.iterator(); iter.hasNext();) { 563 v = iter.next(); 564 565 if ((filter == null) || filter.contains(v)) { 567 addVertex(v); 568 } 569 } 570 } 571 572 protected Graph<V, E> getBase() 573 { 574 return base; 575 } 576 577 580 public double getEdgeWeight(E e) 581 { 582 return base.getEdgeWeight(e); 583 } 584 585 588 public void setEdgeWeight(E e, double weight) 589 { 590 ((WeightedGraph<V, E>) base).setEdgeWeight(e, weight); 591 } 592 593 595 601 private class BaseGraphListener 602 implements GraphListener<V, E>, Serializable 603 { 604 private static final long serialVersionUID = 4343535244243546391L; 605 606 609 public void edgeAdded(GraphEdgeChangeEvent<V, E> e) 610 { 611 if (isInduced) { 612 E edge = e.getEdge(); 613 addEdge( 614 base.getEdgeSource(edge), 615 base.getEdgeTarget(edge), 616 edge); 617 } 618 } 619 620 623 public void edgeRemoved(GraphEdgeChangeEvent<V, E> e) 624 { 625 E edge = e.getEdge(); 626 627 removeEdge(edge); 628 } 629 630 633 public void vertexAdded(GraphVertexChangeEvent<V> e) 634 { 635 } 637 638 641 public void vertexRemoved(GraphVertexChangeEvent<V> e) 642 { 643 V vertex = e.getVertex(); 644 645 removeVertex(vertex); 646 } 647 } 648 } 649 | Popular Tags |