Igraph calculating minimum spanning tree with weights C interface - igraph

I have been trying to calculate a minimum spanning tree using the prim method, but I have got rather confused about the way that weights are used in this context. The suggested example program in the source documents does not appear to be correct, I don't understand why the edge betweenness needs to be calculated.
Please see the following program, it's designed to make a simple undirected graph.
#include <igraph.h>
int main()
{
igraph_vector_t eb, edges;
igraph_vector_t weights;
long int i;
igraph_t theGraph, tree;
struct arg {
int index;
int source;
int target;
float weight;
};
struct arg data[] = {
{0, 0, 1, 2.0},
{1, 1, 2, 3.0},
{2, 2, 3, 44.0},
{3, 3, 4, 3.0},
{4, 4, 1, 2.0},
{5, 4, 5, 9.0},
{6, 4, 6, 3.0},
{6, 6, 5, 7.0}
};
int nargs = sizeof(data) / sizeof(struct arg);
igraph_empty(&theGraph, nargs, IGRAPH_UNDIRECTED);
igraph_vector_init(&weights, nargs);
// create graph
for (i = 0; i < nargs; i++) {
igraph_add_edge(&theGraph, data[i].source, data[i].target);
// Add an weight per entry
igraph_vector_set(&weights, i, data[i].weight);
}
igraph_vector_init(&eb, igraph_ecount(&theGraph));
igraph_edge_betweenness(&theGraph, &eb, IGRAPH_UNDIRECTED, &weights);
for (i = 0; i < igraph_vector_size(&eb); i++) {
VECTOR(eb)[i] = -VECTOR(eb)[i];
}
igraph_minimum_spanning_tree_prim(&theGraph, &tree, &eb);
igraph_write_graph_edgelist(&tree, stdout);
igraph_vector_init(&edges, 0);
igraph_minimum_spanning_tree(&theGraph, &edges, &eb);
igraph_vector_print(&edges);
igraph_vector_destroy(&edges);
igraph_destroy(&tree);
igraph_destroy(&theGraph);
igraph_vector_destroy(&eb);
return 0;
}
Can anybody see anything that is wrong with this program it's designed to build a simple graph with what I hope is the correct way to use a weight argument. One value per edge between a source and a target.

The section about adding an edge betweenness comes from the original code example for the use of prim. It just needs to be removed for the program to work correctly using a user supply value of weight.

Related

Count no. of ones by position(place) of an array of 32-bit binary numbers

