21 package org.matsim.core.network.algorithms;
23 import org.apache.logging.log4j.LogManager;
24 import org.apache.logging.log4j.Logger;
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.Collection;
40 import java.util.HashMap;
41 import java.util.HashSet;
42 import java.util.List;
45 import java.util.TreeSet;
46 import java.util.function.BiConsumer;
47 import java.util.function.BiPredicate;
96 public void run(
final Network network,
final BiPredicate<Link, Link> isMergeable,
113 public void run(
final Network network,
double thresholdLength){
125 for(Long l : nodeIDs){
131 run(network, thresholdLength, type, DEFAULT_IS_MERGEABLE_PREDICATE, DEFAULT_TRANSFER_ATTRIBUTES_CONSUMER);
135 final BiPredicate<Link, Link> isMergeable,
final BiConsumer<
Tuple<Link, Link>,
Link> transferAttributes) {
137 if(this.nodeTopoToMerge.size() == 0){
138 throw new RuntimeException(
"No types of node specified. Please use setNodesToMerge to specify which nodes should be merged");
141 log.info(
"running " + this.getClass().getName() +
" algorithm...");
144 nodeTopo.
run(network);
148 if(this.nodeTopoToMerge.contains(nodeTopo.
getTopoType(node)) && (!this.nodesNotToMerge.contains(node.getId())) ){
150 List<Link> removedLinks =
new ArrayList<>();
152 List<Link> iLinks =
new ArrayList<>(node.getInLinks().values());
153 List<Link> oLinks =
new ArrayList<>(node.getOutLinks().values());
155 for (
Link inLink : iLinks) {
156 for (
Link outLink : oLinks) {
159 if(this.mergeLinksWithDifferentAttributes){
162 boolean criteria =
false;
186 Id.
create(inLink.getId() +
"-" + outLink.getId(),
Link.class),
187 inLink.getFromNode(),
188 outLink.getToNode());
191 link.
setLength(inLink.getLength() + outLink.getLength());
195 (inLink.getLength() + outLink.getLength()) /
200 link.
setCapacity(Math.min(inLink.getCapacity(), outLink.getCapacity()));
204 + outLink.getLength() * outLink.getNumberOfLanes())
205 / (inLink.getLength() + outLink.getLength())
211 transferAttributes.accept(
Tuple.
of(inLink, outLink), link);
214 removedLinks.add(inLink);
215 removedLinks.add(outLink);
224 boolean isHavingShortLinks =
false;
236 if(isHavingShortLinks){
237 Link newLink =
NetworkUtils.
createAndAddLink(network,
Id.
create(inLink.getId() +
"-" + outLink.getId(),
Link.class), inLink.getFromNode(), outLink.getToNode(), inLink.getLength() + outLink.getLength(), inLink.getFreespeed(), inLink.getCapacity(), inLink.getNumberOfLanes());
244 transferAttributes.accept(
Tuple.
of(inLink, outLink), newLink);
247 removedLinks.add(inLink);
248 removedLinks.add(outLink);
256 for (
Link removedLink : removedLinks) {
257 this.mergedLinksToIntermediateNodes.remove(removedLink.getId());
262 log.info(
" resulting network contains " + network.
getNodes().size() +
" nodes and " +
263 network.
getLinks().size() +
" links.");
268 nodeTopo.
run(network);
272 Set<Node> fromNodes =
new HashSet<>();
273 List<Node> tmp = this.mergedLinksToIntermediateNodes.get(inLink.
getId());
274 if (tmp != null) fromNodes.addAll(tmp);
277 Set<Node> toNodes =
new HashSet<>();
278 tmp = this.mergedLinksToIntermediateNodes.get(outLink.
getId());
279 if (tmp != null) toNodes.addAll(tmp);
283 fromNodes.retainAll(toNodes);
285 return fromNodes.isEmpty();
289 List<Node> nodes =
new ArrayList<>();
290 List<Node> tmp = this.mergedLinksToIntermediateNodes.get(inLink.
getId());
294 tmp = this.mergedLinksToIntermediateNodes.get(outLink.
getId());
300 this.mergedLinksToIntermediateNodes.put(mergedLinkId, nodes);
311 this.nodeTopoToMerge.addAll(nodeTypesToMerge);
336 boolean hasTwoShortLinks =
false;
338 hasTwoShortLinks =
true;
340 return hasTwoShortLinks;
353 boolean hasShortLink =
false;
378 public static void main(String[] args) {
379 final String inNetworkFile = args[ 0 ];
380 final String outNetworkFile = args[ 1 ];
382 Set<Integer> nodeTypesToMerge =
new TreeSet<>();
383 nodeTypesToMerge.add(4);
384 nodeTypesToMerge.add(5);
393 nsimply.
run(network, Double.NEGATIVE_INFINITY);
void run(final Network network, double thresholdLength, ThresholdExceeded type, final BiPredicate< Link, Link > isMergeable, final BiConsumer< Tuple< Link, Link >, Link > transferAttributes)
static void setOrigId(final Node node, final String id)
void setNumberOfLanes(double lanes)
static final BiConsumer< Tuple< Link, Link >, Link > DEFAULT_TRANSFER_ATTRIBUTES_CONSUMER
Map< Id< Node >, ? extends Node > getNodes()
void setNodesToMerge(Set< Integer > nodeTypesToMerge)
void setFreespeed(double freespeed)
Link removeLink(final Id< Link > linkId)
static final Integer PASS1WAY
void run(final Network network, double thresholdLength, ThresholdExceeded type)
boolean areLinksMergeable(Link inLink, Link outLink)
void run(final Network network)
void write(final String filename)
static final Integer PASS2WAY
void collectMergedLinkNodeInfo(Link inLink, Link outLink, Id< Link > mergedLinkId)
static String getOrigId(Node node)
boolean bothLinksHaveSameLinkStats(Link linkA, Link linkB)
Set< Id< Node > > nodesNotToMerge
NetworkFactory getFactory()
void setNodesNotToMerge(Set< Long > nodeIDs)
static< T > Id< T > create(final long key, final Class< T > type)
static void main(String[] args)
boolean eitherLinkIsShorterThanThreshold(Link linkA, Link linkB, double thresholdLength)
Link createLink(final Id< Link > id, final Node fromNode, final Node toNode)
void run(final Network network)
void setLength(double length)
void setMergeLinkStats(boolean mergeLinksWithDifferentAttributes)
double getNumberOfLanes()
int getTopoType(final Node node)
Map< Id< Link >, ? extends Link > getLinks()
static double getFreespeedTravelTime(Link link)
static< A, B > Tuple< A, B > of(final A first, final B second)
static final BiPredicate< Link, Link > DEFAULT_IS_MERGEABLE_PREDICATE
static Link createAndAddLink(Network network, final Id< Link > id, final Node fromNode, final Node toNode, final double length, final double freespeed, final double capacity, final double numLanes)
boolean bothLinksAreShorterThanThreshold(Link linkA, Link linkB, double thresholdLength)
void setAllowedModes(Set< String > modes)
final Map< Id< Link >, List< Node > > mergedLinksToIntermediateNodes
void run(final Network network, double thresholdLength)
static Scenario createScenario(final Config config)
Collection< Integer > nodeTopoToMerge
void run(final Network network, final BiPredicate< Link, Link > isMergeable, final BiConsumer< Tuple< Link, Link >, Link > transferAttributes)
static Id< Node > createNodeId(final long key)
void setCapacity(double capacity)
Set< String > getAllowedModes()
static Config createConfig(final String context)
boolean mergeLinksWithDifferentAttributes