I need a matching algorithm between a collection(Xi) and a collection(collection(Yj))
knowing that Collection()Yj may have elements in common
I explain with an example:
suppose we have a web service S with 3 inputs (I1,I2,I3)
I1 can be provided by services A, B, C, D
I2 can be provided by service A,E
I3 can be provided by services F
I need an algorithm or a function to find the best combinaison between the available services(A to F) to provide the input of S (I1,I2,I3)
Collection(Xi)={I1,I2,I3}
Collection(Collection(Yj))= {{A,B,C,D},{A,E},{F}}
Thank you.
This is exactly the explanation of Maximum Bipartite Matching problem.
One part is {i1, i2, i3 .....}, the other part is {A, B, C, D, ....}
Read more about it here.
http://www.geeksforgeeks.org/maximum-bipartite-matching/
Related
I'm trying to solve project Euler problem 9 using prolog. I'm a 100% n00b with prolog and I'm just trying to understand the basics right now.
I'm trying to use findall to get all triplets that would add up to 1000, but I can't really figure out the syntax.
What I'm hoping for is something like:
pythag_trip(A, B, C, D) :- D is (A * A) + (B * B) + (C * C).
one_thou_pythag(A, B, C) :- pythag_trip(A, B, C, 1000).
product_trip(A, B, C, D) :- D is A * B * C.
findall([A, B, C], one_thou_pythag(A, B, C) , Bag)).
writeln(Bag).
I know that doesn't work because it's saying Bag is not instantiated. But there are still some basics that I don't understand about the language, too.
1: can I even do this? With multiple moving pieces at once? Can I find all triplets satisfying a condition? Do I need to go down a completely different like like using clpfd?
2: What is supposed to be going in that last argument where I put Bag?
3: Is it possible to create data types? I was thinking it might be good to create a triplet set type and an operation to get the pythagorean triplet sum of them if I have to find some way to generate all the possibilities on my own
Basically those questions and then, I could use some pointing in the right direction if anyone has tips
Sorry but I don't answer your questions. It seems to me that you're trying not a prolog-like approach.
You should try to solve it logically.
So do this problem from the top to bottom.
We want to have 3 numbers that sum to 1000.
between(1,1000,A), between(A,1000,B), between(B,1000,C), C is 1000-A-B.
In that case, we will have them sorted and we won't take permutations.
So let's go a step further. We want them to be pythagorem triplet.
between(1,1000,A), between(A,1000,B), between(B,1000,C), C is 1000-A-B, is_triplet(A,B,C).
But we don't have is_triplet/3 predicate, so let's create it
is_triplet(A,B,C) :- D is C*C - A*A -B*B, D=0.
And that's actually it.
So let's sum it up
is_triple(A, B, C) :- D is C*C - A*A - B*B, D = 0.
triplet(A,B,C) :- between(1,1000,A), between(A,1000,B), C is 1000-A-B, between(B,1000,C), C is 1000-A-B, is_triple(A,B,C).
When you call triplet(A,B,C) you should get an answer.
Notice one thing, that at the end I've swapped C is 1000-A-B with between(B,1000,C). It makes the program much faster, try to think why.
In a directed acyclic graph describing a set of tasks to process, i need to find all tasks that can be processed concurrently. The graph has no loops and is quite small (~1000 nodes, ~2000 edges), performance is not a primary concern.
Examples with desired result:
[] is a group. All tasks in a group must be processed before continuing
[x & y] means x and y can be processed concurrently (x and y in parallel)
x -> y means x and y must be processed sequentially (x before y)
1
a -> [b & c] -> c
2
[a & e] -> b -> c -> [d & f]
3
[ [a -> b] & [e -> f] ] -> [ [c -> d] & g ]
I do not want to actually execute the graph, but rather build a data structure that is as parallel as possible, while maintaining the order. The nomenclature and names of algorithms is not that familiar to me, so i'm having a hard time trying to find similar problems/solutions online.
Mathematically, I would frame this problem as finding a minimally defined series-parallel partial order extending the given partial order.
I would start by transitively reducing the graph and repeatedly applying two heuristics.
If x has one dependent y, and y has one dependency x, merge them into a new node z = [x → y].
If x and y have the same dependencies and dependents, merge them into a new node z = [x & y].
Now, if the input is already series-parallel, the result will be one node. In general, however, this will leave a graph that embeds an N-shaped structure like b → c, b → g, f → g from the last example in the question. This structure must be addressed by adding one or more of b → f, c → f, c → g, f → b, f → c, g → c. But in a different instance, this act would in turn create new N-shaped structures. There's no obvious notion of a closure, which is why this problem feels hard to me.
Some of these choices seem worse than others. For example, c → f forces the sequence b → c → f → g, whereas f → c is the only choice that doesn't increase the length of the critical path.
I guess what I'd try is,
If heuristics 1 and 2 have no targets, form a graph with edges x--y if and only if x and y have either a common dependent or a common dependency, compute the connected components of this graph, and &-merge the smallest component that isn't a singleton, followed by another transitive reduction.
Here's a solution i came up with (pseudocode):
sequence = []
for each (node, depth) in depthFirstSearch(graph)
sequence[depth].push(node)
return sequence
The sequence defines the order to process the graph. If an item in it contains more than one node, they can be processed concurrently.
While this allows for some concurrency, it does not advance as fast as it could. For example, f in the 3rd example in the question would require a to be completed first (as it will be at depth 1, when a and e are depth 0). Ideally work on f could start when e is done.
I have a problem to get all combinations of elements, and elements can be repeat and reuse for many times, even in a single combination.
For example, I have a box with 100 cm2, then i have below objects:
1) Object A: 20cm2
2) Object B: 50cm2
The expected combinations would be: (A), (A, A), (A, A, A), (A, A, A, A), (A, A, A, A, A), (A, B), (A, B, A), (A, B, A, A) .....
Any combination are allowed, as long as they can fit into the box. Objects can be repeat many times in single combination. However, repeated pattern is not needed e.g. (A, B) is equal to (B, A).
I not sure what is the keyword to search for this question, do let me know if this is a repeated question.
Seems to me like a recursive algo would do the job: fit the first object then add all combinations of the next objects (including the one you just included) in the box with a reduced size.
Then do the same with the second object, always using combinations with the next objects in line, not the previous ones (can't have an A after a B).
With your example, you would have:
(A)
(A,A)
(A,A,A)
(A,A,A,A)
(A,A,A,A,A)
(A,A,A,A,B) does not work
(A,A,A,B) does not work
(A,A,B)
(A,B)
(A,B,B) does not work
(B)
(B,B)
I have four sets:
A={a,b,c}, B={d,e}, C={c,d}, D={a,b,c,e}
I want to search the sequence of sets that give me: a b c d
Example: the sequence A A A C can give me a b c d because "a" is an element of A, "b" is an element of A, "c" is an element of A and "d" is an element of C.
The same thing for : D A C B, etc.
I want an algorithm to enumerate all sequences possibles or a mathematical method to find the sequences.
You should really come up with some code of your own and then ask specific questions about problems with it. But it's interesting, so I'll share some thoughts.
You want a b c d.
a can come from A, D
b can come from A, D
c can come from A, C, D
d can come from B, C
So the problem reduces to finding all of the 2*2*3*2=24 ways to combine those options.
One way is recursion with backtracking. Build it from left to right, output when you have a complete set. Like the 8 queens problem, but much simpler since everything is independent.
Another way is to count the integers and map them into a mixed-base system. First digit base 2, then 2, 3, 2. So 0 becomes AAAB, 1 is AAAC, 2 is AACB, etc. 23 is DDDC and 24 needs five digits so you stop there.
Having some issues with a Prolog question:
The following clauses represent a directed graph, where nodes are
atoms, and edges are denoted by the connected predicate. Given that
the following clauses are in the database, answer the two questions
below.
connected(a,b).
connected(b,d).
connected(b,e).
connected(b,f).
connected(a,c).
connected(c,f).
connected(c,g).
connected(h,c).
path(X,Y) :- connected(X,Y).
path(X,Z) :- connected(X,Y), path(Y,Z).
Show the Prolog query that returns all nodes having two or more
different incoming edges (i.e., at least two different nodes are
connected to it). Also, show the result of entering the query (asking
for every solution). Your query may return the same node multiple
times, and may printout the values of other variables in the query.
The variable denoting the node in question should be called DNode.
So far I have:
path(DNode,__) , path(__,DNode).
But that only give me b and c
I think the letters with more than one nodes are a, b, c, f.
I tried this to get a, b and c:
path(__,DNode),path(DNode,__) ; path(DNode,__) , path(DNode,__).
But I got a, b, c and h.
I am assuming I'll have to like this to get all the letters I want:
path(__,DNode),path(DNode,__) ; path(DNode,__) , path(DNode,__) ; path(__,DNode) , path(__,DNode).
It gives me a, b, c, e, f, g and h though.
Any advice about how to get the 4 letters I want would be appreciated.
if you display your graph, perhaps with Graphviz
?- writeln('digraph G {'), forall(connected(A,B), writeln(A->B)), writeln('}').
you can see that only [c,f] have 2 incoming edges, and that you don't need path/2. It's sufficient a join on the second argument of connected/2, with a test that the first arguments are different (operator (\=)/2).