3

I am facing a problem in my project. I have different types of controller that provide different input and output ports. I have the number of required points. I need some code that generate the number of controllers and types depending on the required point + some spare points that should be assigned as like the cheapest combination.

For example, I have a system that requires :

  • digital output point = 8
  • analog output point = 2
  • digital input point = 15
  • analog input points = 4

and what I need is to spare 15% on each input/output :

What I have is:

  • controller 1 providing :
  • 3 digital inputs
  • 2 analog outputs
  • 10 digital outputs
  • 4 analog inputs
  • controller 2 providing:
  • 2 digital inputs
  • 1 analog output
  • 3 digital outputs
  • 3 analog inputs

The price of controller 1 is 200$ and the price of controller 2 is 120$.

How can I start programming this code either on excel or using javascript?

Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • does controller2 has no analog input? – Nina Scholz Apr 06 '16 at 10:40
  • ahh sorry i will correct my mistake now it has 3 analog imputs – kamil abou jaoude Apr 06 '16 at 10:45
  • the thing is that i need some help to begin so i know where to do my research i know what i asked is something not easy, i would be very happy if you can provide that help needed if there is anything i can do as some research i am ready i dont want just to sit and wait and if anything new or i get any hint i will post it – kamil abou jaoude Apr 06 '16 at 11:00

1 Answers1

1

To get you started, you could think about a data structure, which makes all data comparable and iterable.

Raw data

                requirement  controller 1 controller 2
cost               minimum          200          120
digital output           8           10            3
analog output            2            2            1
digital input           15            3            2
analog input             4            4            3

The code gives you an array with all possible combinations of the two controllers and the optimum.

function getCount() {
    function check(count, constraint) { return function (b, i) { return b <= count * constraint[i]; }; }
    function getCost(item, count) { return constraints.items[item].cost * count; }

    var i = 0, count, data, o, result = [];

    do {
        count = 0;
        data = constraints.requirements.data.map(function (a, j) {
            return a - i * constraints.items[0].data[j];
        });
        while (!data.every(check(count, constraints.items[1].data))) {
            count++;
        }
        o = { count: [i, count], cost: [getCost(0, i), getCost(1, count)] };
        o.total = o.cost.reduce(function (a, b) { return a + b; }, 0);
        result.push(o);
        i++;
    } while (count);
    return result;
}

var constraints = {
        requirements: { data: [8, 2, 15, 4], optimum: 'min' },
        items: [
            { data: [10, 2, 3, 4], cost: 200 },
            { data: [3, 1, 2, 3], cost: 120 }
        ]
    },
    result = getCount(),
    optimum = result.reduce(function (r, a, i) {
        if (!i || a.total === Math[constraints.requirements.optimum](r[0].total, a.total)) {
            return [a];
        }
        r[0].total === a.total && r.push(a);
        return r;
    }, []);

document.write("<pre>optimum: " + JSON.stringify(optimum, 0, 4) + "</pre>");
document.write("<pre>result: " + JSON.stringify(result, 0, 4) + "</pre>");

Update for more than two controllers/items

function getResult() {
    function add(a, b) { return a + b; }
    function check(count, constraint) {
        return function (b, i) {
            return !b || b <= count * constraint[i];
        };
    }

    function iter(data, count, level) {
        var temp;

        count[level] = count[level] || 0;
        count = count.slice();
        if (level + 1 === constraints.items.length) {
            while (!data.every(check(count[level], constraints.items[level].data))) {
                count[level]++;
            }
            temp = {
                count: count,
                cost: count.map(function (a, i) {
                    return a * constraints.items[i].cost;
                })
            };
            temp.total = temp.cost.reduce(add, 0);
            result.push(temp);
            return;
        }

        do {
            iter(data, count, level + 1);
            if (!data.reduce(add, 0)) {
                break;
            }
            data = data.map(function (a, j) {
                return Math.max(0, a - constraints.items[level].data[j]);
            });
            count[level]++;
        } while (true);
    }

    var result = [];

    iter(constraints.requirements.data.slice(), [], 0);
    return result;
}

var constraints = {
        requirements: { data: [8, 2, 15, 4], optimum: 'min' },
        items: [
            { data: [10, 2, 3, 4], cost: 200 },
            { data: [3, 1, 2, 3], cost: 120 },
            { data: [1, 1, 1, 1], cost: 75 }
        ]
    },
    result = getResult(),
    optimum = result.reduce(function (r, a, i) {
        if (!i || a.total === Math[constraints.requirements.optimum](r[0].total, a.total)) {
            return [a];
        }
        r[0].total === a.total && r.push(a);
        return r;
    }, []);

document.write("<pre>optimum: " + JSON.stringify(optimum, 0, 4) + "</pre>");
document.write("<pre>result: " + JSON.stringify(result, 0, 4) + "</pre>");
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • Dear Nina, thank you for that superb code that you did so quickly but what about talking about a combination between the 2 controllers ? is this function doable ?! – kamil abou jaoude Apr 06 '16 at 12:00
  • thank you for this code dear nina i will test it and i will try to develop it. and for any further question i will come to you in seek for help. i dont know if anyone ever told you that you are amazing and a life savor – kamil abou jaoude Apr 06 '16 at 12:55