aboutsummaryrefslogtreecommitdiff
path: root/src/ats/plugin_ats_mlp.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2014-05-12 18:31:16 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2014-05-12 18:31:16 +0000
commit9c56050d0805cde393515f63d9b2d8918f8d4c76 (patch)
tree06dd1795617f74f38ad63dbd4b33aae168de67e3 /src/ats/plugin_ats_mlp.c
parentd743a7e758a4fd96f5997a2b6d0f2ce4d62e13cf (diff)
downloadgnunet-9c56050d0805cde393515f63d9b2d8918f8d4c76.tar.gz
gnunet-9c56050d0805cde393515f63d9b2d8918f8d4c76.zip
adding config option to check for feasibility only
Diffstat (limited to 'src/ats/plugin_ats_mlp.c')
-rw-r--r--src/ats/plugin_ats_mlp.c206
1 files changed, 112 insertions, 94 deletions
diff --git a/src/ats/plugin_ats_mlp.c b/src/ats/plugin_ats_mlp.c
index 27a502f13..20ffbbfaf 100644
--- a/src/ats/plugin_ats_mlp.c
+++ b/src/ats/plugin_ats_mlp.c
@@ -139,15 +139,6 @@
139 139
140 140
141/** 141/**
142 * Maximize bandwidth assigned
143 *
144 * This option can be used to test if problem can be solved at all without
145 * optimizing for utility, diversity or relativity
146 *
147 */
148#define MAXIMIZE_FOR_BANDWIDTH_ASSIGNED GNUNET_NO
149
150/**
151 * Intercept GLPK terminal output 142 * Intercept GLPK terminal output
152 * @param info the mlp handle 143 * @param info the mlp handle
153 * @param s the string to print 144 * @param s the string to print
@@ -554,7 +545,11 @@ mlp_create_problem_set_value (struct MLP_Problem *p,
554 return; 545 return;
555 } 546 }
556 if ((0 == row) || (0 == col)) 547 if ((0 == row) || (0 == col))
548 {
557 GNUNET_break (0); 549 GNUNET_break (0);
550 LOG (GNUNET_ERROR_TYPE_ERROR, "[P]: Invalid call from line %u: row = %u, col = %u\n",
551 line, row, col);
552 }
558 p->ia[p->ci] = row ; 553 p->ia[p->ci] = row ;
559 p->ja[p->ci] = col; 554 p->ja[p->ci] = col;
560 p->ar[p->ci] = val; 555 p->ar[p->ci] = val;
@@ -657,16 +652,19 @@ mlp_create_problem_add_address_information (void *cls,
657 if (peer->processed == GNUNET_NO) 652 if (peer->processed == GNUNET_NO)
658 { 653 {
659 /* Add peer dependent constraints */ 654 /* Add peer dependent constraints */
660 /* Add constraint c2 */ 655 /* Add c2) One address active per peer */
661 GNUNET_asprintf(&name, "c2_%s", GNUNET_i2s(&address->peer)); 656 GNUNET_asprintf(&name, "c2_%s", GNUNET_i2s(&address->peer));
662 peer->r_c2 = mlp_create_problem_create_constraint (p, name, GLP_FX, 1.0, 1.0); 657 peer->r_c2 = mlp_create_problem_create_constraint (p, name, GLP_FX, 1.0, 1.0);
663 GNUNET_free (name); 658 GNUNET_free (name);
664 /* Add constraint c9 */ 659 if (GNUNET_NO == mlp->opt_feasibility_only)
665 GNUNET_asprintf(&name, "c9_%s", GNUNET_i2s(&address->peer)); 660 {
666 peer->r_c9 = mlp_create_problem_create_constraint (p, name, GLP_LO, 0.0, 0.0); 661 /* Add c9) Relativity */
667 GNUNET_free (name); 662 GNUNET_asprintf(&name, "c9_%s", GNUNET_i2s(&address->peer));
668 /* c 9) set coefficient */ 663 peer->r_c9 = mlp_create_problem_create_constraint (p, name, GLP_LO, 0.0, 0.0);
669 mlp_create_problem_set_value (p, peer->r_c9, p->c_r, -peer->f, __LINE__); 664 GNUNET_free (name);
665 /* c9) set coefficient */
666 mlp_create_problem_set_value (p, peer->r_c9, p->c_r, -peer->f, __LINE__);
667 }
670 peer->processed = GNUNET_YES; 668 peer->processed = GNUNET_YES;
671 } 669 }
672 670
@@ -679,27 +677,27 @@ mlp_create_problem_add_address_information (void *cls,
679 677
680 /* Add bandwidth column */ 678 /* Add bandwidth column */
681 GNUNET_asprintf (&name, "b_%s_%s_%p", GNUNET_i2s (&address->peer), address->plugin, address); 679 GNUNET_asprintf (&name, "b_%s_%s_%p", GNUNET_i2s (&address->peer), address->plugin, address);
682#if TEST_MAX_BW_ASSIGNMENT 680 if (GNUNET_NO == mlp->opt_feasibility_only)
683 mlpi->c_b = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO, 0.0, 0.0, 1.0); 681 {
684#else 682 mlpi->c_b = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO, 0.0, 0.0, 0.0);
685 mlpi->c_b = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO, 0.0, 0.0, 0.0); 683 }
686#endif 684 else
687 685 {
686 /* Maximize for bandwidth assignment in feasibility testing */
687 mlpi->c_b = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO, 0.0, 0.0, 1.0);
688 }
688 GNUNET_free (name); 689 GNUNET_free (name);
689 690
690 /* Add usage column */ 691 /* Add address active column */
691 GNUNET_asprintf (&name, "n_%s_%s_%p", GNUNET_i2s (&address->peer), address->plugin, address); 692 GNUNET_asprintf (&name, "n_%s_%s_%p", GNUNET_i2s (&address->peer), address->plugin, address);
692 mlpi->c_n = mlp_create_problem_create_column (p, name, GLP_IV, GLP_DB, 0.0, 1.0, 0.0); 693 mlpi->c_n = mlp_create_problem_create_column (p, name, GLP_IV, GLP_DB, 0.0, 1.0, 0.0);
693 GNUNET_free (name); 694 GNUNET_free (name);
694 695
695 /* Add address dependent constraints */ 696 /* Add address dependent constraints */
696 /* Add constraint c1) bandwidth capping 697 /* Add c1) bandwidth capping: b_t + (-M) * n_t <= 0 */
697 * b_t + (-M) * n_t <= 0
698 * */
699 GNUNET_asprintf(&name, "c1_%s_%s_%p", GNUNET_i2s(&address->peer), address->plugin, address); 698 GNUNET_asprintf(&name, "c1_%s_%s_%p", GNUNET_i2s(&address->peer), address->plugin, address);
700 mlpi->r_c1 = mlp_create_problem_create_constraint (p, name, GLP_UP, 0.0, 0.0); 699 mlpi->r_c1 = mlp_create_problem_create_constraint (p, name, GLP_UP, 0.0, 0.0);
701 GNUNET_free (name); 700 GNUNET_free (name);
702
703 /* c1) set b = 1 coefficient */ 701 /* c1) set b = 1 coefficient */
704 mlp_create_problem_set_value (p, mlpi->r_c1, mlpi->c_b, 1, __LINE__); 702 mlp_create_problem_set_value (p, mlpi->r_c1, mlpi->c_b, 1, __LINE__);
705 /* c1) set n = -M coefficient */ 703 /* c1) set n = -M coefficient */
@@ -719,17 +717,13 @@ mlp_create_problem_add_address_information (void *cls,
719 717
720 718
721 /* Set coefficient entries in invariant rows */ 719 /* Set coefficient entries in invariant rows */
720
721 /* Feasbility */
722
722 /* c 4) minimum connections */ 723 /* c 4) minimum connections */
723 mlp_create_problem_set_value (p, p->r_c4, mlpi->c_n, 1, __LINE__); 724 mlp_create_problem_set_value (p, p->r_c4, mlpi->c_n, 1, __LINE__);
724 /* c 6) maximize diversity */
725 mlp_create_problem_set_value (p, p->r_c6, mlpi->c_n, 1, __LINE__);
726 /* c 2) 1 address peer peer */ 725 /* c 2) 1 address peer peer */
727 mlp_create_problem_set_value (p, peer->r_c2, mlpi->c_n, 1, __LINE__); 726 mlp_create_problem_set_value (p, peer->r_c2, mlpi->c_n, 1, __LINE__);
728 /* c 9) relativity */
729 mlp_create_problem_set_value (p, peer->r_c9, mlpi->c_b, 1, __LINE__);
730 /* c 8) utility */
731 mlp_create_problem_set_value (p, p->r_c8, mlpi->c_b, 1, __LINE__);
732
733 /* c 10) obey network specific quotas 727 /* c 10) obey network specific quotas
734 * (1)*b_1 + ... + (1)*b_m <= quota_n 728 * (1)*b_1 + ... + (1)*b_m <= quota_n
735 */ 729 */
@@ -749,20 +743,29 @@ mlp_create_problem_add_address_information (void *cls,
749 } 743 }
750 } 744 }
751 745
752 /* c 7) Optimize quality */ 746 /* Optimality */
753 /* For all quality metrics, set quality of this address */ 747 if (GNUNET_NO == mlp->opt_feasibility_only)
754 props = mlp->get_properties (mlp->get_properties_cls, address);
755 for (c = 0; c < mlp->pv.m_q; c++)
756 { 748 {
757 if ((props[c] < 1.0) && (props[c] > 2.0)) 749 /* c 6) maximize diversity */
750 mlp_create_problem_set_value (p, p->r_c6, mlpi->c_n, 1, __LINE__);
751 /* c 9) relativity */
752 mlp_create_problem_set_value (p, peer->r_c9, mlpi->c_b, 1, __LINE__);
753 /* c 8) utility */
754 mlp_create_problem_set_value (p, p->r_c8, mlpi->c_b, 1, __LINE__);
755 /* c 7) Optimize quality */
756 /* For all quality metrics, set quality of this address */
757 props = mlp->get_properties (mlp->get_properties_cls, address);
758 for (c = 0; c < mlp->pv.m_q; c++)
758 { 759 {
759 fprintf (stderr, "PROP == %.3f \t ", props[c]); 760 if ((props[c] < 1.0) && (props[c] > 2.0))
760 GNUNET_break (0); 761 {
762 fprintf (stderr, "PROP == %.3f \t ", props[c]);
763 GNUNET_break (0);
764 }
765 mlp_create_problem_set_value (p, p->r_q[c], mlpi->c_b, props[c], __LINE__);
761 } 766 }
762 mlp_create_problem_set_value (p, p->r_q[c], mlpi->c_b, props[c], __LINE__);
763 } 767 }
764 768
765 //fprintf (stderr, "\n");
766 return GNUNET_OK; 769 return GNUNET_OK;
767} 770}
768 771
@@ -772,19 +775,15 @@ mlp_create_problem_add_address_information (void *cls,
772static void 775static void
773mlp_create_problem_add_invariant_rows (struct GAS_MLP_Handle *mlp, struct MLP_Problem *p) 776mlp_create_problem_add_invariant_rows (struct GAS_MLP_Handle *mlp, struct MLP_Problem *p)
774{ 777{
775 char *name;
776 int c; 778 int c;
777 779
780 /* Feasibility */
781
778 /* Row for c4) minimum connection */ 782 /* Row for c4) minimum connection */
779 /* Number of minimum connections is min(|Peers|, n_min) */ 783 /* Number of minimum connections is min(|Peers|, n_min) */
780 p->r_c4 = mlp_create_problem_create_constraint (p, "c4", GLP_LO, (mlp->pv.n_min > p->num_peers) ? p->num_peers : mlp->pv.n_min, 0.0); 784 p->r_c4 = mlp_create_problem_create_constraint (p, "c4", GLP_LO, (mlp->pv.n_min > p->num_peers) ? p->num_peers : mlp->pv.n_min, 0.0);
781 785
782 /* Add row for c6) */ 786 /* Rows for c 10) Enforce network quotas */
783 p->r_c6 = mlp_create_problem_create_constraint (p, "c6", GLP_FX, 0.0, 0.0);
784 /* c6 )Setting -D */
785 mlp_create_problem_set_value (p, p->r_c6, p->c_d, -1, __LINE__);
786
787 /* Add rows for c 10) */
788 for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++) 787 for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
789 { 788 {
790 char * text; 789 char * text;
@@ -794,18 +793,29 @@ mlp_create_problem_add_invariant_rows (struct GAS_MLP_Handle *mlp, struct MLP_Pr
794 GNUNET_free (text); 793 GNUNET_free (text);
795 } 794 }
796 795
797 /* Adding rows for c 8) */ 796 /* Optimality */
798 p->r_c8 = mlp_create_problem_create_constraint (p, "c8", GLP_FX, 0.0, 0.0); 797 if (GNUNET_NO == mlp->opt_feasibility_only)
799 /* -u */
800 mlp_create_problem_set_value (p, p->r_c8, p->c_u, -1, __LINE__);
801
802 /* c 7) For all quality metrics */
803 for (c = 0; c < mlp->pv.m_q; c++)
804 { 798 {
805 GNUNET_asprintf(&name, "c7_q%i_%s", c, mlp_ats_to_string(mlp->pv.q[c])); 799 char *name;
806 p->r_q[c] = mlp_create_problem_create_constraint (p, name, GLP_FX, 0.0, 0.0); 800 /* Add row for c6) Maximize for diversity */
807 GNUNET_free (name); 801 p->r_c6 = mlp_create_problem_create_constraint (p, "c6", GLP_FX, 0.0, 0.0);
808 mlp_create_problem_set_value (p, p->r_q[c], p->c_q[c], -1, __LINE__); 802 /* Set c6 ) Setting -D */
803 mlp_create_problem_set_value (p, p->r_c6, p->c_d, -1, __LINE__);
804
805 /* Adding rows for c 8) Maximize utility */
806 p->r_c8 = mlp_create_problem_create_constraint (p, "c8", GLP_FX, 0.0, 0.0);
807 /* -u */
808 mlp_create_problem_set_value (p, p->r_c8, p->c_u, -1, __LINE__);
809
810 /* For all quality metrics:
811 * c 7) Maximize utilization, austerity */
812 for (c = 0; c < mlp->pv.m_q; c++)
813 {
814 GNUNET_asprintf(&name, "c7_q%i_%s", c, mlp_ats_to_string(mlp->pv.q[c]));
815 p->r_q[c] = mlp_create_problem_create_constraint (p, name, GLP_FX, 0.0, 0.0);
816 GNUNET_free (name);
817 mlp_create_problem_set_value (p, p->r_q[c], p->c_q[c], -1, __LINE__);
818 }
809 } 819 }
810} 820}
811 821
@@ -816,35 +826,27 @@ mlp_create_problem_add_invariant_rows (struct GAS_MLP_Handle *mlp, struct MLP_Pr
816static void 826static void
817mlp_create_problem_add_invariant_columns (struct GAS_MLP_Handle *mlp, struct MLP_Problem *p) 827mlp_create_problem_add_invariant_columns (struct GAS_MLP_Handle *mlp, struct MLP_Problem *p)
818{ 828{
819 char *name; 829 if (GNUNET_NO == mlp->opt_feasibility_only)
820 int c; 830 {
821 831 char *name;
822#if TEST_MAX_BW_ASSIGNMENT 832 int c;
823 mlp->pv.co_D = 0.0;
824 mlp->pv.co_U = 0.0;
825
826#endif
827 //mlp->pv.co_R = 0.0;
828 833
829 /* Diversity d column */ 834 /* Diversity d column */
830 p->c_d = mlp_create_problem_create_column (p, "d", GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_D); 835 p->c_d = mlp_create_problem_create_column (p, "d", GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_D);
831 836
832 /* Utilization u column */ 837 /* Utilization u column */
833 p->c_u = mlp_create_problem_create_column (p, "u", GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_U); 838 p->c_u = mlp_create_problem_create_column (p, "u", GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_U);
834 839
835 /* Relativity r column */ 840 /* Relativity r column */
836 p->c_r = mlp_create_problem_create_column (p, "r", GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_R); 841 p->c_r = mlp_create_problem_create_column (p, "r", GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_R);
837 842
838 /* Quality metric columns */ 843 /* Quality metric columns */
839 for (c = 0; c < mlp->pv.m_q; c++) 844 for (c = 0; c < mlp->pv.m_q; c++)
840 { 845 {
841 GNUNET_asprintf (&name, "q_%u", mlp->pv.q[c]); 846 GNUNET_asprintf (&name, "q_%u", mlp->pv.q[c]);
842#if TEST_MAX_BW_ASSIGNMENT 847 p->c_q[c] = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_Q[c]);
843 p->c_q[c] = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO, 0.0, 0.0, 0.0); 848 GNUNET_free (name);
844#else 849 }
845 p->c_q[c] = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO, 0.0, 0.0, mlp->pv.co_Q[c]);
846#endif
847 GNUNET_free (name);
848 } 850 }
849} 851}
850 852
@@ -918,6 +920,7 @@ mlp_create_problem (struct GAS_MLP_Handle *mlp)
918 /* Load the matrix */ 920 /* Load the matrix */
919 LOG (GNUNET_ERROR_TYPE_DEBUG, "Loading matrix\n"); 921 LOG (GNUNET_ERROR_TYPE_DEBUG, "Loading matrix\n");
920 glp_load_matrix(p->prob, (p->ci)-1, p->ia, p->ja, p->ar); 922 glp_load_matrix(p->prob, (p->ci)-1, p->ia, p->ja, p->ar);
923 glp_scale_prob (p->prob, GLP_SF_AUTO);
921 924
922 return res; 925 return res;
923} 926}
@@ -1408,6 +1411,9 @@ GAS_mlp_address_property_changed (void *solver,
1408 abs_value, 1411 abs_value,
1409 rel_value); 1412 rel_value);
1410 1413
1414 if (GNUNET_YES == mlp->opt_feasibility_only)
1415 return;
1416
1411 /* Find row index */ 1417 /* Find row index */
1412 type_index = -1; 1418 type_index = -1;
1413 for (c1 = 0; c1 < mlp->pv.m_q; c1++) 1419 for (c1 = 0; c1 < mlp->pv.m_q; c1++)
@@ -1432,6 +1438,7 @@ GAS_mlp_address_property_changed (void *solver,
1432 if (GNUNET_YES == mlp->opt_mlp_auto_solve) 1438 if (GNUNET_YES == mlp->opt_mlp_auto_solve)
1433 GAS_mlp_solve_problem (solver); 1439 GAS_mlp_solve_problem (solver);
1434 } 1440 }
1441
1435} 1442}
1436 1443
1437 1444
@@ -1863,7 +1870,7 @@ GAS_mlp_address_change_preference (void *solver,
1863 GNUNET_STATISTICS_update (mlp->stats,"# LP address preference changes", 1, GNUNET_NO); 1870 GNUNET_STATISTICS_update (mlp->stats,"# LP address preference changes", 1, GNUNET_NO);
1864 /* Update the constraints with changed preferences */ 1871 /* Update the constraints with changed preferences */
1865 1872
1866 /* Update quality constraint c7 */ 1873
1867 1874
1868 /* Update relativity constraint c9 */ 1875 /* Update relativity constraint c9 */
1869 if (NULL == (p = GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers, peer))) 1876 if (NULL == (p = GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers, peer)))
@@ -1871,14 +1878,17 @@ GAS_mlp_address_change_preference (void *solver,
1871 LOG (GNUNET_ERROR_TYPE_INFO, "Updating preference for unknown peer `%s'\n", GNUNET_i2s(peer)); 1878 LOG (GNUNET_ERROR_TYPE_INFO, "Updating preference for unknown peer `%s'\n", GNUNET_i2s(peer));
1872 return; 1879 return;
1873 } 1880 }
1874 p->f = get_peer_pref_value (mlp, peer);
1875 mlp_create_problem_update_value (&mlp->p, p->r_c9, mlp->p.c_r, -p->f, __LINE__);
1876 1881
1877 /* Problem size changed: new address for peer with pending request */ 1882 if (GNUNET_NO == mlp->opt_feasibility_only)
1878 mlp->stat_mlp_prob_updated = GNUNET_YES; 1883 {
1879 if (GNUNET_YES == mlp->opt_mlp_auto_solve) 1884 p->f = get_peer_pref_value (mlp, peer);
1880 GAS_mlp_solve_problem (solver); 1885 mlp_create_problem_update_value (&mlp->p, p->r_c9, mlp->p.c_r, -p->f, __LINE__);
1881 return; 1886
1887 /* Problem size changed: new address for peer with pending request */
1888 mlp->stat_mlp_prob_updated = GNUNET_YES;
1889 if (GNUNET_YES == mlp->opt_mlp_auto_solve)
1890 GAS_mlp_solve_problem (solver);
1891 }
1882} 1892}
1883 1893
1884 1894
@@ -2029,6 +2039,14 @@ libgnunet_plugin_ats_mlp_init (void *cls)
2029 if (GNUNET_SYSERR == mlp->opt_glpk_verbose) 2039 if (GNUNET_SYSERR == mlp->opt_glpk_verbose)
2030 mlp->opt_glpk_verbose = GNUNET_NO; 2040 mlp->opt_glpk_verbose = GNUNET_NO;
2031 2041
2042 mlp->opt_feasibility_only = GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
2043 "ats", "MLP_FEASIBILITY_ONLY");
2044 if (GNUNET_SYSERR == mlp->opt_feasibility_only)
2045 mlp->opt_feasibility_only = GNUNET_NO;
2046 if (GNUNET_YES == mlp->opt_feasibility_only)
2047 LOG (GNUNET_ERROR_TYPE_WARNING,
2048 "MLP solver is configured to check feasibility only!\n");
2049
2032 mlp->pv.BIG_M = (double) BIG_M_VALUE; 2050 mlp->pv.BIG_M = (double) BIG_M_VALUE;
2033 2051
2034 /* Get timeout for iterations */ 2052 /* Get timeout for iterations */