So i am starting with Prolog and had an example task, where i have some points that form a maze and i want to know all the nodes that can lead to node 1.
connected(1,2).
connected(3,4).
connected(5,6).
connected(7,8).
connected(9,10).
connected(12,13).
connected(13,14).
connected(15,16).
connected(17,18).
connected(19,20).
connected(4,1).
connected(6,3).
connected(4,7).
connected(6,11).
connected(14,9).
connected(11,15).
connected(16,12).
connected(14,17).
connected(16,19).
reachable(X,Z) :- connected(X,Z).
reachable(X,Z) :- connected(X,Y),reachable(Y,Z).
I used the following query:
reachable(X,1).
which resulted in a simple false and not all nodes that lead to 1.
I on the other hand expected something like this:
x = 4;
It should be noted that this is a directed Graph.
If I execute the query reachable(X,1)., I get the expected result:
?- reachable(N,1).
N = 4 ;
N = 3 ;
N = 5 ;
N = 6 ;
false.
Which is what one expects based on the following graph:
generated with: dot -Tpng < conn.dot > conn.png and conn.dot:
digraph G {
1 -> 2;
3 -> 4;
5 -> 6;
7 -> 8;
9 -> 10;
12 -> 13;
13 -> 14;
15 -> 16;
17 -> 18;
19 -> 20;
4 -> 1;
6 -> 3;
4 -> 7;
6 -> 11;
14 -> 9;
11 -> 15;
16 -> 12;
14 -> 17;
16 -> 19;
}
Please check whether you have made a small typo or space error in your Prolog file.
Related
Given n, I have a binary pattern to be generated like this in a part of my application:
n = 0
0 -> 0
n = 1
0 -> 0
1 -> 1
n = 2
0 -> 00
1 -> 01
2 -> 10
3 -> 11
n = 3
0 -> 000
1 -> 001
2 -> 010
3 -> 100
4 -> 011
5 -> 101
6 -> 110
7 -> 111
n = 4
0 -> 0000
1 -> 0001
2 -> 0010
3 -> 0100
4 -> 1000
5 -> 0011
6 -> 0101
7 -> 1001
8 -> 0110
9 -> 1010
10 -> 1100
11 -> 0111
12 -> 1011
13 -> 1101
14 -> 1110
15 -> 1111
n = 5
0 -> 00000
1 -> 00001
2 -> 00010
3 -> 00100
4 -> 01000
5 -> 10000
6 -> 00011
7 -> 00101
8 -> 01001
9 -> 10001
10 -> 00110
11 -> 01010
12 -> 10010
13 -> 01100
14 -> 10100
15 -> 11000
16 -> 00111
17 -> 01011
18 -> 10011
19 -> 01101
20 -> 10101
21 -> 11001
22 -> 01110
23 -> 10110
24 -> 11010
25 -> 11100
26 -> 01111
27 -> 10111
28 -> 11011
29 -> 11101
30 -> 11110
31 -> 11111
I'll try to explain this algorithm the best way I can:
The algorithm has loops. In each loop, an extra bit is flipped. Then combinations are to be made out of it.
So in the first loop, no bits are 1s.
In the second loop, only one bit is 1. We need to first go through all possible combinations, in such an order that the leftmost bits are lit only after all combinations for the rightmost bits are over.
Similarly keep proceeding to further loops.
I'm not sure how to write an efficient code for it. One thing I could think of is like a DP solution to this problem. But could there be a more elegant, something like a mathematical solution, where I could put in 'n' and get the binary pattern equivalent?
You could use a recursive approach. In the main routine, increase the number of one-bits you want to produce (from 1 to n), and then call a recursive function that will do that job as follows:
It chooses a bit to set to 1, and then calls the function recursively to use the remaining bits at the right of it, to place one fewer one-bits.
Here is an implementation in JavaScript, with a demo run for n=4:
function * generateOnes(numDigits, numOnes) {
if (numDigits === 0 || numOnes === 0) {
yield 0;
} else {
for (let pos = numOnes - 1; pos < numDigits; pos++) {
for (let result of generateOnes(pos, numOnes - 1)) {
yield (1 << pos) | result;
}
}
}
}
function * generate(numDigits) {
for (let numOnes = 1; numOnes <= numDigits; numOnes++) {
yield * generateOnes(numDigits, numOnes);
}
}
// Demo with n=4:
for (let result of generate(4)) {
console.log(result.toString(2).padStart(4, "0"));
}
Here is the equivalent in Python:
def generate_ones(num_digits, num_ones):
if num_digits == 0 or num_ones == 0:
yield 0
else:
for pos in range(num_ones - 1, num_digits):
for result in generate_ones(pos, num_ones - 1):
yield (1 << pos) | result
def generate(num_digits):
for num_ones in range(1, num_digits + 1):
yield from generate_ones(num_digits, num_ones)
# Demo with n=4:
for result in generate(4):
print('{0:04b}'.format(result))
n=int(input())
a=[]
for i in range(2**n):
Str = bin(i).replace('0b','')
a.append(Str)
for i in range(len(a)):
a[i] = '0'*(n-len(a[i])) + a[i]
for i in range(len(a)):
print(a[i])
If you have any doubts related to the code comment down
Supposing “We need to first go through all possible combinations, in such an order that the leftmost bits are lit only after all combinations for the rightmost bits are over” is correct and the example shown for n=4:
7 -> 1001
8 -> 0110
is wrong, then here is C code to iterate through the values as desired:
#include <stdio.h>
// Print the n-bit binary numeral for x.
static void PrintBinary(int n, unsigned x)
{
putchar('\t');
// Iterate through bit positions from high to low.
for (int p = n-1; 0 <= p; --p)
putchar('0' + ((x >> p) & 1));
putchar('\n');
}
/* This is from Hacker’s Delight by Henry S. Warren, Jr., 2003,
Addison-Wesley, Chapter 2 (“Basics”), Section 2-1 “Manipulating Rightmost
Bits”, page 14.
*/
static unsigned snoob(unsigned x)
{
/* Consider some bits in x dddd011...1100...00, where d is “do not care”
and there are t bits in that trailing group of 1s. Then, in the code
below:
smallest is set to the trailing 1 bit.
ripple adds to that bit, carrying to the next 0, producing
dddd100...0000...00. Note that t 1 bits changed to 0s and one 0
changed to 1, so ripple has t-1 fewer 1 bits than x does.
ones is set to all bits that changed, dddd111...1100...0. It has
t+1 bits set -- for the t 1s that changed to 0s and the 0 that
changed to 1.
ones/smallest aligns those bits to the right, leaving the lowest
t+1 bits set. Shifting right two bits leaves t-1 bits set.
Then ripple | ones restores t-1 1 bits in the low positions,
resulting in t bits set.
*/
unsigned smallest = x & -x; // Find trailing 1 bit.
unsigned ripple = x + smallest; // Change it, carrying to next 0.
unsigned ones = x ^ ripple; // Find all bits that changed.
ones = ones/smallest >> 2;
return ripple | ones;
}
/* Give a number of bits n, iterate through all values of n bits in order
first by the number of bits set then by the binary value.
*/
static void Iterate(int n)
{
printf("Patterns for n = %d:\n", n);
// Iterate s through the numbers of bits set.
for (int s = 0; s <= n; ++s)
{
/* Set s low bits. Note: If n can equal (or exceed) the number of
bits in unsigned, "1u << s" is not defined by the C standard, and
some alternative must be used.
*/
unsigned i = (1u << s) - 1;
// Find the highest value.
unsigned h = i << n-s;
PrintBinary(n, i);
while (i < h)
{
i = snoob(i);
PrintBinary(n, i);
}
}
}
int main(void)
{
for (int n = 1; n <= 4; ++n)
Iterate(n);
}
There is a m x n array, I need to output each possible combination Of each line's element. For example, for array{{1,2,3},{4,5,6}}, I need to output{{1,4},{1,5},{1,6},{2,4},{2,5},{2,6},{3,4},{3,5},{3,6}}.
I think there should be a m loop to solve this. For the example above, I wrote the code:
int[,] array = new int[,] {{1, 2, 3}, {4, 5, 6}};
for (var i = 0; i < 3; i++)
{
for (var j = 0; j < 3; j++)
{
Console.WriteLine($"{{{array[0, i]},{array[1, j]}}}");
}
}
With m changes, the number of for loop also changes. But m is unknown when I write the code. How can I solve it?
Maintain a list of active combinations c. Initialize c to be the array's first row. Then iterate every additional row and update c. Basically, you augment each of the current combinations with each of the row's items. Here is some pseudo code:
c = array[0]; //read: the first row of the array
for(var i = 1; i < m; ++i) { //iterate all rows
var c_modified = [];
for(var j = 0; j < n; ++j) { //iterate all row entries
for(var k = 0; k < c.length; ++k) { //iterate all entries of c
add c[k].array[i, j] to c_modified; // . represents concatenation
}
}
c = c_modified;
}
This combination of elements (n^m sets) is called Cartesian product. There are ready-to-use functions for its generation in some language libraries
I believe that the simplest code is recursive one.
type
TArr2D = TArray<TArray<Integer>>;
procedure CartesianProduct(const A: TArr2D; Line: Integer; Reslt: TArray<Integer>);
var
i: integer;
begin
if Line > High(A) then
Memo1.Lines.Add(ArrayToString(Reslt)) // output m-element set
else
for i in A[Line] do
CartesianProduct(A, Line + 1, Reslt + [i]); // include element in set
end;
var
A: TArr2D;
n, m, i, j: Integer;
begin
m := 3;
n := 3;
SetLength(A, m, n);
for j := 0 to m - 1 do
for i := 0 to n - 1 do
A[j, i] := j * n + i;
//0 1 2
//3 4 5
//6 7 8
CartesianProduct(A, 0, []);
gives
0 3 6
0 3 7
0 3 8
0 4 6
0 4 7
0 4 8
0 5 6
0 5 7
0 5 8
1 3 6
1 3 7
1 3 8
1 4 6
1 4 7
1 4 8
1 5 6
1 5 7
1 5 8
2 3 6
2 3 7
2 3 8
2 4 6
2 4 7
2 4 8
2 5 6
2 5 7
2 5 8
I am solving a hailstone problem, but with a twist, you are given the length, find the value of x if the hailstone starts with 1
I thought it could be determined, if I alternatively change odd and even, and reverse the equation like so:
function r(len, prev, isEven) {
if(len < 1) return prev;
if(isEven) {
return r(len - 1, prev * 2, !isEven);
} else {
return r(len - 1, (prev - 1) * 3, !isEven);
}
}
Now I realized it wasn't just alternate seq., what mathematical concept should I apply in this problem.
Example:
if Len = 8, answer is 6
since:
6 -> 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
Just output 2^len :)
Imagine, for len = 8, 6 is a valid answer, because 6 -> 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
again, 2^len = 2^8 = 256 is also valid, because 256 -> 128 -> 64 -> 32 -> 16 -> 8 -> 4 -> 2 -> 1
function r(len , pre){
if (len <1) return prev
if ((pre-1)/3 == 1 && (pre-1)%3== 0) || ((pre-1)/3 > 1 && (pre-1)%3 != 0) || (pre<=3 && pre>=1) {
return r(len-1 , 2*pre)
}
elsif((pre-1)/3 > 1 && (pre-1)%3 == 0){
return r(len-1 , (pre-1)/3)
}
}
I can't get GraphViz to respect some node positions, even though they have pos attributes with !. E.g.:
digraph Versions {
ranksep=0.05;
node [style=filled, shape=point, fillcolor=black, fixedsize=true, width=0.3, height=0.1, fontname="Helvetica", fontsize=8, fontcolor=white];
edge [arrowhead=none, len=0.1];
2 [pos="0,0!", fillcolor=red];
3 [pos="20,0!", fillcolor=red];
4 [pos="40,0!", fillcolor=red];
5 [pos="60,0!", fillcolor=red];
6 [pos="80,0!", fillcolor=red];
7 [pos="100,0!", fillcolor=red];
8 [pos="120,0!", fillcolor=red];
9 [pos="140,0!", fillcolor=red];
10 [pos="160,0!", fillcolor=red];
11 [pos="180,0!", fillcolor=red];
12 [pos="200,0!", fillcolor=red];
13 [pos="220,0!", fillcolor=red];
2 -> 14;
14 -> 15;
3 -> 16;
16 -> 17;
11 -> 18;
18 -> 19;
6 -> 20;
20 -> 21;
10 -> 22;
22 -> 23;
13 -> 24;
24 -> 25;
9 -> 26;
26 -> 27;
4 -> 28;
28 -> 29;
7 -> 30;
30 -> 31;
5 -> 32;
32 -> 33;
8 -> 34;
34 -> 35;
12 -> 36;
36 -> 37;
15 -> 38;
38 -> 39;
17 -> 40;
40 -> 41;
19 -> 42;
42 -> 43;
// etc.
}
The top most rank should be evenly distributed, but is not. The horizontal spacing between the top most nodes is not the same:
From the documentation of the pos attribute:
In neato and fdp, pos can be used to set the initial position of a node.
Are you using neato or fdp? Because dot does not respect this attribute.
Assuming you're using neato, here's an excerpt from the manual:
-n[1|2] (no-op) If set, neato assumes nodes have already been positioned and all nodes have a pos attribute giving the positions
This means you can render a graph with
neato -n2 -Tpng mygraph.gv -o mygraph.png
and have neato respect the pos attributes (in points) of the nodes.
This also states that all nodes must have a pos attribute.
Since some nodes of your graph do not have a pos attribute, this will lead to an error.
I have a test graph here that I would like to tweak to make it look nicer.
Here is the graphviz (dot) source, test6.dot:
digraph G {
ranksep=0.3; size="6.0,6.0";
node [fontsize=11];
subgraph clusterA {
X2 [shape=box];
node [style=filled];
1 -> 2 -> 3 -> X2 -> 5;
6;
7;
label = "A";
color=blue
}
X1 [shape=box];
subgraph clusterB {
node [style=filled];
8;
9;
10 -> 11 -> 12;
12 -> 9;
12 -> 8 -> 13;
13 -> 14;
label = "B";
color=blue
}
subgraph clusterC {
label = "C";
{
node [style="invis"];
gap;
}
node [shape=box];
edge [style="invis"];
X3 -> gap -> X4;
}
14 -> X4 -> 3;
6 -> X1 -> 10;
{ edge [dir="both"];
8 -> X3 -> 7;
}
9 -> X3
}
Questions / changes I would like to make:
I want the flow of nodes 10 -> 11 -> 12 -> 8 -> 13 -> 14 to be in a vertical line (swap 8 and 9 horizontally). How can I do this? (same with 1 -> 2 -> 3 -> X2 -> 5; swap 6 and 1)
I want X1 to be at the same vertical position as 10, and the same horizontal position as 6. How can I do this?
I want 8 and X3 and 7 to be at the same vertical position, also with 14 and X4 and 3. How can I do this?
The ranksep=0.3; statement works great except note that 8 -> 13 -> 14 has a larger gap, as does X3 -> gap -> X4. Why doesn't it obey the ranksep=0.3 rule, and how do I fix this?
Below is the best I can do: phantom nodes and edges help. But I can't seem to encourage a particular ordering in the transverse direction (the other direction from rankdir).
digraph G {
ranksep=0.3; size="6.0,6.0";
rankdir=TB;
node [fontsize=11];
subgraph clusterA {
X2 [shape=box];
label = "A";
color=blue;
node [style=filled];
/* force 1, 6, and 7 to be at the top together,
add enough phantoms to keep things in nice columns */
{
node [style="invis", label=""];
phantom3;
phantom4;
phantom5;
phantom6;
}
rank = same;
1 -> 2 -> 3 -> X2 -> 5;
edge [style="invis"];
6 -> phantom3 -> phantom5;
7 -> phantom4 -> phantom6;
}
subgraph clusterB {
node [style=filled];
label = "B";
color=blue;
/* create an invisible phantom node
to take up space */
{
node [style="invis",label=""];
phantom1;
phantom1b;
}
{ rank=same; 11;
phantom1;
}
10 -> 11 -> 12 -> 8 -> 13 -> 14;
12 -> 9;
phantom1 -> 9 -> phantom1b [style="invis"];
}
/* force X1 to be at the same vertical pos as 10
(this yields a warning though) */
{ rank = same;
X1 [shape=box];
10;
}
6 -> X1;
X1 -> 10 [weight=0.5];
subgraph clusterC {
label = "C";
phantom2 [style="invis", label=""];
node [shape=box];
edge [style="invis"];
X3 -> phantom2 -> X4;
}
9 -> X3 [weight=0.5];
{
edge [weight=20];
14 -> X4 -> 3;
3 -> X4 -> 14 [style="invis"];
/* add a reverse path so graphviz doesn't force 14 above X4 above 3 */
}
{
edge [dir="both", weight=20];
8 -> X3 -> 7;
7 -> X3 -> 8 [style="invis"];
edge [style="invis"];
X4 -> phantom6;
1 -> phantom2;
8 -> phantom2;
}
}