or-tools: dirrerent slack_max for some locations - or-tools

In my project I use or-tools for solving VRPTW problem.
I need to set different waiting time for different nodes.
For example. I have 6 locations.
Depot of vehicle. With max time window (0, 1440)
Pickup point for client 1. Time window (0, 10)
Delivery point for client 1. Time window (0, 50)
Pickup point for client 2. Time window (500, 510)
Delivery point for client 2. Time window (500, 600)
Vehicle service point. With max time window (0, 1440)
If I set slack_max with addDimension
routing.addDimension(transitCallbackIndex, // transit callback
1440, // allow waiting time
60 * 24 * 2,
false, // start cumul to zero
"Time");
My vehicle can wait time in range (0, 1440) in each location. In that case time goes of out range time windows of pickup/delivery node . How can I set slack only for Vehicle service point, because time window for that node is max?
I tried set slack like this
if (index == 5) {
timeDimension.slackVar(index).setRange(0, 1440);
}
but that doesn't work as I expected.
Full code sample:
package test;
import com.google.ortools.Loader;
import com.google.ortools.constraintsolver.Assignment;
import com.google.ortools.constraintsolver.FirstSolutionStrategy;
import com.google.ortools.constraintsolver.IntVar;
import com.google.ortools.constraintsolver.IntervalVar;
import com.google.ortools.constraintsolver.RoutingDimension;
import com.google.ortools.constraintsolver.RoutingIndexManager;
import com.google.ortools.constraintsolver.RoutingModel;
import com.google.ortools.constraintsolver.RoutingSearchParameters;
import com.google.ortools.constraintsolver.Solver;
import com.google.ortools.constraintsolver.main;
import java.util.Arrays;
import java.util.logging.Logger;
/** Minimal VRP with Resource Constraints.*/
public class Test {
// static {
// System.loadLibrary("jniortools");
// }
private static final Logger logger = Logger.getLogger(Test.class.getName());
static class DataModel {
public final long[][] timeMatrix = {
{0, 0, 0, 0, 0, 0},
{0, 0, 10, 0, 10, 0},
{0, 10, 0, 10, 0, 0},
{0, 0, 10, 0, 10, 0},
{0, 10, 0, 10, 0, 0},
{0, 0, 0, 0, 0, 0}
};
public final long[][] timeWindows = {
{0, 1440},
{0, 10}, // 1 from
{0, 50}, // 1 to
{500, 510}, // 2 from
{500, 600}, // 2 to
{0, 1440}, // rest location
};
public final int[][] pickupDeliveries = {
{1, 2},
{3, 4},
};
public final int vehicleNumber = 1;
public final int depot = 0;
}
public static void main(String[] args) throws Exception {
Loader.loadNativeLibraries();
// Instantiate the data problem.
final DataModel data = new DataModel();
// Create Routing Index Manager
RoutingIndexManager manager =
new RoutingIndexManager(data.timeMatrix.length, data.vehicleNumber, data.depot);
// Create Routing Model.
RoutingModel routing = new RoutingModel(manager);
Solver solver = routing.solver();
// Create and register a transit callback.
final int transitCallbackIndex =
routing.registerTransitCallback((long fromIndex, long toIndex) -> {
// Convert from routing variable Index to user NodeIndex.
int fromNode = manager.indexToNode(fromIndex);
int toNode = manager.indexToNode(toIndex);
return data.timeMatrix[fromNode][toNode];
});
// Define cost of each arc.
routing.setArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
// Add Time constraint.
routing.addDimension(transitCallbackIndex, // transit callback
1440, // allow waiting time
60 * 24 * 2,
false, // start cumul to zero
"Time");
RoutingDimension timeDimension = routing.getMutableDimension("Time");
// Add time window constraints for each location except depot.
for (int i = 1; i < data.timeWindows.length; ++i) {
long index = manager.nodeToIndex(i);
if (index >= 0) {
timeDimension.cumulVar(index).setRange(data.timeWindows[i][0], data.timeWindows[i][1]);
}
if (index == 5) {
timeDimension.slackVar(index).setRange(0, 1440);
}
}
// Add time window constraints for each vehicle start node.
for (int i = 0; i < data.vehicleNumber; ++i) {
long index = routing.start(i);
timeDimension.cumulVar(index).setRange(data.timeWindows[0][0], data.timeWindows[0][1]);
}
// Instantiate route start and end times to produce feasible times.
for (int i = 0; i < data.vehicleNumber; ++i) {
routing.addVariableMinimizedByFinalizer(timeDimension.cumulVar(routing.start(i)));
routing.addVariableMinimizedByFinalizer(timeDimension.cumulVar(routing.end(i)));
}
// Define Transportation Requests.
for (int[] request : data.pickupDeliveries) {
long pickupIndex = manager.nodeToIndex(request[0]);
long deliveryIndex = manager.nodeToIndex(request[1]);
routing.addPickupAndDelivery(pickupIndex, deliveryIndex);
solver.addConstraint(
solver.makeEquality(routing.vehicleVar(pickupIndex), routing.vehicleVar(deliveryIndex)));
solver.addConstraint(solver.makeLessOrEqual(
timeDimension.cumulVar(pickupIndex), timeDimension.cumulVar(deliveryIndex)));
}
// Setting first solution heuristic.
RoutingSearchParameters searchParameters =
main.defaultRoutingSearchParameters()
.toBuilder()
.setFirstSolutionStrategy(FirstSolutionStrategy.Value.PATH_CHEAPEST_ARC)
.build();
// Solve the problem.
Assignment solution = routing.solveWithParameters(searchParameters);
if (solution == null) {
System.err.println("No solution found");
return;
}
// Print solution on console.
printSolution(data, routing, manager, solution);
}
/// #brief Print the solution.
static void printSolution(
DataModel data, RoutingModel routing, RoutingIndexManager manager, Assignment solution) {
RoutingDimension timeDimension = routing.getMutableDimension("Time");
long totalTime = 0;
for (int i = 0; i < data.vehicleNumber; ++i) {
long index = routing.start(i);
logger.info("Route for Vehicle " + i + ":");
String route = "";
while (!routing.isEnd(index)) {
IntVar timeVar = timeDimension.cumulVar(index);
route += manager.indexToNode(index) + " Time(" + solution.min(timeVar) + ","
+ solution.max(timeVar) + ") -> ";
index = solution.value(routing.nextVar(index));
}
IntVar timeVar = timeDimension.cumulVar(index);
route += manager.indexToNode(index) + " Time(" + solution.min(timeVar) + ","
+ solution.max(timeVar) + ")";
logger.info(route);
logger.info("Time of the route: " + solution.min(timeVar) + "min");
totalTime += solution.min(timeVar);
}
logger.info("Total time of all routes: " + totalTime + "min");
}
}

