How can I represent a set in ampl into a vector in c++? - c++

I have two sets in ampl to be implemented in c++, set NS and set S.
But I'm not understanding the set S very well.
set N ordered := {1..n};
set NS ordered := 1..(2**n-1);
set S {s in NS} := {i in N: (s div 2**(ord(i)-1)) mod 2 = 1};
If n = 4, I will have:
set N := 1 2 3 4
set NS := 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15;
set S[1] := 1;
set S[2] := 2;
set S[3] := 1 2;
set S[4] := 3;
set S[5] := 1 3;
set S[6] := 2 3;
set S[7] := 1 2 3;
set S[8] := 4;
set S[9] := 1 4;
set S[10] := 2 4;
set S[11] := 1 2 4;
set S[12] := 3 4;
set S[13] := 1 3 4;
set S[14] := 2 3 4;
set S[15] := 1 2 3 4;
The first set can be easily created.
vector <int> NS;
int auxMax = pow(2,n)-1;
for (int i = 0; i < auxMax; i++) {
NS.push_back(i);
}
Although I know how the operators div (returns the truncated quotient when its left operand is divided by its right operand), mod (computes the remainder) and ord(returns the numerical position of [i] within the set N) work, I'm not able to make a struct of "for" to fed set S.
Can anyone help me understanding the generation of set S and transforming it to a vector in c++?
Thank you!

Im not familiar with ampl, but I'll give it a go:
Assuming I understood that {} translates to some form of vector type.
Result is the following:
int main()
{
const int n = 4;
int NS = pow(2, n) - 1;
std::vector< std::vector<int> > S;
for (int s = 1; s <= NS; s++) // {s in NS}
{
std::vector<int> iN;
for (int ord_i = 1; ord_i <= n; ord_i++) // {i in N}
{
if ((s / (int)pow(2, ord_i - 1)) % 2 == 1)
iN.push_back(ord_i);
}
S.push_back(iN);
}
}

Related

How to make lemmas about changes made to heap objects?

