ant colony optimisation for 01 MKP - c++

I'm trying to implement an ACO for 01MKP. My input values are from the OR-Library mknap1.txt. According to my algorithm, first I choose an item randomly. then i calculate the probabilities for all other items on the construction graph. the probability equation depends on pheremon level and the heuristic information.
p[i]=(tau[i]*n[i]/Σ(tau[i]*n[i]).
my pheremon matrix's cells have a constant value at initial (0.2). for this reason when i try to find the next item to go, pheremon matrix is becomes ineffective because of 0.2. so, my probability function determines the next item to go, checking the heuristic information. As you know, the heuristic information equation is
n[i]=profit[i]/Ravg.
(Ravg is the average of the resource constraints). for this reason my prob. functions chooses the item which has biggest profit value. (Lets say at first iteration my algorithm selected an item randomly which has 600 profit. then at the second iteration, chooses the 2400 profit value. But, in OR-Library, the item which has 2400 profit value causes the resource violation. Whatever I do, the second chosen is being the item which has 2400 profit.
is there anything wrong my algorithm? I hope ppl who know somethings about ACO, should help me. Thanks in advance.
Input values:
6 10 3800//no of items (n) / no of resources (m) // the optimal value
100 600 1200 2400 500 2000//profits of items (6)
8 12 13 64 22 41//resource constraints matrix (m*n)
8 12 13 75 22 41
3 6 4 18 6 4
5 10 8 32 6 12
5 13 8 42 6 20
5 13 8 48 6 20
0 0 0 0 8 0
3 0 4 0 8 0
3 2 4 0 8 4
3 2 4 8 8 4
80 96 20 36 44 48 10 18 22 24//resource capacities.
My algorithm:
for i=0 to max_ant
for j=0; to item_number
if j==0
{
item=rand()%n
ant[i].value+=profit[item]
ant[i].visited[j]=item
}
else
{
calculate probabilities for all the other items in P[0..n]
find the biggest P value.
item=biggest P's item.
check if it is in visited list
check if it causes resource constraint.
if everthing is ok:
ant[i].value+=profit[item]
ant[i].visited[j]=item
}//end of else
}//next j
update pheremon matrix => tau[a][b]=rou*tau[a][b]+deltaTou
}//next i

Related