In your code:
// Add time window constraints for each location except depot.
for (int i = 1; i < data.timeWindows.length; ++i) {
long index = manager.nodeToIndex(i);
if (index >= 0) {
timeDimension.cumulVar(index).setRange(data.timeWindows[i][0], data.timeWindows[i][1]);
}
if (index == 5) {
timeDimension.slackVar(index).setRange(0, 1440);
}
}
I think:
here your if conditions should use i,
since your loop start at 1 you already skip the depot (node 0),
your timeWindows structure already contains [0, 1440] for node 5.
to force slack to zero for P&D nodes you should use SetValue()
So you could rewrite it like this:
// Add time window constraints for each location except depot.
for (int i = 1; i < data.timeWindows.length; ++i) {
long index = manager.nodeToIndex(i);
timeDimension.cumulVar(index).setRange(data.timeWindows[i][0], data.timeWindows[i][1]);
if (i == 5) {
timeDimension.slackVar(index).setRange(data.timeWindows[i][0], data.timeWindows[i][1]);
} else { // disable waiting time for Pickup&Drop location
timeDimension.slackVar(index).setValue(0);
}
}
possible output:
$ mvn exec:java
[INFO] --- exec-maven-plugin:3.0.0:java (default-cli) # test ---
Dec 22, 2020 12:40:45 PM Test printSolution
INFO: Route for Vehicle 0:
Dec 22, 2020 12:40:45 PM Test printSolution
INFO: 0 Time(0,0) -> 1 Time(0,10) -> 2 Time(10,20) -> 5 Time(10,20) -> 3 Time(500,500) -> 4 Time(510,510) -> 0 Time(510,510)
Dec 22, 2020 12:40:45 PM Test printSolution
INFO: Time of the route: 510min
Dec 22, 2020 12:40:45 PM Test printSolution
INFO: Total time of all routes: 510min
So last question, what do you means by "but that doesn't work as I expected."
What is the observed output and what did you expect ?

Related

Microphone, gain value and spectrum values do not sync using Unity