An array(10^5 size) of 32-bit binary numbers is given, we're required to count the no. of ones for every bit of those numbers.
For example:
Array : {10101,1011,1010,1}
Counts : {1's place: 3, 2's place: 2, 3's place: 1, 4's place: 2, 5's place: 1}
No bit manipulation technique seems to satisfy the constraints to me.
Well, this should be solveable with two loops: one going over the array the other one masking the right bits. Running time should be not too bad for your constraints.
Here is a rust implementation (out of my head, not throughtfully tested):
fn main() {
let mut v = vec!();
for i in 1..50*1000 {
v.push(i);
}
let r = bitcount_arr(v);
r.iter().enumerate().for_each( |(i,x)| print!("index {}:{} ",i+1,x));
}
fn bitcount_arr(input:Vec<u32>) -> [u32;32] {
let mut res = [0;32];
for num in input {
for i in 0..31 {
let mask = 1 << i;
if num & mask != 0 {
res[i] += 1;
}
}
}
res
}
This can be done with transposed addition, though the array is a bit long for it.
To transpose addition, use an array of counters, but instead of using one counter for every position we'll use one counter for every bit of the count. So a counter that tracks for each position whether the count is even/odd, a counter that tracks for each position whether the count has a 2 in it, etc.
To add an element of the array into this, only half-add operations (& to find the new carry, ^ to update) are needed, since it's only a conditional increment: (not tested)
uint32_t counters[17];
for (uint32_t elem : array) {
uint32_t c = elem;
for (int i = 0; i < 17; i++) {
uint32_t nextcarry = counters[i] & c;
counters[i] ^= c;
c = nextcarry;
}
}
I chose 17 counters because log2(10^5) is just less than 17. So even if all bits are 1, the counters won't wrap.
To read off the result for bit k, take the k'th bit of every counter.
There are slightly more efficient ways that can add several elements of the array into the counters at once using some full-adds and duplicated counters.

Processing code not refreshing?

I'm new to Processing and I'm trying a simple code to test a light to frequency converter. I have recorded data onto a cvs file through an Arduino and I'm now looking to get Processing to read through the table and spew out (in text) the time and frequency per second.
However, it just seems to display them all at the same time? I do not know what I am doing wrong as the code works for print/println, but not on the screen. Any help would be greatly appreciated!
Table table;
TableRow row;
int fData;
String [] frequency;
String [] time;
int index = 0;
void setup() {
size(800, 500);
background(255);
table = loadTable("test2.csv", "header");
time = table.getStringColumn(1);
frequency = table.getStringColumn(2);
println(table.getColumnCount() + " columns in table");
println(table.getRowCount() + " rows in table");
println("Date: " + table.getString(1, 0));
println("Start time: " + table.getString(0, 1));
println("Duration: " + (table.getRowCount()/60) + " minutes");
}
void draw () {
background(255);
text("Date: "+table.getString(0, 0), 30, 340);
text("Start time: "+ time[index], 30, 360);
fill(0);
for (int i = 0; i < 1575; i = i+1) {
fData=((table.getInt(i, 2))/1000);// alpha range 0-255
println(fData);
fill(0);
text("End time: " + time[i], 30, 380);
text("Times:["+table.getString(i, 1)+"]", 30, 420);
fill(255);
rect(0, height-100, width, 100);
fill(0);
text("fData:["+fData+"]", 30, 440);
float number = +table.getInt(i, 2);
println(number);
text("#["+number+"]", 30, 480);
}
}
The text() function takes 3 parameters: the String you want to display, and the x and y coordinates of the position it should be displayed.
Notice that you're always passing the same x and y values into the text() function, so you end up drawing everything in the same position.
You have to modify the x and/or y passed into the text() function. How you do that depends on exactly what you want to happen. But you'd probably start by modifying the position based on the for loop variable:
text("End time: " + time[i], 30, i*30);
Notice that here I'm changing the y value so that each iteration of the loop shows the text 30 pixels lower. That's just an example, but the idea is the same: you want to pass in different positions over time.
You could also do something like only displaying one line of text at a time, maybe for 1 second or so.
Here's an MCVE that shows your problem without all your extra code:
background(0);
String one = "ABC";
String two = "XYZ";
text(one, 25, 25);
text(two, 25, 25);
Since we're drawing the one and two Strings in the same location, we get this:
But we can change the positions we're passing in:
background(0);
String one = "ABC";
String two = "XYZ";
text(one, 25, 25);
text(two, 25, 50);
So now they draw in different locations:
If you have further questions, try to post your own MCVE that uses hard-coded values instead of your entire sketch.

AS3: adding different numbers in an array to get specific result.

I got a numberArray.
It contains intergers - randomised, within a specific range.
I want to get a specific sum, but not for everything inside the numberArray,
more of trying to sum up different amount of numbers (total of 5 only) inside the numberArray and see if it'll get the specific total required. and if not, it'll randomise another number to take over one of the numbers inside the numberArray.
What's the easiest way to do this ?
doing lots of
if (numberArray[1] + numberArray[2] == specificNumber)
{
}
if (numberArray[1] + numberArray[3] == specificNumber)
{
}
etc. etc. etc.
have too many lines of codes, and it seems like there are easier codes. right now i only have 5 different numbers in the array, so it's still bearable, but if the amount of numbers are higher.... ....
Reading your question like this: For your array of random integers, find a (or all) set(s) of integers that have a given sum.
This is an NP-Complete problem - i.e. there's no known algorithm that solves it efficiently.
The fastest known way is rather complex, so we'll go with a naive solution - should be good enough if you're not doing this on every frame or the input set is huge.
This should also work with 0 or negative values in the input set.
// The sum we're looking for:
var requiredSum:int = 8;
// Our input set:
var numberArray:Array = [1, 2, 3, 4, 5, 2, 3];
// Results will be stored here:
var resultSets:Array = [];
// Go through all possible subset sizes.
// This allows subset sizes all the way up to the size of
// the input set (numberArray.length).
// You can modify it to a fixed value (say, 5), of course:
for (var subsetSize:int = 1; subsetSize <= numberArray.length; subsetSize++)
{
// We'll use the same array for all our attempts of this size:
var subset:Array = new Array(subsetSize);
findSum(numberArray, subset, 0, 0);
}
// Output results:
for (var i:int = 0; i < resultSets.length; i++)
{
trace(resultSets[i].join("+"));
}
// numberArray : Our input set
// subset : The set we're currently filling
// setIndex : The position we're at in numberArray
// subsetIndex : The position we're at in the set we're filling
function findSum(numberArray:Array, subset:Array, setIndex:int,
subsetIndex:int):void
{
// Try every value from the input set starting from our current position,
// and insert the value at the current subset index:
for (var index:int = setIndex ; index < numberArray.length; index++)
{
subset[subsetIndex] = numberArray[index];
// Have we filled the subset?
if (subsetIndex == subset.length - 1)
{
var sum:int = 0;
for (var i:int = 0; i < subset.length; i++)
{
sum += subset[i];
}
if (sum == requiredSum)
{
// Clone the array before adding it to our results,
// since we'll be modifying it if we find more:
resultSets.push(subset.concat());
}
}
else
{
// Recursion takes care of combining our subset so far
// with every possible value for the remaining subset indices:
findSum(numberArray, subset, index + 1, subsetIndex + 1);
}
}
}
Output for the values used in the above code:
3+5
5+3
1+2+5
1+3+4
1+4+3
1+5+2
2+3+3
2+4+2
3+2+3
1+2+3+2
1+2+2+3
If we only need to know IF a sum exists, there's no need for the result set - we just return true/false, and break out of the recursive algorithm completely when a sum has been found:
var requiredSum:int = 8;
var numberArray:Array = [1, 2, 3, 4, 5, 2, 3];
// Go through all possible subset sizes:
for (var subsetSize:int = 1; subsetSize <= numberArray.length; subsetSize++)
{
// We'll use the same array for all our attempts of this size:
var subset:Array = new Array(subsetSize);
if (findSum(numberArray, subset, 0, 0))
{
trace("Found our sum!");
// If we found our sum, no need to look for more sets:
break;
}
}
// numberArray : Our input set
// subset : The set we're currently filling
// setIndex : The position we're at in numberArray
// subsetIndex : The position we're at in the set we're filling
// RETURNS : True if the required sum was found, otherwise false.
function findSum(numberArray:Array, subset:Array, setIndex:int,
subsetIndex:int):Boolean
{
// Try every value from the input set starting from our current position,
// and insert the value at the current subset index:
for (var index:int = setIndex ; index < numberArray.length; index++)
{
subset[subsetIndex] = numberArray[index];
// Have we filled the subset?
if (subsetIndex == subset.length - 1)
{
var sum:int = 0;
for (var i:int = 0; i < subset.length; i++)
{
sum += subset[i];
}
// Return true if we found our sum, false if not:
return sum == requiredSum;
}
else
{
if (findSum(numberArray, subset, index + 1, subsetIndex + 1))
{
// If the "inner" findSum found a sum, we're done, so return
// - otherwise stay in the loop and keep looking:
return true;
}
}
}
// We found no subset with our required sum this time around:
return false;
}
ETA: How this works... As mentioned, it's the naive solution - in other words, we're simply checking every single permutation of numberArray, summing each permutation, and checking if it's the sum we want.
The most complicated part is making all the permutations. The way this code does it is through recursion - i.e., the findSum() function filling a slot then calling itself to fill the next one, until all slots are filled and it can check the sum. We'll use the numberArray [1, 5, 4, 2] as an example here:
Go through all subset sizes in a loop - i.e., start by making all [a], then all [a,b], [a,b,c], [a,b,c,d]... etc.
For each subset size:
Fill slot 1 of the subset...
... with each value of numberArray - [1, ?, ?], [5, ?, ?], [4, ?, ?]...
If all slots in subset have been filled, check if the sum matches and skip step 4.
(Recursively) call findSum to:
Fill slot 2 of the subset...
... with each remaining value of numberArray - [1, 5, ?], [1, 4, ?], [1, 2, ?]
If all slots in subset have been filled, check if the sum matches and skip step 4.
(Recursively) call findSum to:
Fill slot 3 of the subset
... with each remaining value of numberArray - [1, 5, 4], [1, 5, 2]
If all slots in subset have been filled, check if the sum matches and skip step 4.
(Recursively) call findSum (this goes on "forever", or until all slots are filled and we "skip step 4")
Go to 2.4.4.1. to try next value for slot 3.
Go to 2.4.1 to try next value for slot 2.
Go to 2.1 to try next value for slot 1.
This way, we go through every permutation of size 1, 2, 3, 4...
There's more optimization that could be done here, since the code never checks that it actually has enough values left in the input set to fill the remaining slots - i.e. it does some loops and calls to findSum() that are unneeded. This is only a matter of efficiency, however - the result is still correct.
I would do something like the following:
shuffle array
take random amount of numbers from the array
sum them up
if the sum is not the total sum you want, repeat
hm, not sure what you want to do at the end when a "conclusion" or "no conclusion" is reached, but you could generate a Power set from your set of numbers then for each subset add up all the numbers in it to see if you get your desired sum.
(This would be a 'brute force' approach and could be slow if you have many numbers.)
Possibly useful for how to create a Power set:
Calculating all of the subsets of a set of numbers

Eigen library: return a matrix block in a function as lvalue

I am trying to return a block of a matrix as an lvalue of a function. Let's say my function looks like this:
Block<Derived> getBlock(MatrixXd & m, int i, int j, int row, int column)
{
return m.block(i,j,row,column);
}
As it turns out, it seems that C++ compiler understands that block() operator gives only temporary value and so returning it as an lvalue is prohibited by the compiler. However, in Eigen documentation there is some example that we can use Eigen as an lvalue (http://eigen.tuxfamily.org/dox/TutorialBlockOperations.html#TutorialBlockOperationsUsing) so I am wondering how we couldn't do the same with function return.
a.block(0,0,2,3) = a.block(2,1,2,3);
Thank you!
I want to put what I found myself so it might be helpful to someone else:
My basic solution is to know what derived type you want the block to be. In this case:
Block<MatrixXd> getBlock(MatrixXd & m, int i, int j, int row, int column)
{
return m.block(i,j,row,column);
}
It is interesting to me to notice that this method will return the reference to the content of matrix m by default. So if we do:
MatrixXd m = MatrixXd::Zero(10,10);
Block<MatrixXd> myBlock = getBlock(m, 1, 1, 3, 3);
myBlock << 1, 0, 0,
0, 1, 0,
0, 0, 1;
The content in matrix m will be modified as well. Note that, however,
MatrixXd m = MatrixXd::Zero(10,10);
MatrixXd myBlock = getBlock(m, 1, 1, 3, 3);
myBlock << 1, 0, 0,
0, 1, 0,
0, 0, 1;
will not work. My understanding is that once we convert the block to another type Eigen makes a copy of the data before conversion.
I was trying something like this, specifically returning the last 3 elements of a 4 element vector and I couldn't get this to work.
Solution turned out kind of nice, although maybe a little confusing if you're not familiar with trailing return types:
struct foo{
Eigen::Vector4d e_;
// const version
auto get_tail() const -> const auto { return e_.tail<3>(); };
// non-const version
auto get_tail() -> auto { return e_.tail<3>(); };
};

quicksort help, not sure why partitioning returns index and not array

i was wondering if anyone could help me on quicksort. i understand the general idea for partitioning, but not sure why it returns an index
int partition(int arr[], int left, int right)
{
int i = left, j = right;
int tmp;
int pivot = arr[(left + right) / 2];
while (i <= j) {
while (arr[i] < pivot)
i++;
while (arr[j] > pivot)
j--;
if (i <= j) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
i++;
j--;
}
}
return i;
}
void quickSort(int arr[], int left, int right) {
int index = partition(arr, left, right);
if (left < index - 1)
quickSort(arr, left, index - 1);
if (index < right)
quickSort(arr, index, right);
}
i understand the whole rearranging part. it makes sense to me, but im not sure why partition is returning just an index. i thought it was supposed to return an array? like if the problem was to ... Sort {1, 12, 5, 26, 7, 14, 3, 7, 2}. i thought it would return...
1, 2, 5, 7, 3, 14, 7, 26, 12
i guess thats why im not understanding the actual quicksort function. but if someone could help explain it clearly and in an easy to understand way, it would be much appreciated. thanks a lot!
The index that has been returned is only there to identify the end of recurrsion within the QuickSort algorithm. It's mainly the index of the pivot element that is used to identify the smaller and bigger numbers.
AND: You are referring to an enhanced Quick Search Algorithm. In the basic version of the QuickSearch algorithm the returned index won't be needed.
It would also work with: (but a lot slower)
void quickSort(int arr[], int left, int right)
{
if (left < right)
{
int index = partition(arr, left, right);
quickSort(arr, left, index - 1);
quickSort(arr, index+1, right);
}
}
Your partition function is modifying the array in-place. The integer it is returning is the index before which values are smaller than the pivot, and starting at which the values are bigger than the pivot. The two recursive calls are sorting the smaller elements and the larger elements; the condition tested before the recursive calls serves as the base case.