20 package org.matsim.core.network.algorithms;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.List;
30 import java.util.TreeMap;
32 import org.apache.logging.log4j.LogManager;
33 import org.apache.logging.log4j.Logger;
66 List<Node> toBeRemoved =
new ArrayList<>();
68 if ((node.getInLinks().size() == 0) && (node.getOutLinks().size() == 0)) {
69 toBeRemoved.add(node);
72 for (
Node node : toBeRemoved) {
87 public void run(
final Set<String> modes) {
88 run(modes,
new HashSet<String>());
111 public void run(
final Set<String> cleaningModes,
final Set<String> connectivityModes) {
112 final Set<String> combinedModes =
new HashSet<>(cleaningModes);
113 combinedModes.addAll(connectivityModes);
114 final Map<Id<Link>,
Link> visitedLinks =
new TreeMap<>();
115 Map<Id<Link>,
Link> biggestCluster =
new TreeMap<>();
117 log.info(
"running " + this.getClass().getName() +
" algorithm for modes " + Arrays.toString(cleaningModes.toArray())
118 +
" with connectivity modes " + Arrays.toString(connectivityModes.toArray()) +
"...");
121 log.info(
" checking " + this.network.
getNodes().size() +
" nodes and " +
122 this.network.
getLinks().size() +
" links for dead-ends...");
123 boolean stillSearching =
true;
124 Iterator<? extends Link> iter = this.network.
getLinks().values().iterator();
125 while (iter.hasNext() && stillSearching) {
126 Link startLink = iter.next();
127 if ((!visitedLinks.containsKey(startLink.
getId())) && (intersectingSets(combinedModes, startLink.
getAllowedModes()))) {
128 Map<Id<Link>,
Link> cluster = this.
findCluster(startLink, combinedModes);
129 visitedLinks.putAll(cluster);
130 if (cluster.size() > biggestCluster.size()) {
131 biggestCluster = cluster;
132 if (biggestCluster.size() >= (this.network.
getLinks().size() - visitedLinks.size())) {
134 stillSearching =
false;
139 log.info(
" The biggest cluster consists of " + biggestCluster.size() +
" links.");
145 List<Link> allLinks =
new ArrayList<>(this.network.
getLinks().values());
146 for (
Link link : allLinks) {
147 if (!biggestCluster.containsKey(link.getId())) {
148 Set<String> reducedModes =
new HashSet<>(link.getAllowedModes());
149 reducedModes.removeAll(cleaningModes);
150 link.setAllowedModes(reducedModes);
151 if (reducedModes.isEmpty()) {
153 if ((link.getFromNode().getInLinks().size() + link.getFromNode().getOutLinks().size()) == 0) {
154 this.network.
removeNode(link.getFromNode().getId());
156 if ((link.getToNode().getInLinks().size() + link.getToNode().getOutLinks().size()) == 0) {
157 this.network.
removeNode(link.getToNode().getId());
159 this.removedLinks.add(link.getId());
161 if(!removedLinks.contains(link.getId())) modifiedLinks.add(link.getId());
164 log.info(
" resulting network contains " + this.network.
getNodes().size() +
" nodes and " +
165 this.network.
getLinks().size() +
" links.");
180 final Map<Id<Link>, DoubleFlagRole> linkRoles =
new HashMap<>(this.network.
getLinks().size());
182 ArrayList<Node> pendingForward =
new ArrayList<>();
183 ArrayList<Node> pendingBackward =
new ArrayList<>();
185 TreeMap<Id<Link>,
Link> clusterLinks =
new TreeMap<>();
187 pendingForward.add(startLink.
getToNode());
191 while (pendingForward.size() > 0) {
192 int idx = pendingForward.size() - 1;
193 Node currNode = pendingForward.remove(idx);
195 if (intersectingSets(modes, link.getAllowedModes())) {
197 if (!r.forwardFlag) {
198 r.forwardFlag =
true;
199 pendingForward.add(link.getToNode());
206 while (pendingBackward.size() > 0) {
207 int idx = pendingBackward.size()-1;
208 Node currNode = pendingBackward.remove(idx);
210 if (intersectingSets(modes, link.getAllowedModes())) {
212 if (!r.backwardFlag) {
213 r.backwardFlag =
true;
214 pendingBackward.add(link.getFromNode());
217 clusterLinks.put(link.getId(), link);
253 private <T>
boolean intersectingSets(
final Set<T> setA,
final Set<T> setB) {
255 if (setB.contains(t)) {
263 DoubleFlagRole r = linkRoles.get(l.
getId());
265 r =
new DoubleFlagRole();
266 linkRoles.put(l.
getId(), r);
271 static class DoubleFlagRole {
272 boolean forwardFlag =
false;
273 boolean backwardFlag =
false;
Map< Id< Node >, ? extends Node > getNodes()
Link removeLink(final Id< Link > linkId)
Node removeNode(final Id< Node > nodeId)
void run(final Set< String > modes)
Map< Id< Link >, ? extends Link > getInLinks()
final Set< Id< Link > > getRemovedLinkIds()
void removeNodesWithoutLinks()
final Set< Id< Link > > removedLinks
final Set< Id< Link > > getModifiedLinkIds()
Map< Id< Link >, Link > findCluster(final Link startLink, final Set< String > modes)
MultimodalNetworkCleaner(final Network network)
Map< Id< Link >, ? extends Link > getLinks()
void run(final Set< String > cleaningModes, final Set< String > connectivityModes)
static DoubleFlagRole getDoubleFlag(final Link l, final Map< Id< Link >, DoubleFlagRole > linkRoles)
Map< Id< Link >, ? extends Link > getOutLinks()
final Set< Id< Link > > modifiedLinks
Set< String > getAllowedModes()