I'm trying to implement a MaxHeap using Dafny based on the code from Intro. to Algorithms, CLRS 3rd edition, section 6.1, page 153 or the Max-Heapify function here. I switched from using recursion to a while loop because that seemed a bit easier to handle in Dafny.
Trying to prove the heap property on an array after calling the heapify function. In particular I was hoping to be able to use the require statement on heapify to assert that triples which didn't change in the heap which were satisfying the heap property before an update, are satisfying the heap property after the update.
However, after making any changes to the array it seems like it forgets all about the require/invariant statement. Even if I show that the value are the same before and after the update it still no longer passes the assertion. I pulled out the update into the swap method.
I was hoping I could write a lemma asserting this fact but it seems like lemmas don't allow modifying the heap or using old() or calling a method. Is there a way to write a lemma for this?
function method parent(i: int): int
{
i/2
}
function method left(i: int): int
{
2*i
}
function method right(i: int): int
{
2*i+1
}
class MaxHeap {
var data: array<int>
ghost var repr: set<object>
constructor(data: array<int>)
ensures this.data == data
ensures this in repr
{
this.data := data;
this.repr := {this};
}
predicate method MaxHeapChildren(i: int)
reads this, this.data
requires 1 <= i
{
(left(i) > this.data.Length || this.data[i-1] >= this.data[left(i)-1]) && (right(i) > this.data.Length || this.data[i-1] >= this.data[right(i)-1])
}
method heapify(i: int) returns (largest: int)
modifies this.data
requires 1 <= i <= this.data.Length
requires forall x :: i < x <= this.data.Length ==> MaxHeapChildren(x)
// ensures multiset(this.data[..]) == multiset(old(this.data[..]))
ensures forall x :: i <= x <= this.data.Length ==> MaxHeapChildren(x)
decreases this.data.Length - i
{
var i' := i;
ghost var oldi := i;
largest := i;
var l := left(i);
var r := right(i);
ghost var count := 0;
ghost var count' := 1;
while !MaxHeapChildren(i')
invariant count' == count + 1;
invariant 1 <= largest <= this.data.Length
invariant l == left(i')
invariant r == right(i')
invariant 1 <= i' <= this.data.Length
invariant i' == i || i' == left(oldi) || i' == right(oldi)
invariant largest == i'
invariant count == 0 ==> oldi == i
invariant oldi > 0
invariant count > 0 ==> oldi == parent(i')
invariant count > 0 ==> MaxHeapChildren(oldi)
invariant count > 0 ==> forall x :: i <= x < i' ==> old(this.data)[x] == this.data[x]
invariant count > 0 ==> forall x :: i <= x < i' && left(x+1) < this.data.Length ==> old(this.data)[left(x+1)] == this.data[left(x+1)]
invariant count > 0 ==> forall x :: i <= x < i' && right(x+1) < this.data.Length ==> old(this.data)[right(x+1)] == this.data[right(x+1)]
// invariant count > 0 ==> forall x :: i <= x <= i' && left(x+1) ==> MaxHeapChildren(left(x+1))
invariant forall x :: i <= x <= this.data.Length && x != i' ==> MaxHeapChildren(x)
decreases this.data.Length-i';
{
if l <= this.data.Length && this.data[l-1] > this.data[i'-1] {
largest := l;
}
if r <= this.data.Length && this.data[r-1] > this.data[largest-1] {
largest := r;
}
if largest != i' {
assert forall x :: i < x <= this.data.Length && x != i' ==> MaxHeapChildren(x);
swap(this, i', largest);
label AfterChange:
oldi := i';
assert MaxHeapChildren(oldi);
i' := largest;
assert forall x :: largest < x <= this.data.Length && x != i' ==> MaxHeapChildren(x);
l := left(i');
r := right(i');
assert forall x :: i <= x < i' ==> old#AfterChange(this.data[x]) == this.data[x] && left(x+1) < this.data.Length ==> old(this.data)[left(x+1)] == this.data[left(x+1)] && right(x+1) < this.data.Length ==> old(this.data)[right(x+1)] == this.data[right(x+1)];
}else{
assert MaxHeapChildren(i');
assert MaxHeapChildren(oldi);
}
count := count + 1;
count' := count' + 1;
}
}
}
method swap(heap: MaxHeap, i: int, largest: int)
modifies heap.data
requires 1 <= i < largest <= heap.data.Length
requires heap.data[largest-1] > heap.data[i-1]
requires left(i) <= heap.data.Length ==> heap.data[largest-1] >= heap.data[left(i)-1]
requires right(i) <= heap.data.Length ==> heap.data[largest-1] >= heap.data[right(i)-1]
requires forall x :: i <= x <= heap.data.Length && x != i ==> heap.MaxHeapChildren(x)
ensures heap.data[i-1] == old(heap.data[largest-1])
ensures heap.data[largest-1] == old(heap.data[i-1])
ensures heap.MaxHeapChildren(i)
ensures forall x :: 1 <= x <= heap.data.Length && x != i && x != largest ==> heap.data[x-1] == old(heap.data[x-1])
ensures forall x :: i <= x <= heap.data.Length && x != largest ==> heap.MaxHeapChildren(x)
{
ghost var oldData := heap.data[..];
var temp := heap.data[i-1];
heap.data[i-1] := heap.data[largest-1];
heap.data[largest-1] := temp;
var z:int :| assume i < z <= heap.data.Length && z != largest;
var lz: int := left(z);
var rz: int := right(z);
assert heap.data[z-1] == old(heap.data[z-1]);
assert lz != i && lz != largest && lz <= heap.data.Length ==> heap.data[lz-1] == old(heap.data[lz-1]);
assert rz != i && rz != largest && rz <= heap.data.Length ==> heap.data[rz-1] == old(heap.data[rz-1]);
assert heap.MaxHeapChildren(z);
}
/**
heapify(4)
length = 17
i = 4
left = 8, 7 (0based)
right = 9, 8 (0based)
x in 5 .. 17 :: MaxHeapChildren(x) (i+1)..17
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
[20,18,16,3,14,12,10, 8, 6, 4, 2, 0, 1,-2, 4, 4,-5]
i = 8
left = 16
right = 17
x in i' .. i-1 :: MaxHeapChildren (4..15)
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
[20,18,16,8,14,12,10, 3, 6, 4, 2, 0, 1,-2, 4, 4,-5]
i = 16
left = 32
right = 33
x in i' .. i-1 :: MaxHeapChildren (4..16) + 17.. MaxHeapChildren
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
[20,18,16,8,14,12,10, 4, 6, 4, 2, 0, 1,-2, 4, 3,-5]
*/
Yes, I think what you are looking for is called a twostate lemma
Basically, you can use old() in their specification, and at the call site, you can specify which heap to consider for calls to old() by suffixing the lemma's name by #a, if label a: existed before that method's call.

how to calculate multiset of elements given probability on each element?

let say I have a total number
tN = 12
and a set of elements
elem = [1,2,3,4]
and a prob for each element to be taken
prob = [0.0, 0.5, 0.75, 0.25]
i need to get a random multiset of these elements, such as
the taken elements reflects the prob
the sum of each elem is tN
with the example above, here's some possible outcome:
3 3 2 4
2 3 2 3 2
3 4 2 3
2 2 3 3 2
3 2 3 2 2
at the moment, maxtN will be 64, and elements the one above (1,2,3,4).
is this a Knapsack problem? how would you easily resolve it? both "on the fly" or "pre-calculate" approch will be allowed (or at least, depends by the computation time). I'm doing it for a c++ app.
Mission: don't need to have exactly the % in the final seq. Just to give more possibility to an elements to be in the final seq due to its higher prob. In few words: in the example, i prefer get seq with more 3-2 rather than 4, and no 1.
Here's an attempt to select elements with its prob, on 10 takes:
Randomizer randomizer;
int tN = 12;
std::vector<int> elem = {2, 3, 4};
std::vector<float> prob = {0.5f, 0.75f, 0.25f};
float probSum = std::accumulate(begin(prob), end(prob), 0.0f, std::plus<float>());
std::vector<float> probScaled;
for (size_t i = 0; i < prob.size(); i++)
{
probScaled.push_back((i == 0 ? 0.0f : probScaled[i - 1]) + (prob[i] / probSum));
}
for (size_t r = 0; r < 10; r++)
{
float rnd = randomizer.getRandomValue();
int index = 0;
for (size_t i = 0; i < probScaled.size(); i++)
{
if (rnd < probScaled[i])
{
index = i;
break;
}
}
std::cout << elem[index] << std::endl;
}
which gives, for example, this choice:
3
3
2
2
4
2
2
4
3
3
Now i just need to build a multiset which sum up to tN. Any tips?

How to find the value of k after the following pseudocode has been executed?

What is the value of k after the following pseudocode has been executed?
k := 0
for i1 := 1 to n1
k := k + 1
for i2 := 1 to n2
k := k + 1
...
for im := 1 to nm
k := k + 1
[EDIT based on modified question]
Since the loops are NOT nested inside one another, each loop will simply increment k n_i times.
Therefore, the final value is
k = n1 + n2 + ... + nm

Histogram of the distribution of dice rolls

I saw a question on careercup, but I do not get the answer I want there. I wrote an answer myself and want your comment on my analysis of time complexity and comment on the algorithm and code. Or you could provide a better algorithm in terms of time. Thanks.
You are given d > 0 fair dice with n > 0 "sides", write an function that returns a histogram of the frequency of the result of dice rolls.
For example, for 2 dice, each with 3 sides, the results are:
(1, 1) -> 2
(1, 2) -> 3
(1, 3) -> 4
(2, 1) -> 3
(2, 2) -> 4
(2, 3) -> 5
(3, 1) -> 4
(3, 2) -> 5
(3, 3) -> 6
And the function should return:
2: 1
3: 2
4: 3
5: 2
6: 1
(my sol). The time complexity if you use a brute force depth first search is O(n^d). However, you can use the DP idea to solve this problem. For example, d=3 and n=3. You can use the result of d==1 when computing d==2:
d==1
num #
1 1
2 1
3 1
d==2
first roll second roll is 1
num # num #
1 1 2 1
2 1 -> 3 1
3 1 4 1
first roll second roll is 2
num # num #
1 1 3 1
2 1 -> 4 1
3 1 5 1
first roll second roll is 3
num # num #
1 1 4 1
2 1 -> 5 1
3 1 6 1
Therefore,
second roll
num #
2 1
3 2
4 3
5 2
6 1
The time complexity of this DP algorithm is
SUM_i(1:d) {n*[n(d-1)-(d-1)+1]} ~ O(n^2*d^2)
~~~~~~~~~~~~~~~ <--eg. d=2, n=3, range from 2~6
The code is written in C++ as follows
vector<pair<int,long long>> diceHisto(int numSide, int numDice) {
int n = numSide*numDice;
vector<long long> cur(n+1,0), nxt(n+1,0);
for(int i=1; i<=numSide; i++) cur[i]=1;
for(int i=2; i<=numDice; i++) {
int start = i-1, end = (i-1)*numSide; // range of previous sum of rolls
//cout<<"start="<<start<<" end="<<end<<endl;
for(int j=1; j<=numSide; j++) {
for(int k=start; k<=end; k++)
nxt[k+j] += cur[k];
}
swap(cur,nxt);
for(int j=start; j<=end; j++) nxt[j]=0;
}
vector<pair<int,long long>> result;
for(int i=numDice; i<=numSide*numDice; i++)
result.push_back({i,cur[i]});
return result;
}
You can do it in O(n*d^2). First, note that the generating function for an n-sided dice is p(n) = x+x^2+x^3+...+x^n, and that the distribution for d throws has generating function p(n)^d. Representing the polynomials as arrays, you need O(nd) coefficients, and multiplying by p(n) can be done in a single pass in O(nd) time by keeping a rolling sum.
Here's some python code that implements this. It has one non-obvious optimisation: it throws out a factor x from each p(n) (or equivalently, it treats the dice as having faces 0,1,2,...,n-1 rather than 1,2,3,...,n) which is why d is added back in when showing the distribution.
def dice(n, d):
r = [1] + [0] * (n-1) * d
nr = [0] * len(r)
for k in xrange(d):
t = 0
for i in xrange(len(r)):
t += r[i]
if i >= n:
t -= r[i-n]
nr[i] = t
r, nr = nr, r
return r
def show_dist(n, d):
for i, k in enumerate(dice(n, d)):
if k: print i + d, k
show_dist(6, 3)
The time and space complexity are easy to see: there's nested loops with d and (n-1)*d iterations so the time complexity is O(n.d^2), and there's two arrays of size O(nd) and no other allocation, so the space complexity is O(nd).
Just in case, here a simple example in Python using the OpenTurns platform.
import openturns as ot
d = 2 # number of dice
n = 6 # number of sides per die
# possible values
dice_distribution = ot.UserDefined([[i] for i in range(1, n + 1)])
# create the sum distribution d times the sum
sum_distribution = sum([dice_distribution] * d)
That's it!
print(sum_distribution)
will show you all the possible values and their corresponding probabilities:
>>> UserDefined(
{x = [2], p = 0.0277778},
{x = [3], p = 0.0555556},
{x = [4], p = 0.0833333},
{x = [5], p = 0.111111},
{x = [6], p = 0.138889},
{x = [7], p = 0.166667},
{x = [8], p = 0.138889},
{x = [9], p = 0.111111},
{x = [10], p = 0.0833333},
{x = [11], p = 0.0555556},
{x = [12], p = 0.0277778}
)
You can also draw the probability distribution function:
sum_distribution.drawPDF()

C++ get every number separately

I have a range of numbers from 100 to 999. I need to get every number separately of it and check whether it can be divided by 2. For example:
232
2 divided by 2 = 1 = true
3 divided by 2 = 1.5 = false
2 divided by 2 = 1 = true
and so on.
To get the first number all I have to do is to divide the entire number by 100.
int x = 256;
int k = x/100;
so x would hold a value of 2.
Now, is there a way to check those other ones? Because k = x/10; would already be 25.
Try this:
int x = 256;
int i = x / 100; // i is 2
int j = (x % 100) / 10; // j is 5
int k = (x % 10); // k is 6
maybe look into integer division and the modulo.
int k1 = (x / 10) % 10 // "10s"
int k2 = ( x / 100 ) % 10 // "100s"
//etc etc
Use modulo to get the last digit of the number, then divide by ten to discard the last digit.
Repeat while the number is non-zero.
What you need is the modulus operator %. It does a division and returns the reminder.
1 % 2 = 1
2 % 2 = 0
3 % 2 = 1
4 % 2 = 0
...
eg. take 232:
int num = 232;
int at_ones_place = num % 10;
int at_tens_place = ( num /10 ) % 10 ;
int at_hundreds_place = (num /100);