Circular traverse of parameter values algorithm [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 days ago.
Improve this question
Could you pls. help with algorithm (I use C++) which seemed so simple at first glance.
I need a total enumeration of all combinations of N parameters to run some target function for all combination and choose one optimal combination.
Let say there are three parameters (it can be any number set by user but for this example let’s assume 3)
Possible values (can be any number for any parameter - NOT a fixed number - number of values set a user before program starts)
name
value
value
value
value
param1
1
2
..
param2
10
20
..
param3
100
200
300
..
So the number of combinations = 12 (2 * 2 * 3 = 12)
All combinations
#
param1
param2
param3
1
1
10
100
2
2
10
100
3
1
20
100
4
2
20
100
5
1
10
200
6
2
10
200
7
1
20
200
8
2
20
200
9
1
10
300
10
2
10
300
11
1
20
300
12
2
20
300
Ok – let say the order may be different
#
param1
param2
param3
1
1
10
100
2
1
20
100
3
1
10
200
4
1
20
200
5
1
10
300
6
1
20
300
7
2
10
100
8
2
20
100
9
2
10
200
10
2
20
200
11
2
10
300
12
2
20
300
However it’s obviously one counter should change while others fixed and after one counter finish increment next in the chain
This approach seems quite simple but I still can’t find an implementation. I thought use a list for the parameters and as one counter finish itereates it's values it call the next parameter and increment next parameter value and reset the first parameter counter. But how put it in couple of loops … ? I intuitively feels it should be quite simple solution.
The another approach I think – use all combinations to build a graph and after that traverse the whole graph and in the end get an optimal combination. But if I fill the graph it means I already solve this problem and building a graph just a waste of time and memory.
For now there is a sketch (in pseudo-code) like this:
std::list<param> params
bool isDone = false
func(node* n)
{
if(n->prev)
{
n->GetCurrentValue() // return current value and increment by one
n->prev->reset();
func(n->prev)
Run(); // target function
if(n->IsDone()) // finish end of the values
{
if(n->next)
func(n->next);
else
isDone = true;
}
}
else // first node in the list
{
while(n->IsDone()) // finish end of the values
{
n->GetCurrentValue() // return current value and increment by one
Run() // target function
}
n.reset() // set internal counter for the node to 0
func(n->next())
}
}
while(!isDone)
{
for(p : params)
{
func(p)
}
}

How to retain calculated values between rows when calculating running totals?

I have a tricky question about conditional sum in SAS. Actually, it is very complicated for me and therefore, I cannot explain it by words. Therefore I want to show an example:
A B
5 3
7 2
8 6
6 4
9 5
8 2
3 1
4 3
As you can see, I have a datasheet that has two columns. First of all, I calculated the conditional cumulative sum of column A ( I can do it by myself-So no need help for that step):
A B CA
5 3 5
7 2 12
8 6 18
6 4 8 ((12+8)-18)+6
9 5 17
8 2 18
3 1 10 (((17+8)-18)+3
4 3 14
So my condition value is 18. If the cumulative more than 18, then it equal 18 and next value if sum of the first value after 18 and exceeds amount over 18. ( As I said I can do it by myself )
So the tricky part is I have to calculate the cumulative sum of column B according to column A:
A B CA CB
5 3 5 3
7 2 12 5
8 6 18 9.5 (5+(6*((18-12)/8)))
6 4 8 5.5 ((5+6)-9.5)+4
9 5 17 10.5 (5.5+5)
8 2 18 10.75 (10.5+(2*((18-7)/8)))
3 1 10 2.75 ((10.5+2)-10.75)+1
4 3 14 5.75 (2.75+3)
As you can see from example the cumulative sum of column B is very specific. When column CA is equal to our condition value (18), then we calculate the proportion of the last value for getting our condition value (18) and then use this proportion for computing cumulative sum of column B.
Looks like when the sum of A reaches 18 or more you want to split the values of A and B between the current and the next record. One way is to remember the left over values for A and B and carry them forward in your new cumulative variables. Just make sure to output the observation before resetting those variables.
data want ;
set have ;
ca+a;
cb+b;
if ca >= 18 then do;
extra_a=ca - 18;
extra_b=b - b*((a - extra_a)/a) ;
ca=18;
cb=cb-extra_b ;
end;
output;
if ca=18 then do;
ca=extra_a;
cb=extra_b;
end;
drop extra_a extra_b ;
run;

How to balance between two arrays such as the difference is minimized?

I have an array A[]={3,2,5,11,17} and B[]={2,3,6}, size of B is always less than A. Now I have to map from every element B to distinct elements of A such that the total difference sum( abs(Bi-Aj) ) becomes minimum (Where Bi has been mapped to Aj). What is the type of algorithm?
For the example input, I could select, 2->2=0 , 3->3=0 and then 6->5=1. So the total cost is 0+0+1 = 1. I have been thinking sorting both the arrays and then take the first sizeof B elements from the A. Will this work?
It can be thought of as an unbalanced Assignment Problem.
The cost matrix shall be the difference in values of B[i] and A[j]. You can add dummy elements to B so that the problem becomes balanced and put the costs associated very high.
Then Hungarian Algorithm can be applied to solve it.
For the example case A[]={3,2,5,11,17} and B[]={2,3,6} the cost matrix shall be:
. 3 2 5 11 17
2 1 0 3 9 15
3 0 1 2 8 14
6 3 4 1 5 11
d1 16 16 16 16 16
d2 16 16 16 16 16

adjusting the distance between numbers on console

I've made a program to create the pascal's triangle. the program takes number of rows as input and displays the triangle on the console. I've used the setw() function to set the distance between numbers. it's of for unit single digits but when the numbers get greater than 10,the width is not being adjusted properly,right now I've :
if(P<10){
std::cout << P ;
std::cout <<std::setw(2);
}
if(P>=10){
std::cout<<std::setw(3) << P ;
std::cout<<std::setw(2);
}
here's the ouput from the console:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84126126 84 36 9 110
I want it to appear like a proper triangle,Could someone help me out please???
If you read e.g. this reference of std::setw you will see
The width property of the stream will be reset to zero (meaning "unspecified") if any of the following functions are called
And then goes on to list basically all output operators.
This means that when you do
std::cout <<std::setw(2);
the width will only be set for the next output operation. If you do any kind of output after that the width will be reset to zero.

How to group data in kdb+ using customized groups?

I have a table (allsales) with a column for time (sale_time). I want to group the data by sale_time. But I want to be able to bucket this. ex any data where time is between 00:00:00-03:00:00 should be grouped together, 03:00:00-06:00:00 should be grouped together and so on. Is there a way to write such a query?
xbar is useful for rounding to interval values e.g.
q)5 xbar 1 3 5 8 10 11 12 14 18
0 0 5 5 10 10 10 10 15
We can then use this to group rows into time groups, for your example:
q)s:([] t:13:00t+00:15t*til 24; v:til 24)
q)s
t v
--------------
13:00:00.000 0
13:15:00.000 1
13:30:00.000 2
13:45:00.000 3
14:00:00.000 4
14:15:00.000 5
..
q)select count i,sum v by xbar[`int$03:00t;t] from s
t | x v
------------| ------
12:00:00.000| 8 28
15:00:00.000| 12 162
18:00:00.000| 4 86
"by xbar[`int$03:00t;t]" rounds the time column t to the nearest three hour value, then this is used as the group by.
There are few more ways to achieve the same results.
q)select count i , sum v by t:01:00u*3 xbar t.hh from s
q)select count i , sum v by t:180 xbar t.minute from s
t | x v
-----| ------
12:00| 8 28
15:00| 12 162
18:00| 4 86
But in all cases, be careful of the date column if present in the table, otherwise same time window across different dates will generate the wrong results.
q)s:([] d:24#2013.05.07 2013.05.08; t:13:00t+00:15t*til 24; v:til 24)
q)select count i , sum v by d, t:180 xbar t.minute from s
d t | x v
----------------| ----
2013.05.07 12:00| 4 12
2013.05.07 15:00| 6 78
2013.05.07 18:00| 2 42
2013.05.08 12:00| 4 16
2013.05.08 15:00| 6 84
2013.05.08 18:00| 2 44