I am making a simple voice visualization program. My goals are:
Playback microphone input
Visualize voice spectrum and gain in real time
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class VisualizeVoice : MonoBehaviour
{
private const int NUM_SPECTRUM_SAMPLES = 256;
private const int NUM_SPECTRUM_BARS = 32;
private const int NUM_PCM_SAMPLES = 16000;
private const float BAR_DROP_SPEED = 1e-3f;
private const int NUM_SAMPLES_TO_AVERAGE = 8;
private string _deviceName;
private float[] _spectrumData = new float[NUM_SPECTRUM_SAMPLES];
private float[] _fPCMData = new float[NUM_PCM_SAMPLES];
private float _gain = 0;
private AudioClip _audio; // Audio from microphone
private AudioSource _playback; // To play the audio from microphone
// For visualization
private GameObject[] _spectrumBars = new GameObject[NUM_SPECTRUM_BARS];
private GameObject _gainBar;
// Start is called before the first frame update
void Start()
{
if (Microphone.devices.Length == 0) {
Debug.LogError("No Microphone");
return;
}
_deviceName = Microphone.devices[0];
Debug.Log("Current microphone is " + _deviceName);
if ((_playback = this.GetComponent<AudioSource>()) == null) {
_playback = this.gameObject.AddComponent<AudioSource>();
}
_playback.loop = true;
_playback.bypassEffects = true;
_playback.bypassListenerEffects = true;
_playback.bypassReverbZones = true;
_playback.priority = 0;
_playback.pitch = 1;
_playback.clip = _audio = Microphone.Start(_deviceName, true, 1, AudioSettings.outputSampleRate);
// Sync microphone and playback, but it always fails
float waitTime = 0;
while (!(Microphone.GetPosition(_deviceName) > 0) && waitTime <= 2)
waitTime += Time.deltaTime;
if (waitTime > 2) {
Debug.LogError("time out waiting for microphone");
}
_playback.Play();
InitVisualization();
}
// Update is called once per frame
void Update()
{
// Get PCM data and calculate gain
var audioPosition = Microphone.GetPosition(_deviceName);
_audio.GetData(_fPCMData, audioPosition);
UpdateGain();
// Get spectrum data
_playback.GetSpectrumData(_spectrumData, 0, FFTWindow.BlackmanHarris);
// Update visualization
UpdateVisualization();
}
private void InitVisualization()
{
// Initialize spectrum bars
for (int ibar = 0; ibar < NUM_SPECTRUM_BARS; ibar++) {
_spectrumBars[ibar] = GameObject.CreatePrimitive(PrimitiveType.Cube);
_spectrumBars[ibar].transform.parent = this.transform;
_spectrumBars[ibar].transform.localPosition = new Vector3(ibar, 0, 0);
_spectrumBars[ibar].transform.localScale = new Vector3(1, 0, 1);
}
// Initialize gain bar
_gainBar = GameObject.CreatePrimitive(PrimitiveType.Cube);
_gainBar.transform.parent = this.transform;
_gainBar.transform.localPosition = new Vector3(-5, 0, 0);
_gainBar.transform.localScale = new Vector3(4, 0, 1);
// Overall dimension
this.transform.localScale = new Vector3(0.2f, 10.0f, 0.2f);
}
private void UpdateVisualization()
{
// Update spectrum bars
int nSamplesPerBar = NUM_SPECTRUM_SAMPLES / NUM_SPECTRUM_BARS;
for (int ibar = 0; ibar < NUM_SPECTRUM_BARS; ibar++) {
// Calculate value of each bar
float value = 0;
for (int isample = 0; isample < nSamplesPerBar; isample++) {
value += _spectrumData[ibar * nSamplesPerBar + isample];
}
value /= nSamplesPerBar;
// Use current value if increasing, or slowly drop previous value if decreasing
float prevValue = _spectrumBars[ibar].transform.localScale.y;
if (value < prevValue)
value = prevValue - BAR_DROP_SPEED;
// Y scale is set to value
_spectrumBars[ibar].transform.localScale = new Vector3(1, value, 1);
}
// Update gain bar
_gainBar.transform.localScale = new Vector3(4, _gain, 1);
}
private void UpdateGain()
{
_gain = 0;
for(int i = 0; i < NUM_SAMPLES_TO_AVERAGE; i++) {
_gain += Mathf.Abs(_fPCMData[NUM_PCM_SAMPLES - i - 1]);
}
_gain /= NUM_SAMPLES_TO_AVERAGE;
}
}
Here are my questions:
I can't use while (!Microphone.GetPosition(_deviceName) > 0)); to avoid latency from microphone to speaker. If I use it, my application just freezes. If I add code to allow time-out, it has time-out every time.
The gain bar seems irrelevant with my voice. I don't know if my calculation is right.
I'm not sure if I need to average over multiple samples calculating gains, and how many samples I need to average over. I need this gain value later to detect silent moments and cut audio data.
To 1.
You can. Unity allows to define Start as a Coroutine
private IEnumerator Start()
{
...
}
On this way you can use a non blocking
while (!Microphone.GetPosition(_deviceName) > 0))
{
yield return null;
}

SURF with hashing

