hamiltonian cycle in a group - graph

The group elements are generated by (g, 1, 1, ...), (1, g, 1, ... ), (1, 1, g, ...) ... that is have a form (g^i1, g^i2, ... ) where g^p = 1 for some p.
There is an edge between elements in the group where elements at some index have powers of g different by 1 modulo p, that is g^1 and g^2 have a bidirectional edge for p = 4, but g^1 and g^3 do not.
Does there always exist a Hamiltonian cycle in such a group? What kind of structure does it have?
Example
For g = 1 under addition modulo 2 (0, 0, ... 1, 0, 0, 0) generate vertices of a hypercube. So the question is if there is a Hamiltonian cycle in the hypercube.

Related

Best way to identify duplicates in two lists or a dictionary?

Lets say you have two lists such as:
list1 = [-2, -1, 0, 1, 2, 3]
list2 = [4, 1, 0, 1, 4, 9]
...and the two lists were zipped into a dictionary to produce:
dict1 = {-2: 4,
-1: 1,
0: 0,
1: 1,
2: 4,
3: 9}
...where list1 is the key, and list 2 is the value.
You will notice that some of the elements in list2 are duplicates such as 4 and 1. They show up twice in list 2, and consequently in the dictionary.
-2 corresponds to 4
2 corresponds to 4
-1 corresponds to 1
1 corresponds to 1
I am trying to figure out a way either using the lists or the dictionary to identify the duplicate items in list2, and return their keys from list 1.
So the returned values I would expect from the two lists above would be:
(-2, 2) #From list 1 since they both correspond to 4 in list2
(-1, 1) #from list 1 since they both correspond to 1 in list2
In this example, list2 happens to be the square of list1. But this will not always be the case.
So ultimately, what I am looking for is a way to return those keys based on their duplicate values.
Any thoughts on how to approach this? I am able to identify the duplicates in list2, but I am completely stuck on how to identify their corresponding values in list 1.
In python3:
from itertools import groupby
list1 = [-2, -1, 0, 1, 2, 3]
list2 = [4, 1, 0, 1, 4, 9]
pairs = zip(list2, list1)
ordered = sorted(pairs, key=lambda x: x[0])
groups = ((k, list(g)) for k,g in groupby(ordered, key=lambda x: x[0])) # generator
duplicates = (k for k in groups if len(k[1])>1) # generator
for k,v in duplicates :
print(str(k) + " : " + str(list(v)))
result:
1 : [(1, -1), (1, 1)]
4 : [(4, -2), (4, 2)]
Bonus: in functional c#:
var list1 = new[] { -2, -1, 0, 1, 2, 3 };
var list2 = new[] { 4, 1, 0, 1, 4, 9 };
var g = list1.Zip(list2, (a, b) => (a, b)) //create tuples
.GroupBy(o => o.b, o => o.a, (k, group) => new { key = k, group = group.ToList() }) //create groups
.Where(o => o.group.Count > 1) // select group with minimum 2 elements
.ToList(); // no lazy
foreach (var kvp in g)
Console.WriteLine($"{kvp.key}: {string.Join(",", kvp.group)}");
result:
4: -2,2
1: -1,1

How would I traverse between these two arrayLists with a value-key relationship (Java)?

Let's say, for example, I have two arrayLists. One has strings in the form of:
[a, b, a, a, c, a, d, b, d, b]
The other has integers in the form of:
[1, 4, 2, 3, 5, 5, 6, 2, 5, 1]
In this case, "a" has/maps to values 1, 2, 3, and 5 (because "a" is at index 0, 2, 3, 5 in arrayList 1, and the values at index 0, 2, 3, 5 in arrayList 2 are 1, 2, 3, and 5). "b" has values 4, 2, and 1. "c" has value 5. "d" has values 6 and 5.
Now I want to create a Map from these two arrayLists in the form of:
[(a, 11), (b, 7), (c, 5), (d, 11)]
where the value each string key is matched with is the sum of all its corresponding values in arrayList 2.
Any pointers on an efficient way to go about implementing this in Java?
Thanks.
This kind of operation is, abstractly, "zipping". The stream of Java 8 works great here.
Map<String, Integer> m = IntStream.range(0, stringList.size()) // indices
.boxed() // Stream<Integer>
.collect(Collectors.toMap(
stringList::get, // keyMapper
intList::get, // valueMapper
(x, y) -> x + y // mergeFunction for values when they have the same key
));
This code assumes that intList is the same size as, or longer than stringList. If intList can be shorter and you want to map the missing values to 0, you can modifiy the valueMapper from a method reference to a lambda.

How to add free edge to graph in LightGraphs (Julia)?

