I want to design a map like in traveling salesman problem.
There are a number of nodes, some connected to another.
One node can be connected to many other nodes.
I have designed some, which one is better ? Or maybe there are another better design ?
1.)
class Node {
private int ID;
private int position-x;
private int position-y;
}
class Connection {
private int ID;
private Node first;
private Node second;
public void ConnectTwoNodes( Node a, Node b ) { ... }
}
2.)
class Node {
private int ID;
private int position-x;
private int position-y;
private ArrayList<Node> anotherNodes; // array of connected nodes
public void ConnectTo( Node another ) { ... }
}
Your language seems to be C++.
Your solution 1. has the following problems:
class Connection seems to "aggregate" the Nodes. It should rather be an association in OOspeak (a pointer to a Node to make it understandable to mere mortals)
a Connection object has absolutely no reason to exist, unless it connects 2 Nodes. So the function of ConnectTwoNodes belongs in a constructor. In other words rename it to Connection.
In your second solution it also seems that a Node contains the other Nodes. But in reality they exist independently. Again, you need associations, or pointers to other Nodes.
I actually prefer the 1. approach. Or a non-OO solution with a matrix, with "from" Nodes on one axle and "to" Nodes on the other. It also allows you to handle cases when it's possible to get from New York to Paris, Texas but not vice versa, because there are no more flights in the afternoon. In other words a directional graph.
Related
I'm still new to coding and I'm trying to learn how to create a linked list. What does this part mean? I can't seem to visualize this in my head.
static class Node {
int data;
Node next;
Node(int d){
data = d;
next = null;}
}
So this is a simple visual of a linked list. Your code represents a node class, so thats just the framework for a node. But you can think of that code representing one node, so it could represent the fourth node in this diagram. Thus, its data value would be {D} and its next value would be null.
In a linked list, the next node object it represented by the next variable. So if the node you are looking at is the second node, then your next variable will be the third node.
Please share me your thoughts and any solution to this problem of copying the full non-binary tree, and it may include loops as well in which some of the children are connected to other parent nodes.
Example:
Here, "A" is the root or parent, and its children are "B" and "C" as usual, and at the end, child "G" is connected back to its grand-parent level "B", and similarly the "I" is connected to its immediate parent "C", so these are like a loops, and this also needs to be copied in the new tree as is. So, here we need additional logic to identify the loops while copying the children nodes, and not getting into an infinite loop, and eventually return the copy of the whole tree.
A
- B
- D
- E
- F
- G --> B
- C
- I --> C
- K
This class or node structure can be like this:
public class Node{
private String value;
private List<Node> childrens;
public Node copyTree(Node root) {
...
//return
}
}
Thanks for our help.
I think the most direct way of doing this is to keep a map from nodes that have been copied to their copies. Then just check against the map before making a new copy of a node. Something like this (untested) should work:
public static Node copyTree(Node root) {
return copyTree(root, new HashMap<>());
}
private static Node copyTree(Node root, Map<Node, Node> images) {
Node copy = images.get(root);
if (copy == null) {
copy = new Node();
// register the copy before recursing on children
images.put(root, copy);
// now fill in the copy
copy.value = root.value;
copy.children = new ArrayList<>();
for (Node child : root.children) {
copy.children.add(copyTree(child, images);
}
}
return copy;
}
I try to use jsprit to solve a VRP with multiple TimeWindows. Therefore I created a new Constraint-Class which contains a Map that relates a "TimeWindowsNotAvailable"-class to a Service.
The "TimeWindowsNotAvailable"-class contains a List of TimeWindows where the Service can't be done (e.g. customer is not at home etc.).
The main problem is, that the newAct.getArrTime() is always 0.0, although you can see in the solution of the VRP that the arrTime is not 0.0.
Does anybody have an idea how I can fix this issue or are multiple TimeWindows much harder to implement?
public class TimeConstraint implements HardActivityStateLevelConstraint {
private Map<Service, TimeWindowsNotAvailable> notAvailableMap;
private RouteAndActivityStateGetter states;
private VehicleRoutingTransportCosts routingCosts;
public TimeConstraint() {
super();
}
public boolean checkDepTime(Service service, Double depTime){
TimeWindowsNotAvailable timeWindowsNotAvailable = notAvailableMap.get(service);
if(timeWindowsNotAvailable == null) return true;
System.out.println(depTime);
return timeWindowsNotAvailable.isAvailable(depTime);
}
public void setNotAvailableMap(Map<Service, TimeWindowsNotAvailable> notAvailableMap){
this.notAvailableMap = notAvailableMap;
}
#Override
public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
Service currentService = (Service)iFacts.getJob();
if(checkDepTime(currentService, **newAct.getArrTime()**)) return ConstraintsStatus.FULFILLED;
return ConstraintsStatus.NOT_FULFILLED;
}
}
You cannot yet model multiple time windows out-of-the box but it is going to be implemented. For the time being, you can implement your own. Assume you have for example the following two time windows for a service: (e1,l1), (e2,l2) where e means earliest operation start and l latest. If l1 < e2, it is comparably "easy" to implement. Just look at how I implemented single hard time windows. Look at which is the TimeWindowConstraint and which is the practical time window state updater. You probably only need minor modifications of these classes, so just copy them and add multiple time windows, and add these two new classes to your State- and ConstraintManager (do not forget to deactivate the default time window constraints/stateUpdater).
The newAct does not have any arrTime since it is not yet inserted into the route and the best insertion position is still to be determined (by checking constraints and calculating marginal insertion costs). But you can easily calculate it as follows:
double newActArrTime = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime,iFacts.getNewDriver(),iFacts.getNewVehicle);
Having read this question Immutable or not immutable? and reading answers to my previous questions on immutability, I am still a bit puzzled about efficient implementation of simple LinkedList that is immutable. In terms of array tha seems to be easy - copy the array and return new structure based on that copy.
Supposedly we have a general class of Node:
class Node{
private Object value;
private Node next;
}
And class LinkedList based on the above allowing the user to add, remove etc. Now, how would we ensure immutability? Should we recursively copy all the references to the list when we insert an element?
I am also curious about answers in Immutable or not immutable? that mention cerain optimization leading to log(n) time and space with a help of a binary tree. Also, I read somewhere that adding an elem to the front is 0(1) as well. This puzzles me greatly, as if we don't provide the copy of the references, then in reality we are modifying the same data structures in two different sources, which breaks immutability...
Would any of your answers alo work on doubly-linked lists? I look forward to any replies/pointers to any other questions/solution. Thanks in advance for your help.
Supposedly we have a general class of Node and class LinkedList based on the above allowing the user to add, remove etc. Now, how would we ensure immutability?
You ensure immutability by making every field of the object readonly, and ensuring that every object referred to by one of those readonly fields is also an immutable object. If the fields are all readonly and only refer to other immutable data, then clearly the object will be immutable!
Should we recursively copy all the references to the list when we insert an element?
You could. The distinction you are getting at here is the difference between immutable and persistent. An immutable data structure cannot be changed. A persistent data structure takes advantage of the fact that a data structure is immutable in order to re-use its parts.
A persistent immutable linked list is particularly easy:
abstract class ImmutableList
{
public static readonly ImmutableList Empty = new EmptyList();
private ImmutableList() {}
public abstract int Head { get; }
public abstract ImmutableList Tail { get; }
public abstract bool IsEmpty { get; }
public abstract ImmutableList Add(int head);
private sealed class EmptyList : ImmutableList
{
public override int Head { get { throw new Exception(); } }
public override ImmutableList Tail { get { throw new Exception(); } }
public override bool IsEmpty { get { return true; } }
public override ImmutableList Add(int head)
{
return new List(head, this);
}
}
private sealed class List : ImmutableList
{
private readonly int head;
private readonly ImmutableList tail;
public override int Head { get { return head; } }
public override ImmutableList Tail { get { return tail; } }
public override bool IsEmpty { get { return false; } }
public override ImmutableList Add(int head)
{
return new List(head, this);
}
}
}
...
ImmutableList list1 = ImmutableList.Empty;
ImmutableList list2 = list1.Add(100);
ImmutableList list3 = list2.Add(400);
And there you go. Of course you would want to add better exception handling and more methods, like IEnumerable<int> methods. But there is a persistent immutable list. Every time you make a new list, you re-use the contents of an existing immutable list; list3 re-uses the contents of list2, which it can do safely because list2 is never going to change.
Would any of your answers also work on doubly-linked lists?
You can of course easily make a doubly-linked list that does a full copy of the entire data structure every time, but that would be dumb; you might as well just use an array and copy the entire array.
Making a persistent doubly-linked list is quite difficult but there are ways to do it. What I would do is approach the problem from the other direction. Rather than saying "can I make a persistent doubly-linked list?" ask yourself "what are the properties of a doubly-linked list that I find attractive?" List those properties and then see if you can come up with a persistent data structure that has those properties.
For example, if the property you like is that doubly-linked lists can be cheaply extended from either end, cheaply broken in half into two lists, and two lists can be cheaply concatenated together, then the persistent structure you want is an immutable catenable deque, not a doubly-linked list. I give an example of a immutable non-catenable deque here:
http://blogs.msdn.com/b/ericlippert/archive/2008/02/12/immutability-in-c-part-eleven-a-working-double-ended-queue.aspx
Extending it to be a catenable deque is left as an exercise; the paper I link to on finger trees is a good one to read.
UPDATE:
according to the above we need to copy prefix up to the insertion point. By logic of immutability, if w delete anything from the prefix, we get a new list as well as in the suffix... Why to copy only prefix then, and not suffix?
Well consider an example. What if we have the list (10, 20, 30, 40), and we want to insert 25 at position 2? So we want (10, 20, 25, 30, 40).
What parts can we reuse? The tails we have in hand are (20, 30, 40), (30, 40) and (40). Clearly we can re-use (30, 40).
Drawing a diagram might help. We have:
10 ----> 20 ----> 30 -----> 40 -----> Empty
and we want
10 ----> 20 ----> 25 -----> 30 -----> 40 -----> Empty
so let's make
| 10 ----> 20 --------------> 30 -----> 40 -----> Empty
| /
| 10 ----> 20 ----> 25 -/
We can re-use (30, 40) because that part is in common to both lists.
UPDATE:
Would it be possible to provide the code for random insertion and deletion as well?
Here's a recursive solution:
ImmutableList InsertAt(int value, int position)
{
if (position < 0)
throw new Exception();
else if (position == 0)
return this.Add(value);
else
return tail.InsertAt(value, position - 1).Add(head);
}
Do you see why this works?
Now as an exercise, write a recursive DeleteAt.
Now, as an exercise, write a non-recursive InsertAt and DeleteAt. Remember, you have an immutable linked list at your disposal, so you can use one in your iterative solution!
Should we recursively copy all the references to the list when we insert an element?
You should recursively copy the prefix of the list up until the insertion point, yes.
That means that insertion into an immutable linked list is O(n). (As is inserting (not overwriting) an element in array).
For this reason insertion is usually frowned upon (along with appending and concatenation).
The usual operation on immutable linked lists is "cons", i.e. appending an element at the start, which is O(1).
You can see clearly the complexity in e.g. a Haskell implementation. Given a linked list defined as a recursive type:
data List a = Empty | Node a (List a)
we can define "cons" (inserting an element at the front) directly as:
cons a xs = Node a xs
Clearly an O(1) operation. While insertion must be defined recursively -- by finding the insertion point. Breaking the list into a prefix (copied), and sharing that with the new node and a reference to the (immutable) tail.
The important thing to remember about linked lists is :
linear access
For immutable lists this means:
copying the prefix of a list
sharing the tail.
If you are frequently inserting new elements, a log-based structure , such as a tree, is preferred.
There is a way to emulate "mutation" : using immutable maps.
For a linked list of Strings (in Scala style pseudocode):
case class ListItem(s:String, id:UUID, nextID: UUID)
then the ListItems can be stored in a map where the key is UUID:
type MyList = Map[UUID, ListItem]
If I want to insert a new ListItem into val list : MyList :
def insertAfter(l:MyList, e:ListItem)={
val beforeE=l.getElementBefore(e)
val afterE=l.getElementAfter(e)
val eToInsert=e.copy(nextID=afterE.nextID)
val beforeE_new=beforeE.copy(nextID=e.nextID)
val l_tmp=l.update(beforeE.id,beforeE_new)
return l_tmp.add(eToInsert)
}
Where add, update, get takes constant time using Map: http://docs.scala-lang.org/overviews/collections/performance-characteristics
Implementing double linked list goes similarly.
I was assigned a problem to solve using various search techniques. The problem is very similar to the Escape From Zurg problem or the Bridge and Torch problem. My issue is that I am lost as to how to represent the data as a tree.
This is my guess as to how to do it, but it doesn't make much sense for searching.
Another way could be to use a binary tree sorted by their walking time. However, I'm still not sure if I'm attacking this problem correctly since search algorithms don't necessarily require binary trees.
Any tips on representing this data would be appreciated.
Generally when you are using a tree search to solve a problem, each node represents some possible "state" of the world (who's on what side of the bridge, for example), and the children of each node represent all possible "successor states" (new states that can be reached in one move from the previous state). A depth-first search then represents trying one option until it dead-ends, then backing up to the last state where another option was available and trying it out. A breadth-first search represents trying out lots of options in parallel and seeing when the first of them find the goal node.
In terms of the actual way of encoding this, you would represent this as a multiway tree. Each node would probably contain the current state, plus a list of pointers to child nodes.
Hope this helps!
U could use something like this:
public class Node
{
public int root;
public List<Node> neighbours;
public Node(int x)
{
root=x;
}
public void setNeighboursList(List<Node> l)
{
neighbours = l;
}
public void addNeighbour(Node n)
{
if(neighbours==null) neighbours = new ArrayList<Node>();
neighbours.add(n);
}
...
}
public class Tree
{
public Node root;
....
}