I want to ask you if i can use hashing technique with SURF algorithm,i made a program to make face recognition by matching test image with saved image dataset.
i used Accord.net and made bag of features by BOW of this library then I made ID3 decision tree and KNN but the result in both ways were not very good, i am asking if i can use hashing technique to make fast and better result,or this will not be feasible ?
this is the code for BOW
private void button2_Click(object sender, EventArgs e)
{
try
{
var watchFEC = System.Diagnostics.Stopwatch.StartNew();
Accord.Math.Random.Generator.Seed = 0;
bow.ParallelOptions.MaxDegreeOfParallelism = 1;
bow.Learn(DatasetImages);
// After this point, we will be able to translate
// images into double[] feature vectors using
features = bow.Transform(DatasetImages);
watchFEC.Stop();
var elapsedMs = watchFEC.ElapsedMilliseconds;
MessageBox.Show("Feature Extraction and Clastering is done" + '\n' + "Time for Feature Extraction and Clastering for Dataset is: " + elapsedMs.ToString() + " ms");
} catch { MessageBox.Show("Error"); } }
and this is the code for learn
private void button3_Click(object sender, EventArgs e)
{
try
{
var watchLearn = System.Diagnostics.Stopwatch.StartNew();
inputs = features.ToInt32();
tree = teacher.Learn(inputs, outputs);
error = new ZeroOneLoss(outputs).Loss(tree.Decide(inputs));
MessageBox.Show("Error rate of learning is : "+error.ToString());
watchLearn.Stop();
var elapsedMs = watchLearn.ElapsedMilliseconds;
MessageBox.Show("Learning is done" + '\n' + "Time for Learning is: " + elapsedMs.ToString() + " ms");
}
catch(Exception ex) { MessageBox.Show("Error"+ex); }
}
and this code for test
private void button4_Click_1(object sender, EventArgs e)
{
try
{
var watchTest = System.Diagnostics.Stopwatch.StartNew();
Bitmap[] testimage = new Bitmap[1];
testimage[0] = (Bitmap)pictureBox1.Image;
var ff = bow.Transform(testimage);
ff.ToInt32();
var predicted = tree.Decide(ff);
int i = 1;
for (i = 1; i < sizeofdataset; i++)
{
if (predicted[0] == Convert.ToInt16(workSheet.Cells[i, 3].Value.ToString()))
{
listBox1.SelectedItem = i;
MessageBox.Show("Test" + i);
break;
}
}
MessageBox.Show("Test" + predicted[0]);
pictureBox2.Image = new Bitmap(workSheet.Cells[i, 1].Value.ToString());
watchTest.Stop();
var elapsedMs = watchTest.ElapsedMilliseconds;
MessageBox.Show("Time for Testing is: " + elapsedMs.ToString() + " ms");
}
catch (Exception ex) { MessageBox.Show("Error" + ex); }
}
Instead of ID3 or k-NN, please try using a SVM with a Chi-Square kernel.
If you would like to give SVMs a try, there is an example on how to create multi-class kernel SVMs at the bottom of this page (see second example). You can replace all places where it is written "Gaussian" by "ChiSquare" in order to create a chi-square SVM.
If you happen to run in a {"Index was outside the bounds of the array."} as you have indicated in the project's issue tracker, I think you might have a class without training or testing samples. Please make sure you have enough training samples for all classes, that your class numbers start at 0, that the highest class label in your output vector corresponds to the number_of_classes - 1 and that there are no integers in this interval without any associated training samples.
I am posting below an example on how to train SVMs using a Chi-Square kernel in the Accord.NET Framework:
// Let's say we have the following data to be classified
// into three possible classes. Those are the samples:
//
double[][] inputs =
{
// input output
new double[] { 0, 1, 1, 0 }, // 0
new double[] { 0, 1, 0, 0 }, // 0
new double[] { 0, 0, 1, 0 }, // 0
new double[] { 0, 1, 1, 0 }, // 0
new double[] { 0, 1, 0, 0 }, // 0
new double[] { 1, 0, 0, 0 }, // 1
new double[] { 1, 0, 0, 0 }, // 1
new double[] { 1, 0, 0, 1 }, // 1
new double[] { 0, 0, 0, 1 }, // 1
new double[] { 0, 0, 0, 1 }, // 1
new double[] { 1, 1, 1, 1 }, // 2
new double[] { 1, 0, 1, 1 }, // 2
new double[] { 1, 1, 0, 1 }, // 2
new double[] { 0, 1, 1, 1 }, // 2
new double[] { 1, 1, 1, 1 }, // 2
};
int[] outputs = // those are the class labels
{
0, 0, 0, 0, 0,
1, 1, 1, 1, 1,
2, 2, 2, 2, 2,
};
// Create the multi-class learning algorithm for the machine
var teacher = new MulticlassSupportVectorLearning<ChiSquare>()
{
// Configure the learning algorithm to use SMO to train the
// underlying SVMs in each of the binary class subproblems.
Learner = (param) => new SequentialMinimalOptimization<ChiSquare>()
{
// Estimate a suitable guess for the Gaussian kernel's parameters.
// This estimate can serve as a starting point for a grid search.
UseKernelEstimation = true
}
};
// Configure parallel execution options (or leave it at the default value for maximum speed)
teacher.ParallelOptions.MaxDegreeOfParallelism = 1;
// Learn a machine
var machine = teacher.Learn(inputs, outputs);
// Obtain class predictions for each sample
int[] predicted = machine.Decide(inputs);
// Get class scores for each sample
double[] scores = machine.Score(inputs);
// Compute classification error
double error = new ZeroOneLoss(outputs).Loss(predicted);