I am adding edges to a simple weighted directed graph (from SimpleWeightedDiGraph() that is part of LightGraphs package) in Julia. Some of the arcs are "free" (null weight). However, when specifying the weight of 0 it is not added as a new edge and a shortest path problem does not include it in the possible solution. Is there an easy way to add "free" edges/arcs to a graph in Julia?
The key issue is how zero values are represented in a sparse matrix (which is the underlying data store for SimpleWeightedGraphs. While it is true that the underlying zero value is preserved once it's explicitly set:
julia> g = SimpleWeightedGraph(6)
{6, 0} undirected simple Int64 graph with Float64 weights
julia> add_edge!(g, 1, 2, 1.0)
true
julia> add_edge!(g, 1, 3, 1.0)
true
julia> add_edge!(g, 1, 3, 0.0)
true
julia> weights(g)
6×6 SparseMatrixCSC{Float64,Int64} with 4 stored entries:
[2, 1] = 1.0
[3, 1] = 0.0
[1, 2] = 1.0
[1, 3] = 0.0
this will fail if you have to do anything with the edges:
julia> collect(edges(g))
1-element Array{SimpleWeightedGraphs.SimpleWeightedEdge{Int64,Float64},1}:
Edge 1 => 2 with weight 1.0
There's no really good solution to this. My advice is to use a sufficiently small weight as proposed above to approximate a zero value.
(PS: the reason the initial add_edge!(g, 1, 3, 0.0) doesn't work is because in Julia, setting the value of a new sparsematrix element to zero is a no-op.)
This modification of the SimpleWeightedGraphs README example works for me:
using LightGraphs, SimpleWeightedGraphs
# set the size of the graph
g = SimpleWeightedDiGraph(3)
add_edge!(g, 1, 2, 0.5)
add_edge!(g, 2, 3, 0.8)
add_edge!(g, 1, 3, 2.0)
# find the shortest path from vertex 1 to vertex 3 taking weights into account.
enumerate_paths(dijkstra_shortest_paths(g, 1), 3) # gives [1,2,3]
# reweight the edge from 1 to 3 to be "free"
add_edge!(g, 1, 3, 0.0)
enumerate_paths(dijkstra_shortest_paths(g, 1), 3) # gives [1,3]
Notice that the vertices must be in the graph (according to its size) to be able to set their weights, as stated in the docs: ?add_edge!.

MPI Communication Pattern

I was wondering if there was a smart way to do this. Let's say I have three nodes, 0, 1, 2. And let's say each node has an array, a0, a1, a2. If the contents of each node is something like
a0 = {0, 1, 2, 1}
a1 = {1, 2, 2, 0}
a2 = {0, 0, 1, 2}
Is there a clever communication pattern so to move each number to it's corresponding node, i.e.
a0 = {0, 0, 0, 0}
a1 = {1, 1, 1, 1}
a2 = {2, 2, 2, 2}
The approach I have in mind, would involve sorting and temporary buffers, but I was wondering if there was a smarter way?
You can use MPI_Alltoallv for this in the following way:
Sort the local_data (a) by corresponding node of each element in increasing order.
Create a send_displacements array such that send_displacements[r] indicates the index of the first element in the local_data that refers to node r.
Create a send_counts array such that send_counts[r] equals the number of elements in local_data that correspond to node r. This can be computed send_counts[r] = send_displacements[r+1] - send_displacements[r] except for the last rank.
MPI_Alltoall(send_counts, 1, MPI_INT, recv_counts, 1, MPI_INT, comm)
Compute recv_displacements such that recv_displacements[r] = sum(recv_counts[r'] for all r' < r).
Prepare a recv_data with sum(recv_counts) elements.
MPI_Alltoallv(local_data, send_counts, send_displacements, MPI_INT, recv_data, recv_counts, recv_displacements, MPI_INT, comm)

Mathematica: part assignment

I'm trying to implement an algorithm to build a decision tree from a dataset.
I wrote a function to calculate the information gain between a subset and a particular partition, then I try all the possible partition and want to choose the "best" partition, in the sense that it's got the lowest entropy.
This procedure must be recursive, hence, after the first iteration, it needs to work for every subset of the partition you got in the previous step.
These are the data:
X = {{1, 0, 1, 1}, {1, 1, 1, 1}, {0, 1, 1, 1}, {1, 1, 1, 0}, {1, 1, 0, 0}}
Xfin[0]=X
This is the function: for every subset of the partition, it tries all the possible partitions and calculate the IG. Then it selects the partition with IGMAX:
Partizioneottimale[X_, n_] :=
For[l = 1, l <= Length[Flatten[X[n], n - 1]], l++,
For[v = 1, v <= m, v++,
If[IG[X[n][[l]], Partizione[X[n][[l]], v]] == IGMAX[X[n][[l]]],
X[n + 1][[l]] := Partizione[X[n][[l]], v]]]]
then I call it:
Partizioneottimale[Xfin, 0]
and it works fine for the first one:
Xfin[1]
{{{1, 0, 1, 1}, {1, 1, 1, 1}, {0, 1, 1, 1}, {1, 1, 1, 0}}, {{1, 0, 0, 0}}}
That is the partition with lowest entropy.
But it doesn't work for the next ones:
Partizioneottimale[Xfin, 1]
Set delayed::steps : Xfin[1+1] in the part assignment is not a symbol
Has anybody any idea about how to solve this?
Thanks
without unraveling all your logic a simple fix is this:
Partizioneottimale[X_, n_] := (
xnp1 = Table[Null, {Length[Flatten[X[n], n - 1]]}] ;
For[l = 1, l <= Length[Flatten[X[n], n - 1]], l++,
For[v = 1, v <= m, v++,
If[IG[X[n][[l]], Partizione[X[n][[l]], v]] == IGMAX[X[n][[l]]],
xnp1[[l]] = Partizione[X[n][[l]], v]]]] ;
X[n+1] = xnp1 ; )

Resources