I'm constructing a graph with JGraphX. Using the following code, it takes an inordinately long time to build compared to similar graph implementations like JGraphT. Why would this be? The vertices are created quickly, but the nested loops that create the edges take a long time, especially when the array sizes are 1000.
Vertex[] verts = new Vertex[1000]; // My own vertex class
mxCell[] cells = new mxCell[1000]; // From com.mxGraph.model.mxCell
// Create graph
mxGraph mx = new mxGraph(); // from com.mxgraph.view.mxGraph
// Create vertices
for(int i = 0; i < verts.length; i++)
{
verts[i] = new Vertex(Integer.toString(i));
cells[i] = new mxCell(verts[i]);
mx.getModel().beginUpdate();
mx.insertVertex(null, Integer.toString(i), cells[i], 1, 1, 1, 1);
mx.getModel().endUpdate();
}
System.out.println("Vertices created.");
// Connect graph
Random r = new Random();
for(int j = 0; j < verts.length; j++)
{
for(int k = 0; k < verts.length; k++)
{
if(k != j)
{
if(r.nextInt(5) == 0) // Random connections, fairly dense
{
mx.getModel().beginUpdate();
mx.insertEdge(null, Integer.toString(k) + " " + Integer.toString(j), "", cells[j], cells[k]);
mx.getModel().endUpdate();
}
}
}
}
System.out.println("Finished graph.");
begin and end updates are meant for combining operations into one. Ending an update causes a complete validation of the graph. Here you're wrapping each atomic operation only, they have no effect.
Remove the begin/ends you have an put a begin after you create the graph and the end at the bottom of this code section and try that.
Related
I have a problem when I'm trying to a loop in a DataTable that a dataset contains.
I'm doing a loop like this:
for(int i = 0; i<ds.Tables[0].Rows.Count - 1 ; i++)
The problem is that I can't get the value of the last line with this one, but if I try to get rid of the "-1" and do a loop on the whole table, I'll have an out of range exception.
This out of range exception is because I have to check if the value of a line "i" is equal to the value of a line "i+1", like this:
if (ds.Tables[0].Rows[i]["Release_No"] != ds.Tables[0].Rows[i + 1]["Release_No"])
So if I do it in a loop, when the index is on the last line it will check if the last line is equal to i+1, and it's out of the table.
So I was trying to check if the index is on the last line, then just get the value of the last line, but it seems like it doesn't work.
if(ds.Tables[0].Rows.IndexOf(ds.Tables[0].Rows[i]) == ds.Tables[0].Rows.Count)
If anyone has an idea, let me know, and of course if it is not clear enough let me know, I'll give more information and more code.
Thanks for your help and your time!
Check if it's the last record, first.
I like to refactor code to read as close to sentence form as possible, explaining what you want it to do using named variables and methods, and that often gets me unlocked.
Try to make each line of code do one thing, and one thing only, like check if it is the last row:
var data = ds.Tables[0].Rows;
var lastRow = data.Count - 1;
for(int i = 0; i < lastRow ; i++)
{
if (i == lastRow){
// This is the last row. Handle the last row here.
}
else
{
// Handle all other rows here
var currentRecord = data[i];
var nextRecord = data[i + 1];
if (currentRecord["Release_No"] != nextRecord["Release_No"])
{
// Handle unique Releases...
}
}
}
Use less than or equal to like this
for(int i = 0; i<=ds.Tables[0].Rows.Count - 1 ; i++)
I hope this may get what you want.
Something like this is better ?
var lastRow = data.Count - 1;
var data = ds.Tables[0].Rows;
for(int i = 0; i< lastRow; i++)
{
testFirstCum = Convert.ToInt32(ds.Tables[0].Rows[i]["EDI_Accum_Quantity"]);
if ( i == lastRow)
{
if (DBNull.Value.Equals(data[i]))
{
quantity = 0;
}
else
{
quantity = Convert.ToInt32(data[i]);
testFirstCum = testFirstCum + quantity;
System.Diagnostics.Debug.WriteLine(quantity);
System.Diagnostics.Debug.WriteLine(testFirstCum);
}
}
else
{
var col = ds.Tables[0].Columns;
var currentRecord = data[i];
var nextRecord = data[i + 1];
if(currentRecord["Release_No"] != nextRecord["Release_No"])
{
for (int j = col[2].Ordinal; j < col.Count; j++)
{
if (DBNull.Value.Equals(data[i][j]))
{
quantity = 0;
}
else
{
quantity = Convert.ToInt32(data[i][j]);
testFirstCum = testFirstCum + quantity;
System.Diagnostics.Debug.WriteLine(quantity);
System.Diagnostics.Debug.WriteLine(testFirstCum);
}
}
}
}
}
I wonder if there is any algorithm or some easy procedure to generate an interval graph?
I need to generate interval graphs with n nodes, where n is changing for 1 to, say, 10000.
If it is possible, I need an incidence matrix representation of the graph.
An additional restriction is not to have all these graphs complete.
Thanks everyone in advance!
==ADDITION==
Here is an implementation in Java:
public Object generate(int numberOfNodes) {
int listCapacity = numberOfNodes * 2;
List<Integer> arr = new ArrayList<Integer>();
int[][] adjacencyMatrix = new int[numberOfNodes][numberOfNodes];
Integer nodeNumber = 0;
for (int i = 0; i < listCapacity; i = i + 2) {
arr.add(nodeNumber);
arr.add(nodeNumber);
nodeNumber++;
}
Collections.shuffle(arr);
for (int i = 0; i < numberOfNodes; i++) {
for (int j = arr.indexOf(i); j < arr.lastIndexOf(i); j++) {
adjacencyMatrix[i][arr.get(j)] = 1;
adjacencyMatrix[arr.get(j)][i] = 1;
}
adjacencyMatrix[i][i] = 0;
}
return new Graph(adjacencyMatrix);
}
Though, in some cases it fails to produce interval graph.
One possible way to generate an interval graph with N nodes:
create an array [1, 1, 2, 2, ... n, n]
shuffle the array
create a graph:
each node v_i corresponds to the pair of occurences of i in the shuffled array
two nodes v_i and v_j are connected with an edge iff i and j are interleaved in the array. That is i j i j or i j j i, but not i i j j. In other words, the intervals i and j intersect.
This graph is guaranteed to be an interval graph (every node is an interval in the original array), and every graph is possible to create this way.
I am trying to make a map by reading a text file line by line (because i cant find how to do that word by word). So I make a map00.txt that looks like "33000000111" (every number is one row, first 2 rows are number of columns and rows so matrix that I load it into looks like
000
000
111
). Now I am supposed to draw 3 tiles at the bottom (1=draw tile). I do so by drawing tile at its position in matrix * window height(width) / matrix number of rows(columns).
PROBLEM: i cant get the right parameters for current window width and height.
Code for loading tiles:
public int[,] LoadMatrix(string path)
{
StreamReader sr = new StreamReader(path);
int[,] a = new int[int.Parse(sr.ReadLine().ToString()),
int.Parse(sr.ReadLine().ToString())];
for(int i = 0; i < a.GetLength(0); i++)
for (int j = 0; j < a.GetLength(1); j++)
{ a[i, j] =int.Parse(sr.ReadLine().ToString()); }
sr.Close();
return a;
}
Code for drawing tiles:
public void DrawTiles(SpriteBatch sp, GraphicsDeviceManager gdm)
{
for(int i = 0; i < matrix.GetLength(0); i++)
for(int j = 0; j < matrix.GetLength(1); j++)
{
if (i == 1)
{
sp.Draw(tile,
new Rectangle(j * (gdm.PreferredBackBufferWidth / 3),//matrix.GetLength(1),
i * (gdm.PreferredBackBufferWidth / 3),//matrix.GetLength(0),
gdm.PreferredBackBufferWidth / matrix.GetLength(1),
gdm.PreferredBackBufferHeight / matrix.GetLength(0)),
Color.White);
}
}
}
but the result is that they are drawn about 40 pixels above the bottom of the screen!
and i tried with GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height(Width) but i get the same result. And when i put calculated numbers that should (in theory) be width/columns and heigth/rows i get what i want. So any suggestions would be VERY appriciated because i am stuck at this for a long time on google and Stack Overflow.
Here is a reworked version of your Draw code, which should work:
public void DrawTiles(SpriteBatch sp, GraphicsDeviceManager gdm)
{
//You would typically pre-compute these in a load function
int tileWidth = gdm.PreferredBackBufferWidth / matrix.GetLength(0);
int tileHeight = gdm.PreferredBackBufferWidth / matrix.GetLength(1);
//Loop through all tiles
for(int i = 0; i < matrix.GetLength(0); i++)
{
for(int j = 0; j < matrix.GetLength(1); j++)
{
//If tile value is not 0
if (matrix[i,j] != 0)
{
sp.Draw(tile, new Rectangle(i * tileWidth, j * tileHeight, tileWidth, tileHeight), Color.White);
}
}
}
}
Hi
i am creating online quiz. For that i am creating arrays of answers selected by user. i used following code for that, it gives correct array but sometimes gives error "Index was outside the range"
//rsel is session values for selected answer
int rsel = Convert.ToInt32(Session["rblsel"]);
// [Convert.ToInt32(Session["Counter"] indicates size of array of no. of questions
int[] ansarray = new int[Convert.ToInt32(Session["Counter"]) - 1];
int[] temp = (int[])Session["arrofans"];
int j,n;
if (temp == null)
n = 0;
else
n = temp.Length;
for (j = 0; j < n; j++)
{
ansarray[j] = temp[j];
}
ansarray[j] = rsel;
Session["arrofans"] = ansarray;
Help me to find out exact error. Asp.net,c#
Thank you.
Why are you reducing the "counter" by one?
int[] ansarray = new int[Convert.ToInt32(Session["Counter"]) - 1];
It looks like that should probably be a + 1... but to be honest it would be simpler to use the size of ansarray - and use Array.Resize to effectively extend it:
int[] ansarray = (int[])Session["arrofans"];
Array.Resize(ref ansarray, ansarray.Length + 1);
ansarray[ansarray.Length - 1] = rsel;
Session["arrofans"] = ansarray;
That way you don't even need the "Counter" part of the session.
One possible OutOfRange could be triggered when
**arrofans.length >= Counter**
temp.Length should not be bigger than ansarray.Length, or precisely from your code it ansarray.Length must be temp.Length+1 or bigger. To avoid your problem you must change it to for (j = 0; j < n && j < (ansarray.Length-1); j++) but i don't know if it will suite your case
I need to create an asp.net page that auto generate a brackets tournament tennis style.
Regarding the managing of match in database, it's not a problem.
The problem is the dynamic graphics creation of brackets.
The user will be able to create tournament by 2-4...32 players.
And i don't know ho to create the graphics bracket in html or gdi...
Using Silverlight, and a Grid, You can produce something like this:
To do it, define a regular UserControl containing a Grid. (This is the default when you build a silverlight app in VS2008 with the Silverlight 3.0 SDK).
Then, add a call to the following in the constructor for the user control:
private void SetupBracket(int n)
{
var black = new SolidColorBrush(Colors.Gray);
// number of levels, or rounds, in the single-elim tourney
int levels = (int)Math.Log(n, 2) + 1;
// number of columns in the Grid. There's a "connector"
// column between round n and round n+1.
int nColumns = levels * 2 - 1;
// add the necessary columns to the grid
var cdc = LayoutRoot.ColumnDefinitions;
for (int i = 0; i < nColumns; i++)
{
var cd = new ColumnDefinition();
// the width of the connector is half that of the regular columns
int width = ((i % 2) == 1) ? 1 : 2;
cd.Width = new GridLength(width, GridUnitType.Star);
cdc.Add(cd);
}
var rdc = LayoutRoot.RowDefinitions;
// in the grid, there is one row for each player, and
// an interleaving row between each pair of players.
int totalSlots = 2 * n - 1;
for (int i = 0; i < totalSlots; i++)
{
rdc.Add(new RowDefinition());
}
// Now we have a grid of the proper geometry.
// Next: fill it.
List<int> slots = new List<int>();
ImageBrush brush = new ImageBrush();
brush.ImageSource = new BitmapImage(new Uri("Bridge.png", UriKind.Relative));
// one loop for each level, or "round" in the tourney.
for (int j = 0; j < levels; j++)
{
// Figure the number of players in the current round.
// Since we insert the rounds in the reverse order,
// think of j as the "number of rounds remaining."
// Therefore, when j==0, playersThisRound=1.
// When j == 1, playersThisRound = 2. etc.
int playersThisRound = (int)Math.Pow(2, j);
int x = levels - j;
int f = (int)Math.Pow(2, x - 1);
for (int i = 0; i < playersThisRound; i++)
{
// do this in reverse order. The innermost round is
// inserted first.
var r = new TextBox();
r.Background = black;
if (j == levels - 1)
r.Text = "player " + (i + 1).ToString();
else
r.Text = "player ??";
// for j == 0, this is the last column in the grid.
// for j == levels-1, this is the first column.
// The grid column is not the same as the current
// round, because of the columns used for the
// interleaved connectors.
int k = 2 * (x - 1);
r.SetValue(Grid.ColumnProperty, k);
int m = (i * 2 + 1) * f - 1;
r.SetValue(Grid.RowProperty, m);
LayoutRoot.Children.Add(r);
// are we not on the last round?
if (j > 0)
{
slots.Add(m);
// Have we just inserted two rows? Then we need
// a connector between these two and the next
// round (the round previously added).
if (slots.Count == 2)
{
string xamlTriangle = "<Path xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' "+
"xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' " +
"Data='M0,0 L 100 50 0 100 Z' Fill='LightBlue' Stretch='Fill'/>";
Path path = (Path)System.Windows.Markup.XamlReader.Load(xamlTriangle);
path.SetValue(Grid.ColumnProperty, 2 * (x - 1) + 1);
path.SetValue(Grid.RowProperty, slots[0]);
path.SetValue(Grid.RowSpanProperty, slots[1] - slots[0] + 1);
this.LayoutRoot.Children.Add(path);
slots.Clear();
}
}
}
}
}
In the above, the connector is just an isosceles triangle, with the apex pointing to the right. It is generated by XamlReader.Load() on a string.
You would also want to pretty it up, style it with different colors and fonts, I guess.
You can insert this silverlight "user control" into any HTML web page, something like embedding a flash app into a page. There are silverlight plugins for IE, Firefox, Opera, Safari, and Chrome.
If you don't want to use Silverlight, you could use a similar approach to construct an HTML table.