How to show Output as a text instead of number?

I use this code for print number 0 to 11 in a button:
colorize_combo = gtk_combo_box_text_new_with_entry();
for (int i = 0; i <= 2; i += 1)
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("%d", i));
gtk_combo_box_set_active(GTK_COMBO_BOX(colorize_combo), 11);
gtk_table_attach_defaults(GTK_TABLE(table), colorize_combo, 0, 1, 17, 18);
I use applyColorMap(unsharp, dstt, type_color) in opencv and I have 12 types color. these types color show up as numbers (0 to 11) . I want to show output as a "text" instead of "number" in my button. I can change types color with "color" button.
I just want to change for example, "0" to "AUTUMN", "1" to "BONE" , .... If you use gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("AUTUMN", 0)); that show up "0" to "AUTUMN" but I want all of them show up just with one gtk_combo_box_text_append_text.
I want to show output as a "text" instead of "number" in my button.
"AUTUMN" instead of "0"
"BONE" instead of "1"
"JET" instead of "2"
.
.
.
.
"PARULA" instead of "11"
What ideas on how to solve this task would you suggest? Or on what resource on the internet can I find help?
this is a part of my c++ code:
void incdec2(GtkWidget *widget, const gchar *mode)
{
else if (!g_strcmp0(mode, "colorized"))
{
if (gtk_image_get_pixbuf(GTK_IMAGE(img4)) == NULL)
return;
int type_color = atoi(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(colorize_combo)));
vector< Vec4i > hierarchy;
int largest_contour_index = 0;
int largest_area = 0;
vector< vector <Point> > contours1;
Mat alpha(src1.size(), CV_8UC1, Scalar(0));
normalize(alpha, alpha, 0, 250, NORM_MINMAX, CV_8UC3);
findContours(thresh, contours1, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); // Find the contours in the image
for (int i = 0; i< contours1.size(); i++) // iterate through each contour.
{
double a = contourArea(contours1[i], false); // Find the area of contour
if (a>largest_area){
largest_area = a;
largest_contour_index = i; //Store the index of largest contour
}
}
drawContours(alpha, contours1, largest_contour_index, Scalar(255), CV_FILLED, 8, hierarchy);
applyColorMap(unsharp, dstt, type_color);
split(dstt, rgb);
Mat rgbe[4] = { rgb[0], rgb[1], rgb[2], alpha };
merge(rgbe, 4, im_color);
imwrite("Colorized Image.png", im_color);
gtk_image_set_from_file(GTK_IMAGE(img4), "Colorized Image.png");
}
}
int main(int argc, char *argv[])
{
.
.
.
.
.
colorize_combo = gtk_combo_box_text_new_with_entry();
for (int i = 0; i <= 11; i += 1)
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("%d", i));
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("AUTUMN", 0));
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("BONE", 1));
// gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("JET", 2));
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("WINTER", 3));
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("RAINBOW", 4));
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("OCEAN", 5));
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("SUMMER", 6));
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("SPRING", 7));
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("COOL", 8));
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("HSV", 9));
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("PINK", 10));
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("HOT", 11));
//gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("PARULA", 12));
gtk_combo_box_set_active(GTK_COMBO_BOX(colorize_combo), 11);
gtk_table_attach_defaults(GTK_TABLE(table), colorize_combo, 0, 1, 17, 18);
but13 = bold_img_button("Color", "E:/Works for Gov Project/DOC/GUI/logogui1/colorize243.png");
gdk_color_parse("#50a0ff", &color);
gtk_widget_modify_bg(but13, GTK_STATE_NORMAL, &color);
gtk_table_attach_defaults(GTK_TABLE(table), but13, 1, 2, 17, 18);
g_signal_connect(G_OBJECT(but13), "clicked", G_CALLBACK(incdec2), "colorized");
.
.
.
.
}
For example, I edit my loop as:
string texts[] = { "AUTUMN", "BONE", "JET" };
int size = sizeof(texts) / sizeof(string);
for (int i = 0; i < size; i++)
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("%s", texts[i]));
but it doesn't work correctly.
UPDATED with how to decode the value in the combo box
You don't need g_strdup_printf: gtk_combo_box_text_append_text takes a const gchar *. This means it won't modify the string you pass, it will create a copy by itself.
At the top of your file, declare:
static const char *color_names[] = { "AUTUMN", "BONE", "JET" };
Then, where you're filling your combo box, replace:
string texts[] = { "AUTUMN", "BONE", "JET" };
int size = sizeof(texts) / sizeof(string);
for (int i = 0; i < size; i++)
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), g_strdup_printf("%s", texts[i]));
with:
for (int i = 0; i < G_N_ELEMENTS(texts); i++)
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(colorize_combo), texts[i]);
Finally, where you read the text selected by the combo box, replace:
int type_color = atoi(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(colorize_combo)));
with:
int type_color = -1;
gchar * selected_color_name = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(colorize_combo));
for (int i = 0; i < G_N_ELEMENTS(color_names); i++)
if (g_strcmp0(selected_color_name, color_names[i]) == 0)
type_color = i;
// gtk_combo_box_text_get_active_text return a string that must be freed as stated in the doc
g_free(selected_color_name);

Processing Class/object variable stacking

So I have a problem that I've managed to fix before (by fluke) in simpler programs, but still don't know what the actual problem is.
I have created an class containing the following variables g1.display(tableHr, hrMeasure, 37, 10, 20,160, 0);. The problem is, when I run one object of the class it's all fine and a nice graph is created. Though when I run two objects of the class, the first graph in the program runs fine and the second one gets morphed out of proportion. Almost like variables are stacking or multiplying each other.
Anyone familiar with this problem?
The Main sketch's code:
Graph g1 = new Graph();
Button b1 = new Button();
TableRow hrMeasure;
TableRow spoMeasure;
TableRow tempMeasure;
Table tableHr;
Table tableSpo;
Table tableAbp;
Table tableResp;
Table tableTemp;
int i;
int border;
float p;
PFont font;
PFont font2;
String alarmColor;
void setup(){
font = loadFont("data/OpenSans-36.vlw");
textFont(font,36);
frameRate(15);
smooth(8);
size(1024,768);
tableHr = loadTable("testfile.csv", "header");
tableSpo = loadTable("testfile2.csv", "header");
tableAbp = loadTable("testfile3.csv", "header");
tableResp = loadTable("testfile4.csv", "header");
tableTemp = loadTable("testfile5.csv", "header");
}
void draw(){
retrieveData();
GUI();
relativeGraph();
buttons();
g1.display(tableHr, hrMeasure, 40, 15, 25,200,100);
// g1.display(tableSpo, spoMeasure, 37, 1, 3,160,2);
// g1.display(tableTemp, tempMeasure, 37, 1, 3,160,3);
// g1.display(tableHr, hrMeasure, 37, 13, 18,160,4);
// g1.display(tableHr, hrMeasure, 37, 13, 18,160,5);
}
//retrieving data from the csv file
void retrieveData(){
i++;
hrMeasure = tableHr.getRow(i);
spoMeasure = tableSpo.getRow(i);
tempMeasure = tableTemp.getRow(i);
}
Class:
class Graph {
int adjustment;
float p;
int greenRelative, yellowRelative, redRelative;
float[] measure = new float[1500000];
String alarmColor;
int timer, counter;
int greenTimer, yellowTimer, redTimer;
int graphHeight = 80;
int graphLength = 800;
void display(Table table, TableRow measurement, int average, int bound1, int bound2,int x, int y){
p = measurement.getFloat("value");
pushMatrix();
translate(width,0);
scale(-1,1);
for (int i = 0; i < table.getRowCount(); i++){
adjustment = width-table.getRowCount()-x; // adjustment to the x-coordinate, so every graph will start at 0
//if statement for green readings
if(measure[i] > average-bound1 && measure[i] < average+bound1){
stroke(0, 255, 0);
strokeWeight(1);
alarmColor = "green";
}else{
//if statement for yellow readings
if(measure[i] <= average-bound1 && measure[i] > average-bound2|| measure[i] >= average+bound1 && measure[i] < average+bound2){
stroke(255, 255, 0);
strokeWeight(1);
alarmColor = "yellow";
//else red
}else{stroke(255, 0, 0);
strokeWeight(1);
alarmColor = "red";
}}
line(i+adjustment, graphHeight-map(measure[i], average-bound1-bound2, 37, 0,graphHeight/2)+y, (i+1)+adjustment, graphHeight-map(measure[i+1], average-bound1-bound2, 37, 0,graphHeight/2)+y);
}
popMatrix();
for(int i=0; i < table.getRowCount(); i++){
measure[i] = measure[i+1];
measure[i+1] = p;
println(measure[i]);
}
Ensure you are using independent instances, for example:
Graph g1 = new Graph();
Graph g2 = new Graph();
then in draw():
g1.display(tableHr, hrMeasure, 40, 15, 25,200,100);
g2.display(tableSpo, spoMeasure, 37, 1, 3,160,2);
Full listing:
Graph g1 = new Graph();
Graph g2 = new Graph();
Graph g3 = new Graph();
Graph g4 = new Graph();
Graph g5 = new Graph();
Button b1 = new Button();
TableRow hrMeasure;
TableRow spoMeasure;
TableRow tempMeasure;
Table tableHr;
Table tableSpo;
Table tableAbp;
Table tableResp;
Table tableTemp;
int i;
int border;
float p;
PFont font;
PFont font2;
String alarmColor;
void setup(){
font = loadFont("data/OpenSans-36.vlw");
textFont(font,36);
frameRate(15);
smooth(8);
size(1024,768);
tableHr = loadTable("testfile.csv", "header");
tableSpo = loadTable("testfile2.csv", "header");
tableAbp = loadTable("testfile3.csv", "header");
tableResp = loadTable("testfile4.csv", "header");
tableTemp = loadTable("testfile5.csv", "header");
}
void draw(){
retrieveData();
GUI();
relativeGraph();
buttons();
g1.display(tableHr, hrMeasure, 40, 15, 25,200,100);
g2.display(tableSpo, spoMeasure, 37, 1, 3,160,2);
g3.display(tableTemp, tempMeasure, 37, 1, 3,160,3);
g4.display(tableHr, hrMeasure, 37, 13, 18,160,4);
g5.display(tableHr, hrMeasure, 37, 13, 18,160,5);
}
//retrieving data from the csv file
void retrieveData(){
i++;
hrMeasure = tableHr.getRow(i);
spoMeasure = tableSpo.getRow(i);
tempMeasure = tableTemp.getRow(i);
}
class Graph {
int adjustment;
float p;
int greenRelative, yellowRelative, redRelative;
float[] measure = new float[1500000];
String alarmColor;
int timer, counter;
int greenTimer, yellowTimer, redTimer;
int graphHeight = 80;
int graphLength = 800;
void display(Table table, TableRow measurement, int average, int bound1, int bound2,int x, int y){
p = measurement.getFloat("value");
pushMatrix();
translate(width,0);
scale(-1,1);
for (int i = 0; i < table.getRowCount(); i++){
adjustment = width-table.getRowCount()-x; // adjustment to the x-coordinate, so every graph will start at 0
//if statement for green readings
if(measure[i] > average-bound1 && measure[i] < average+bound1){
stroke(0, 255, 0);
strokeWeight(1);
alarmColor = "green";
}else{
//if statement for yellow readings
if(measure[i] <= average-bound1 && measure[i] > average-bound2|| measure[i] >= average+bound1 && measure[i] < average+bound2){
stroke(255, 255, 0);
strokeWeight(1);
alarmColor = "yellow";
//else red
}else{stroke(255, 0, 0);
strokeWeight(1);
alarmColor = "red";
}}
line(i+adjustment, graphHeight-map(measure[i], average-bound1-bound2, 37, 0,graphHeight/2)+y, (i+1)+adjustment, graphHeight-map(measure[i+1], average-bound1-bound2, 37, 0,graphHeight/2)+y);
}
popMatrix();
for(int i=0; i < table.getRowCount(); i++){
measure[i] = measure[i+1];
measure[i+1] = p;
println(measure[i]);
}

Queue implementation using circular array

I am trying to implement the queue using an array. But my implementation is not working. I couldn't find the mistake. My implementations are as follows:
class ArrayQueue[T: ClassManifest] extends Queue[T] {
private var A = new Array[T](2) // array for storing the queue elements
private var front = 0 // index of the front element in the array
private var rear = 0 // index of the rear element in the array
private var item_num = 0 // number of elements that are in the array
// when an array overflows we double the size of the array
private def grow() {
val B = A
A = new Array[T](2 * B.length)
if (front < rear) {
for ( i <- 0 until B.length)
A(i) = B(i)
}
else {
System.arraycopy(B, rear, A, 0, B.length - rear)
System.arraycopy(B, 0, A, B.length-rear, front)
front = B.length - (rear - front)
rear = 0
}
}
def clear(): Unit = {
A = new Array[T](22)
front = 0
rear = 0
item_num = 0
}
def isEmpty: Boolean = (item_num == 0)
def head = {
if (isEmpty)
throw new NoSuchElementException
A(front)
}
def dequeue(): T = {
if (isEmpty)
throw new NoSuchElementException
front += 1
item_num = item_num - 1
A(front - 1)
}
def enqueue(elem: T): Unit = {
A(rear) = elem
rear += 1
item_num += 1
if (rear == A.length - 1 && item_num != A.length)
rear = 0
if (item_num == A.length || rear == front - 1) {
grow()
}
if (item_num == 0) {
front = 0
rear = 0 }
}
Queue has 5 methods including enqueue, dequeue, isEmpty, clear, head.
In my code head method returns the element at front position
isEmpty returns true if item_num = 0
Clear method clears the queue
Method enqueue must add elements after rear and increase the rear by 1. I think I have some mistake here
Method dequeue returns the first element and removes it.
However, I am having an error. Can you please tell me some hints? Thank you in advance.
To put it simply, in a circular array, whenever a pointer moves, you have to check it and fix it if necessary. You don't do that in dequeue.
The logic inside enqueue is not correct either.
Finally, you have two pointers and a counter. You shouldn't need three things, only two.
There are lots of logical errors. Its hard to find any correct thing implemented in your code.
trying answering following
(1) do you really need to do front = B.length - (rear - front) inside grow() when you already know that grow()is called when the array/queue is full
(2) in case if the if() condition evaluates to true, what are you doing?
let say initially A=[1 2 3 4], front =3, rear =2, then your new array will be [1 2 3 4 0 0 0 0] with same front and rear values. Is it valid?
(3) check the enque and deque logics also.
(4) consider serialization of the queue data otherwise it will go in an inconsistent state.
(5) to ease, you can simply use rear = (rear+1)%length no need to check,no ifs needed.
I am posting the complete code here to implement circular queue using array in java.
trim(): trim the size of array.
package com.java.util.collection.advance.datastructure.queue;
public interface Queue<E>{
boolean addR(E e);
E removeL();
E element();
boolean isFull();
boolean isEmpty();
void trim();
}
package com.java.util.collection.advance.datastructure.queue;
public interface CircularQueue<E> extends Queue<E>{
}
package com.java.util.collection.advance.datastructure.queue;
import java.util.Arrays;
public class MyCircularQueue<E> implements CircularQueue<E>{
private int front = 0;
private int rear =-1;
private E[] elements =null;
private static final int DEFAULT_INTIAL_CAPACITY =100;
private int size =0;
public MyCircularQueue(){
this(DEFAULT_INTIAL_CAPACITY);
}
#SuppressWarnings("unchecked")
public MyCircularQueue(int intialCapacity){
if(intialCapacity < 0){
throw new IllegalArgumentException("intial capacity can't be null");
}
elements =(E[]) new Object[intialCapacity];
}
#Override
public boolean addR(E e) {
if(! isFull()) {
rear = (rear+1)%elements.length;
elements[rear] = e;
size++;
return true;
}
return false;
}
#Override
public E removeL() {
E element =null;
if(!isEmpty()){
if(front == elements.length-1)
{
front =(front+1)%elements.length;
}
element=elements[front];
// Nullify the reference
elements[front] =null;
front++;
--size;
}
return element;
}
#Override
public E element() {
E element =null;
if(!isEmpty()){
element=elements[front];
}
return element;
}
#Override
public boolean isFull() {
return size == elements.length;
}
#Override
public boolean isEmpty() {
return size == 0;
}
#Override
// Do Nothing
public void trim() {
#SuppressWarnings("unchecked")
E[]dest =(E[]) new Object[size];
if(front < rear) {
System.arraycopy(elements, front, dest, front-1,rear);
} else {
System.arraycopy(elements, front, dest, 0, size-front+1);
System.arraycopy(elements, 0, dest, size-front+1, front-rear);
front =0;
rear = size;
}
elements =dest;
}
#Override
public String toString() {
return "MyCircularQueue [front=" + front + ", rear=" + rear
+ ", elements=" + Arrays.toString(elements) + ", size=" + size
+ "]";
}
}
Test class:
package com.java.util.collection.advance.datastructure.queue;
import java.util.Random;
public class MyCircularQueueApp<E> {
public static void main(String[] args) {
CircularQueue<Integer> cirQueue =new MyCircularQueue<Integer>(11);
Random random =new Random();
for(int i=0;i<10;i++){
cirQueue.addR(random.nextInt(3));
}
System.out.println(cirQueue);
cirQueue.removeL();
System.out.println("Before triming: "+cirQueue);
cirQueue.trim();
System.out.println("After triming: "+cirQueue);
cirQueue.removeL();
System.out.println(cirQueue);
cirQueue.addR(1000);
System.out.println(cirQueue);
cirQueue.addR(10000);
cirQueue.addR(100000);
System.out.println(cirQueue);
System.out.println(cirQueue.element());
}
}
Output:
MyCircularQueue [front=0, rear=9, elements=[1, 2, 2, 2, 1, 2, 2, 1, 2, 1, null], size=10]
Before triming: MyCircularQueue [front=1, rear=9, elements=[null, 2, 2, 2, 1, 2, 2, 1, 2, 1, null], size=9]
After triming: MyCircularQueue [front=1, rear=9, elements=[2, 2, 2, 1, 2, 2, 1, 2, 1], size=9]
MyCircularQueue [front=2, rear=9, elements=[2, null, 2, 1, 2, 2, 1, 2, 1], size=8]
MyCircularQueue [front=2, rear=1, elements=[2, 1000, 2, 1, 2, 2, 1, 2, 1], size=9]
MyCircularQueue [front=2, rear=1, elements=[2, 1000, 2, 1, 2, 2, 1, 2, 1], size=9]